def post(self, bay): """Create a new bay. :param bay: a bay within the request body. """ context = pecan.request.context policy.enforce(context, 'bay:create', action='bay:create') baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id) attr_validator.validate_os_resources(context, baymodel.as_dict()) attr_validator.validate_master_count(bay.as_dict(), baymodel.as_dict()) bay_dict = bay.as_dict() bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # bay if the name is not spcified by user. name = bay_dict.get('name') or self._generate_name_for_bay(context) bay_dict['name'] = name new_bay = objects.Bay(context, **bay_dict) res_bay = pecan.request.rpcapi.bay_create(new_bay, bay.bay_create_timeout) # Set the HTTP Location Header pecan.response.location = link.build_url('bays', res_bay.uuid) return Bay.convert_with_links(res_bay)
def post(self, baymodel): """Create a new baymodel. :param baymodel: a baymodel within the request body. """ context = pecan.request.context policy.enforce(context, 'baymodel:create', action='baymodel:create') baymodel_dict = baymodel.as_dict() cli = clients.OpenStackClients(context) attr_validator.validate_os_resources(context, baymodel_dict) image_data = attr_validator.validate_image(cli, baymodel_dict['image_id']) baymodel_dict['cluster_distro'] = image_data['os_distro'] baymodel_dict['project_id'] = context.project_id baymodel_dict['user_id'] = context.user_id # check permissions for making baymodel public if baymodel_dict['public']: if not policy.enforce(context, "baymodel:publish", None, do_raise=False): raise exception.ClusterTemplatePublishDenied() # NOTE(yuywz): We will generate a random human-readable name for # baymodel if the name is not spcified by user. arg_name = baymodel_dict.get('name') name = arg_name or self._generate_name_for_baymodel(context) baymodel_dict['name'] = name new_baymodel = objects.BayModel(context, **baymodel_dict) new_baymodel.create() # Set the HTTP Location Header pecan.response.location = link.build_url('baymodels', new_baymodel.uuid) return BayModel.convert_with_links(new_baymodel)
def post(self, baymodel): """Create a new baymodel. :param baymodel: a baymodel within the request body. """ context = pecan.request.context policy.enforce(context, 'baymodel:create', action='baymodel:create') baymodel_dict = baymodel.as_dict() context = pecan.request.context cli = clients.OpenStackClients(context) attr_validator.validate_os_resources(context, baymodel_dict) image_data = attr_validator.validate_image(cli, baymodel_dict['image_id']) baymodel_dict['cluster_distro'] = image_data['os_distro'] baymodel_dict['project_id'] = context.project_id baymodel_dict['user_id'] = context.user_id # check permissions for making baymodel public if baymodel_dict['public']: if not policy.enforce(context, "baymodel:publish", None, do_raise=False): raise exception.BaymodelPublishDenied() new_baymodel = objects.BayModel(context, **baymodel_dict) new_baymodel.create() # Set the HTTP Location Header pecan.response.location = link.build_url('baymodels', new_baymodel.uuid) return BayModel.convert_with_links(new_baymodel)
def post(self, cluster): """Create a new cluster. :param cluster: a cluster within the request body. """ context = pecan.request.context policy.enforce(context, 'cluster:create', action='cluster:create') temp_id = cluster.cluster_template_id cluster_template = objects.BayModel.get_by_uuid(context, temp_id) cluster_dict = cluster.as_dict() attr_validator.validate_os_resources(context, cluster_template.as_dict()) attr_validator.validate_master_count(cluster_dict, cluster_template.as_dict()) cluster_dict['project_id'] = context.project_id cluster_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # cluster if the name is not specified by user. name = cluster_dict.get('name') or \ self._generate_name_for_cluster(context) cluster_dict['name'] = name new_cluster = objects.Bay(context, **cluster_dict) new_cluster.uuid = uuid.uuid4() pecan.request.rpcapi.bay_create_async(new_cluster, cluster.create_timeout) return ClusterID(new_cluster.uuid)
def post(self, cluster): """Create a new cluster. :param cluster: a cluster within the request body. """ context = pecan.request.context policy.enforce(context, 'cluster:create', action='cluster:create') self._check_cluster_quota_limit(context) temp_id = cluster.cluster_template_id cluster_template = objects.ClusterTemplate.get_by_uuid(context, temp_id) # If keypair not present, use cluster_template value if cluster.keypair is None: cluster.keypair = cluster_template.keypair_id # If docker_volume_size is not present, use cluster_template value if cluster.docker_volume_size == wtypes.Unset: cluster.docker_volume_size = cluster_template.docker_volume_size # If labels is not present, use cluster_template value if cluster.labels == wtypes.Unset: cluster.labels = cluster_template.labels # If master_flavor_id is not present, use cluster_template value if (cluster.master_flavor_id == wtypes.Unset or not cluster.master_flavor_id): cluster.master_flavor_id = cluster_template.master_flavor_id # If flavor_id is not present, use cluster_template value if cluster.flavor_id == wtypes.Unset or not cluster.flavor_id: cluster.flavor_id = cluster_template.flavor_id cluster_dict = cluster.as_dict() attr_validator.validate_os_resources(context, cluster_template.as_dict(), cluster_dict) attr_validator.validate_master_count(cluster_dict, cluster_template.as_dict()) cluster_dict['project_id'] = context.project_id cluster_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # cluster if the name is not specified by user. name = cluster_dict.get('name') or \ self._generate_name_for_cluster(context) cluster_dict['name'] = name cluster_dict['coe_version'] = None cluster_dict['container_version'] = None new_cluster = objects.Cluster(context, **cluster_dict) new_cluster.uuid = uuid.uuid4() pecan.request.rpcapi.cluster_create_async(new_cluster, cluster.create_timeout) return ClusterID(new_cluster.uuid)
def test_validate_os_resources_with_cluster(self, mock_os_cli): mock_cluster_template = {} mock_cluster = {'keypair': 'test-keypair'} mock_keypair = mock.MagicMock() mock_keypair.id = 'test-keypair' mock_nova = mock.MagicMock() mock_nova.keypairs.get.return_value = mock_keypair mock_os_cli = mock.MagicMock() mock_os_cli.nova.return_value = mock_nova mock_context = mock.MagicMock() attr_validator.validate_os_resources(mock_context, mock_cluster_template, mock_cluster)
def patch(self, cluster_template_ident, patch): """Update an existing ClusterTemplate. :param cluster_template_ident: UUID or logic name of a ClusterTemplate. :param patch: a json PATCH document to apply to this ClusterTemplate. """ context = pecan.request.context if context.is_admin: policy.enforce(context, 'clustertemplate:update_all_projects', action='clustertemplate:update_all_projects') context.all_tenants = True cluster_template = api_utils.get_resource('ClusterTemplate', cluster_template_ident) policy.enforce(context, 'clustertemplate:update', cluster_template.as_dict(), action='clustertemplate:update') try: cluster_template_dict = cluster_template.as_dict() new_cluster_template = ClusterTemplate(**api_utils.apply_jsonpatch( cluster_template_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) new_cluster_template_dict = new_cluster_template.as_dict() attr_validator.validate_os_resources(context, new_cluster_template_dict) # check permissions when updating ClusterTemplate public or hidden flag if (cluster_template.public != new_cluster_template.public or cluster_template.hidden != new_cluster_template.hidden): if not policy.enforce(context, "clustertemplate:publish", None, do_raise=False): raise exception.ClusterTemplatePublishDenied() # Update only the fields that have changed for field in objects.ClusterTemplate.fields: try: patch_val = getattr(new_cluster_template, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if cluster_template[field] != patch_val: cluster_template[field] = patch_val cluster_template.save() return ClusterTemplate.convert_with_links(cluster_template)
def _post(self, bay): context = pecan.request.context policy.enforce(context, 'bay:create', action='bay:create') baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id) attr_validator.validate_os_resources(context, baymodel.as_dict()) attr_validator.validate_master_count(bay.as_dict(), baymodel.as_dict()) bay_dict = bay.as_dict() bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # bay if the name is not spcified by user. name = bay_dict.get('name') or self._generate_name_for_bay(context) bay_dict['name'] = name new_bay = objects.Bay(context, **bay_dict) new_bay.uuid = uuid.uuid4() return new_bay
def _post(self, bay): context = pecan.request.context policy.enforce(context, 'bay:create', action='bay:create') baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id) attr_validator.validate_os_resources(context, baymodel.as_dict()) attr_validator.validate_master_count(bay.as_dict(), baymodel.as_dict()) bay_dict = bay.as_dict() bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # bay if the name is not spcified by user. name = bay_dict.get('name') or self._generate_name_for_bay(context) bay_dict['name'] = name new_bay = objects.Bay(context, **bay_dict) new_bay.uuid = uuid.uuid4() return new_bay
def _post(self, bay): context = pecan.request.context policy.enforce(context, 'bay:create', action='bay:create') baymodel = objects.ClusterTemplate.get_by_uuid(context, bay.baymodel_id) # If docker_volume_size is not present, use baymodel value if bay.docker_volume_size == wtypes.Unset: bay.docker_volume_size = baymodel.docker_volume_size # If labels is not present, use baymodel value if bay.labels is None: bay.labels = baymodel.labels # If master_flavor_id is not present, use baymodel value if bay.master_flavor_id == wtypes.Unset or not bay.master_flavor_id: bay.master_flavor_id = baymodel.master_flavor_id # If flavor_id is not present, use baymodel value if bay.flavor_id == wtypes.Unset or not bay.flavor_id: bay.flavor_id = baymodel.flavor_id bay_dict = bay.as_dict() bay_dict['keypair'] = baymodel.keypair_id attr_validator.validate_os_resources(context, baymodel.as_dict(), bay_dict) attr_validator.validate_master_count(bay.as_dict(), baymodel.as_dict()) bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # bay if the name is not specified by user. name = bay_dict.get('name') or self._generate_name_for_bay(context) node_count = bay_dict.pop('node_count') master_count = bay_dict.pop('master_count') bay_dict['name'] = name bay_dict['coe_version'] = None bay_dict['container_version'] = None new_bay = objects.Cluster(context, **bay_dict) new_bay.uuid = uuid.uuid4() return new_bay, node_count, master_count
def test_validate_os_resources_with_cluster(self, mock_os_cli): mock_cluster_template = {} mock_cluster = { 'keypair': 'test-keypair', 'labels': {'lab1': 'val1'}, 'image_id': 'e33f0988-1730-405e-8401-30cbc8535302' } mock_keypair = mock.MagicMock() mock_keypair.id = 'test-keypair' mock_image = {'name': 'fedora-21-atomic-5', 'id': 'e33f0988-1730-405e-8401-30cbc8535302', 'os_distro': 'fedora-atomic'} mock_nova = mock.MagicMock() mock_nova.keypairs.get.return_value = mock_keypair mock_nova.images.get.return_value = mock_image mock_os_cli = mock.MagicMock() mock_os_cli.nova.return_value = mock_nova mock_context = mock.MagicMock() attr_validator.validate_os_resources(mock_context, mock_cluster_template, mock_cluster)
def post(self, bay): """Create a new bay. :param bay: a bay within the request body. """ bay_dict = bay.as_dict() context = pecan.request.context attr_validator.validate_os_resources(context, bay_dict.get('baymodel_id')) bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id if bay_dict.get('name') is None: bay_dict['name'] = None new_bay = objects.Bay(context, **bay_dict) res_bay = pecan.request.rpcapi.bay_create(new_bay, bay.bay_create_timeout) # Set the HTTP Location Header pecan.response.location = link.build_url('bays', res_bay.uuid) return Bay.convert_with_links(res_bay)
def patch(self, baymodel_ident, patch): """Update an existing baymodel. :param baymodel_ident: UUID or logic name of a baymodel. :param patch: a json PATCH document to apply to this baymodel. """ context = pecan.request.context baymodel = api_utils.get_resource('BayModel', baymodel_ident) policy.enforce(context, 'baymodel:update', baymodel, action='baymodel:update') try: baymodel_dict = baymodel.as_dict() new_baymodel = BayModel(**api_utils.apply_jsonpatch( baymodel_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) new_baymodel_dict = new_baymodel.as_dict() attr_validator.validate_os_resources(context, new_baymodel_dict) # check permissions when updating baymodel public flag if baymodel.public != new_baymodel.public: if not policy.enforce(context, "baymodel:publish", None, do_raise=False): raise exception.ClusterTemplatePublishDenied() # Update only the fields that have changed for field in objects.BayModel.fields: try: patch_val = getattr(new_baymodel, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if baymodel[field] != patch_val: baymodel[field] = patch_val baymodel.save() return BayModel.convert_with_links(baymodel)
def post(self, cluster_template): """Create a new ClusterTemplate. :param cluster_template: a ClusterTemplate within the request body. """ context = pecan.request.context policy.enforce(context, 'clustertemplate:create', action='clustertemplate:create') cluster_template_dict = cluster_template.as_dict() cli = clients.OpenStackClients(context) attr_validator.validate_os_resources(context, cluster_template_dict) image_data = attr_validator.validate_image(cli, cluster_template_dict[ 'image_id']) cluster_template_dict['cluster_distro'] = image_data['os_distro'] cluster_template_dict['project_id'] = context.project_id cluster_template_dict['user_id'] = context.user_id # check permissions for making cluster_template public if cluster_template_dict['public']: if not policy.enforce(context, "clustertemplate:publish", None, do_raise=False): raise exception.ClusterTemplatePublishDenied() # NOTE(yuywz): We will generate a random human-readable name for # cluster_template if the name is not specified by user. arg_name = cluster_template_dict.get('name') name = arg_name or self._generate_name_for_cluster_template(context) cluster_template_dict['name'] = name new_cluster_template = objects.ClusterTemplate(context, **cluster_template_dict) new_cluster_template.create() # Set the HTTP Location Header pecan.response.location = link.build_url('clustertemplates', new_cluster_template.uuid) return ClusterTemplate.convert_with_links(new_cluster_template)
def post(self, bay): """Create a new bay. :param bay: a bay within the request body. """ context = pecan.request.context policy.enforce(context, 'bay:create', action='bay:create') baymodel = objects.BayModel.get_by_uuid(context, bay.baymodel_id) attr_validator.validate_os_resources(context, baymodel.as_dict()) bay_dict = bay.as_dict() bay_dict['project_id'] = context.project_id bay_dict['user_id'] = context.user_id # NOTE(yuywz): We will generate a random human-readable name for # bay if the name is not spcified by user. name = bay_dict.get('name') or self._generate_name_for_bay(context) bay_dict['name'] = name new_bay = objects.Bay(context, **bay_dict) res_bay = pecan.request.rpcapi.bay_create(new_bay, bay.bay_create_timeout) # Set the HTTP Location Header pecan.response.location = link.build_url('bays', res_bay.uuid) return Bay.convert_with_links(res_bay)
def test_validate_os_resources_without_validator(self, mock_validators, mock_os_cli): mock_cluster_template = {} mock_context = mock.MagicMock() attr_validator.validate_os_resources(mock_context, mock_cluster_template)