def upgrade(self, cluster_ident, cluster_upgrade_req): """Upgrade a cluster. :param cluster_ident: UUID of a cluster or logical name of the cluster. """ context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:upgrade', cluster, action='cluster:upgrade') new_cluster_template = api_utils.get_resource( 'ClusterTemplate', cluster_upgrade_req.cluster_template) if (cluster_upgrade_req.nodegroup == wtypes.Unset or not cluster_upgrade_req.nodegroup): # NOTE(ttsiouts): If the nodegroup is not specified # reflect the change to the default worker nodegroup nodegroup = cluster.default_ng_worker else: nodegroup = objects.NodeGroup.get(context, cluster.uuid, cluster_upgrade_req.nodegroup) if (new_cluster_template.uuid != cluster.cluster_template_id and not nodegroup.is_default): reason = ("Nodegroup %s can be upgraded only to " "match cluster's template (%s).") reason = reason % (nodegroup.name, cluster.cluster_template.name) raise exception.InvalidClusterTemplateForUpgrade(reason=reason) pecan.request.rpcapi.cluster_upgrade( cluster, new_cluster_template, cluster_upgrade_req.max_batch_size, nodegroup) return ClusterID(cluster.uuid)
def upgrade(self, cluster_ident, cluster_upgrade_req): """Upgrade a cluster. :param cluster_ident: UUID of a cluster or logical name of the cluster. """ context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:upgrade', cluster, action='cluster:upgrade') new_cluster_template = api_utils.get_resource( 'ClusterTemplate', cluster_upgrade_req.cluster_template) if (cluster_upgrade_req.nodegroup == wtypes.Unset or not cluster_upgrade_req.nodegroup): # NOTE(ttsiouts): If the nodegroup is not specified # reflect the change to the default worker nodegroup nodegroup = cluster.default_ng_worker else: nodegroup = objects.NodeGroup.get(context, cluster.uuid, cluster_upgrade_req.nodegroup) pecan.request.rpcapi.cluster_upgrade( cluster, new_cluster_template, cluster_upgrade_req.max_batch_size, nodegroup) return ClusterID(cluster.uuid)
def validate_federation_hostcluster(cluster_uuid): """Validate Federation `hostcluster_id` parameter. If the parameter was not specified raise an `exceptions.InvalidParameterValue`. If the specified identifier does not identify any Cluster, raise `exception.ClusterNotFound` """ if cluster_uuid is not None: api_utils.get_resource('Cluster', cluster_uuid) else: raise exception.InvalidParameterValue( "No hostcluster specified. " "Please specify a hostcluster_id.")
def get_all(self, cluster_id, marker=None, limit=None, sort_key='id', sort_dir='asc', role=None): """Retrieve a list of nodegroups. :param cluster_id: the cluster id or name :param marker: pagination marker for large data sets. :param limit: maximum number of resources to return in a single result. :param sort_key: column to sort results by. Default: id. :param sort_dir: direction to sort. "asc" or "desc". Default: asc. :param role: list all nodegroups with the specified role. """ context = pecan.request.context policy.enforce(context, 'nodegroup:get_all', action='nodegroup:get_all') if context.is_admin: policy.enforce(context, 'nodegroup:get_all_all_projects', action='nodegroup:get_all_all_projects') context.all_tenants = True cluster = api_utils.get_resource('Cluster', cluster_id) filters = {} if not context.is_admin: filters = {"project_id": context.project_id} if role: filters.update({'role': role}) return self._get_nodegroup_collection(cluster.uuid, marker, limit, sort_key, sort_dir, filters, expand=False)
def patch(self, cluster_ident, patch): """Update an existing bay. :param cluster_ident: UUID or logical name of a bay. :param patch: a json PATCH document to apply to this bay. """ context = pecan.request.context cluster = api_utils.get_resource('Bay', cluster_ident) policy.enforce(context, 'cluster:update', cluster, action='cluster:update') try: cluster_dict = cluster.as_dict() new_cluster = Cluster(**api_utils.apply_jsonpatch(cluster_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Bay.fields: try: patch_val = getattr(new_cluster, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if cluster[field] != patch_val: cluster[field] = patch_val delta = cluster.obj_what_changed() validate_bay_properties(delta) pecan.request.rpcapi.bay_update_async(cluster) return ClusterID(cluster.uuid)
def patch(self, container_ident, patch): """Update an existing container. :param container_ident: UUID or name of a container. :param patch: a json PATCH document to apply to this container. """ container = api_utils.get_resource('Container', container_ident) try: container_dict = container.as_dict() new_container = Container(**api_utils.apply_jsonpatch( container_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Container.fields: try: patch_val = getattr(new_container, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if container[field] != patch_val: container[field] = patch_val container.save() return Container.convert_with_links(container)
def post(self, cluster_id, nodegroup): """Create NodeGroup. :param nodegroup: a json document to create this NodeGroup. """ context = pecan.request.context policy.enforce(context, 'nodegroup:create', action='nodegroup:create') cluster = api_utils.get_resource('Cluster', cluster_id) cluster_ngs = [ng.name for ng in cluster.nodegroups] if nodegroup.name in cluster_ngs: raise exception.NodeGroupAlreadyExists(name=nodegroup.name, cluster_id=cluster.name) _validate_node_count(nodegroup) if nodegroup.role == "master": # Currently we don't support adding master nodegroups. # Keep this until we start supporting it. raise exception.CreateMasterNodeGroup() if nodegroup.image_id is None or nodegroup.image_id == wtypes.Unset: nodegroup.image_id = cluster.cluster_template.image_id if nodegroup.flavor_id is None or nodegroup.flavor_id == wtypes.Unset: nodegroup.flavor_id = cluster.flavor_id if nodegroup.labels is None or nodegroup.labels == wtypes.Unset: nodegroup.labels = cluster.labels nodegroup_dict = nodegroup.as_dict() nodegroup_dict['cluster_id'] = cluster.uuid nodegroup_dict['project_id'] = context.project_id new_obj = objects.NodeGroup(context, **nodegroup_dict) new_obj.uuid = uuid.uuid4() pecan.request.rpcapi.nodegroup_create_async(cluster, new_obj) return NodeGroup.convert(new_obj)
def patch(self, bay_ident, patch): """Update an existing bay. :param bay_ident: UUID or logical name of a bay. :param patch: a json PATCH document to apply to this bay. """ context = pecan.request.context bay = api_utils.get_resource('Bay', bay_ident) policy.enforce(context, 'bay:update', bay, action='bay:update') try: bay_dict = bay.as_dict() new_bay = Bay(**api_utils.apply_jsonpatch(bay_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Bay.fields: try: patch_val = getattr(new_bay, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if bay[field] != patch_val: bay[field] = patch_val delta = bay.obj_what_changed() validate_bay_properties(delta) res_bay = pecan.request.rpcapi.bay_update(bay) return Bay.convert_with_links(res_bay)
def _patch(self, federation_ident, patch): context = pecan.request.context federation = api_utils.get_resource('Federation', federation_ident) policy.enforce(context, 'federation:update', federation.as_dict(), action='federation:update') # NOTE(clenimar): Magnum does not allow one to append items to existing # fields through an `add` operation using HTTP PATCH (please check # `magnum.api.utils.apply_jsonpatch`). In order to perform the join # and unjoin operations, intercept the original JSON PATCH document # and change the operation from either `add` or `remove` to `replace`. patch_path = patch[0].get('path') patch_value = patch[0].get('value') patch_op = patch[0].get('op') if patch_path == '/member_ids': if patch_op == 'add' and patch_value is not None: patch = self._join_wrapper(federation_ident, patch) elif patch_op == 'remove' and patch_value is not None: patch = self._unjoin_wrapper(federation_ident, patch) try: federation_dict = federation.as_dict() new_federation = Federation( **api_utils.apply_jsonpatch(federation_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Retrieve only what changed after the patch. delta = self._update_changed_fields(federation, new_federation) validation.validate_federation_properties(delta) return federation
def _patch(self, bay_ident, patch): context = pecan.request.context bay = api_utils.get_resource('Bay', bay_ident) policy.enforce(context, 'bay:update', bay, action='bay:update') try: bay_dict = bay.as_dict() new_bay = Bay(**api_utils.apply_jsonpatch(bay_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Bay.fields: try: patch_val = getattr(new_bay, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if bay[field] != patch_val: bay[field] = patch_val delta = bay.obj_what_changed() validate_bay_properties(delta) return bay
def get_one(self, cluster_template_ident): """Retrieve information about the given ClusterTemplate. :param cluster_template_ident: UUID or logical name of a ClusterTemplate. """ context = pecan.request.context if context.is_admin: policy.enforce(context, "clustertemplate:get_one_all_projects", action="clustertemplate:get_one_all_projects") # TODO(flwang): Instead of asking an extra 'all_project's # parameter, currently the design is allowing admin user to list # all clusters from all projects. But the all_tenants is one of # the condition to do project filter in DB API. And it's also used # by periodic tasks. So the could be removed in the future and # a new parameter 'project_id' would be added so that admin user # can list clusters for a particular project. context.all_tenants = True cluster_template = api_utils.get_resource('ClusterTemplate', cluster_template_ident) if not cluster_template.public: policy.enforce(context, 'clustertemplate:get', cluster_template.as_dict(), action='clustertemplate:get') return ClusterTemplate.convert_with_links(cluster_template)
def _patch(self, cluster_ident, patch): context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:update', cluster.as_dict(), action='cluster:update') try: cluster_dict = cluster.as_dict() new_cluster = Cluster( **api_utils.apply_jsonpatch(cluster_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # NOTE(ttsiouts): magnum.objects.Cluster.node_count will be a # property so we won't be able to store it in the object. So # instead of object_what_changed compare the new and the old # clusters. delta = set() for field in new_cluster.fields: if getattr(cluster, field) != getattr(new_cluster, field): delta.add(field) validation.validate_cluster_properties(delta) return cluster, new_cluster.node_count
def get_one(self, cluster_ident): """Retrieve information about the given Cluster. :param cluster_ident: UUID or logical name of the Cluster. """ context = pecan.request.context if context.is_admin: policy.enforce(context, "cluster:get_one_all_projects", action="cluster:get_one_all_projects") # TODO(flwang): Instead of asking an extra 'all_project's # parameter, currently the design is allowing admin user to list # all clusters from all projects. But the all_tenants is one of # the condition to do project filter in DB API. And it's also used # by periodic tasks. So the could be removed in the future and # a new parameter 'project_id' would be added so that admin user # can list clusters for a particular project. context.all_tenants = True cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:get', cluster.as_dict(), action='cluster:get') cluster = Cluster.convert_with_links(cluster) if cluster.status in fields.ClusterStatus.STATUS_FAILED: cluster.faults = self._collect_fault_info(context, cluster) return cluster
def _patch(self, cluster_ident, patch): context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:update', cluster.as_dict(), action='cluster:update') try: cluster_dict = cluster.as_dict() new_cluster = Cluster(**api_utils.apply_jsonpatch(cluster_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Cluster.fields: try: patch_val = getattr(new_cluster, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if cluster[field] != patch_val: cluster[field] = patch_val delta = cluster.obj_what_changed() validation.validate_cluster_properties(delta) return cluster
def convert(cls, nodegroup, expand=True): url = pecan.request.host_url cluster_path = 'clusters/%s' % nodegroup.cluster_id nodegroup_path = 'nodegroups/%s' % nodegroup.uuid ng = NodeGroup(**nodegroup.as_dict()) if not expand: ng.unset_fields_except(["uuid", "name", "flavor_id", "node_count", "role", "is_default", "image_id", "status", "stack_id"]) else: ng.links = [link.Link.make_link('self', url, cluster_path, nodegroup_path), link.Link.make_link('bookmark', url, cluster_path, nodegroup_path, bookmark=True)] cluster = api_utils.get_resource('Cluster', ng.cluster_id) overridden, added, skipped = api_utils.get_labels_diff( cluster.labels, ng.labels) ng.labels_overridden = overridden ng.labels_added = added ng.labels_skipped = skipped return ng
def _patch(self, bay_ident, patch): context = pecan.request.context bay = api_utils.get_resource('Cluster', bay_ident) policy.enforce(context, 'bay:update', bay.as_dict(), action='bay:update') bay_to_cluster_attrs = { 'baymodel_id': 'cluster_template_id', 'bay_create_timeout': 'create_timeout' } try: bay_dict = bay.as_dict() new_bay = Bay(**api_utils.apply_jsonpatch(bay_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # NOTE(ttsiouts): magnum.objects.Cluster.node_count will be a # property so we won't be able to store it in the object. So # instead of object_what_changed compare the new and the old # clusters. delta = set() for field in new_bay.fields: cluster_field = field if cluster_field in bay_to_cluster_attrs: cluster_field = bay_to_cluster_attrs[field] if cluster_field not in bay_dict: continue if getattr(new_bay, field) != bay_dict[cluster_field]: delta.add(cluster_field) validate_cluster_properties(delta) return bay, new_bay.node_count
def _patch(self, bay_ident, patch): context = pecan.request.context bay = api_utils.get_resource('Cluster', bay_ident) policy.enforce(context, 'bay:update', bay.as_dict(), action='bay:update') try: bay_dict = bay.as_dict() new_bay = Bay(**api_utils.apply_jsonpatch(bay_dict, patch)) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) # Update only the fields that have changed for field in objects.Cluster.fields: try: patch_val = getattr(new_bay, field) except AttributeError: # Ignore fields that aren't exposed in the API continue if patch_val == wtypes.Unset: patch_val = None if bay[field] != patch_val: bay[field] = patch_val delta = bay.obj_what_changed() validate_cluster_properties(delta) return bay
def delete(self, baymodel_ident): """Delete a baymodel. :param baymodel_ident: UUID or logical name of a baymodel. """ rpc_baymodel = api_utils.get_resource('BayModel', baymodel_ident) rpc_baymodel.destroy()
def get_one(self, baymodel_ident): """Retrieve information about the given baymodel. :param baymodel_ident: UUID or logical name of a baymodel. """ baymodel = api_utils.get_resource('BayModel', baymodel_ident) return BayModel.convert_with_links(baymodel)
def get_one(self, bay_ident): """Retrieve information about the given bay. :param bay_ident: UUID of a bay or logical name of the bay. """ bay = api_utils.get_resource('Bay', bay_ident) return Bay.convert_with_links(bay)
def _default(self, container_ident): if pecan.request.method != 'GET': pecan.abort( 405, ('HTTP method %s is not allowed' % pecan.request.method)) container = api_utils.get_resource('Container', container_ident) check_policy_on_container(container, "container:logs") LOG.debug('Calling conductor.container_logs with %s', container.uuid) return pecan.request.rpcapi.container_logs(container.uuid)
def delete(self, bay_ident): """Delete a bay. :param bay_ident: UUID of a bay or logical name of the bay. """ rpc_bay = api_utils.get_resource('Bay', bay_ident) pecan.request.rpcapi.bay_delete(rpc_bay.uuid)
def _delete(self, bay_ident): context = pecan.request.context bay = api_utils.get_resource('Cluster', bay_ident) policy.enforce(context, 'bay:delete', bay.as_dict(), action='bay:delete') return bay
def get_one(self, x509keypair_ident): """Retrieve information about the given x509keypair. :param x509keypair_ident: UUID of a x509keypair or logical name of the x509keypair. """ x509keypair = api_utils.get_resource('X509KeyPair', x509keypair_ident) return X509KeyPair.convert_with_links(x509keypair)
def delete(self, x509keypair_ident): """Delete a x509keypair. :param x509keypair_ident: UUID of a x509keypair or logical name of the x509keypair. """ x509keypair = api_utils.get_resource('X509KeyPair', x509keypair_ident) pecan.request.rpcapi.x509keypair_delete(x509keypair.uuid)
def _default(self, container_ident, command): if pecan.request.method != 'PUT': pecan.abort(405, ('HTTP method %s is not allowed' % pecan.request.method)) container_uuid = api_utils.get_resource('Container', container_ident).uuid LOG.debug('Calling conductor.container_exec with %s command %s' % (container_uuid, command)) return pecan.request.rpcapi.container_exec(container_uuid, command)
def delete(self, container_ident): """Delete a container. :param container_ident: UUID or Name of a container. """ container = api_utils.get_resource('Container', container_ident) pecan.request.rpcapi.container_delete(container.uuid) container.destroy()
def get_one(self, container_ident): """Retrieve information about the given container. :param container_ident: UUID or name of a container. """ container = api_utils.get_resource('Container', container_ident) res_container = pecan.request.rpcapi.container_show(container.uuid) return Container.convert_with_links(res_container)
def delete(self, container_ident): """Delete a container. :param container_ident: UUID or Name of a container. """ container = api_utils.get_resource('Container', container_ident) check_policy_on_container(container, "container:delete") pecan.request.rpcapi.container_delete(container.uuid) container.destroy()
def get_one(self, container_ident): """Retrieve information about the given container. :param container_ident: UUID or name of a container. """ container = api_utils.get_resource('Container', container_ident) check_policy_on_container(container, "container:get") res_container = pecan.request.rpcapi.container_show(container.uuid) return Container.convert_with_links(res_container)
def patch(self, cluster_ident): context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'certificate:rotate_ca', cluster.as_dict(), action='certificate:rotate_ca') if cluster.cluster_template.tls_disabled: raise exception.NotSupported("Rotating the CA certificate on a " "non-TLS cluster is not supported") pecan.request.rpcapi.rotate_ca_certificate(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 if (cluster_template.docker_storage_driver in ('devicemapper', 'overlay')): warnings.warn(self._devicemapper_overlay_deprecation_note, DeprecationWarning) LOG.warning(self._devicemapper_overlay_deprecation_note) cluster_template.save() return ClusterTemplate.convert_with_links(cluster_template)
def get_one(self, bay_ident): """Retrieve information about the given certificate. :param bay_ident: UUID of a bay or logical name of the bay. """ bay = api_utils.get_resource('Bay', bay_ident) certificate = pecan.request.rpcapi.get_ca_certificate(bay) return Certificate.convert_with_links(certificate)
def get_one(self, bay_ident): """Retrieve information about the given bay. :param bay_ident: UUID of a bay or logical name of the bay. """ context = pecan.request.context bay = api_utils.get_resource('Bay', bay_ident) policy.enforce(context, 'bay:get', bay, action='bay:get') return Bay.convert_with_links(bay)
def delete(self, baymodel_ident): """Delete a baymodel. :param baymodel_ident: UUID or logical name of a baymodel. """ context = pecan.request.context baymodel = api_utils.get_resource('BayModel', baymodel_ident) policy.enforce(context, 'baymodel:delete', baymodel, action='baymodel:delete') baymodel.destroy()
def delete(self, baymodel_ident): """Delete a Baymodel. :param baymodel_ident: UUID or logical name of a Baymodel. """ context = pecan.request.context baymodel = api_utils.get_resource('ClusterTemplate', baymodel_ident) policy.enforce(context, 'baymodel:delete', baymodel.as_dict(), action='baymodel:delete') baymodel.destroy()
def delete(self, bay_ident): """Delete a bay. :param bay_ident: UUID of a bay or logical name of the bay. """ context = pecan.request.context bay = api_utils.get_resource('Bay', bay_ident) policy.enforce(context, 'bay:delete', bay, action='bay:delete') pecan.request.rpcapi.bay_delete(bay.uuid)
def test_get_resource_with_uuid(self, mock_get_by_uuid, mock_get_by_name, mock_request): mock_bay = mock.MagicMock mock_get_by_uuid.return_value = mock_bay uuid = uuidutils.generate_uuid() returned_bay = utils.get_resource('Bay', uuid) mock_get_by_uuid.assert_called_once_with(mock_request.context, uuid) self.assertFalse(mock_get_by_name.called) self.assertEqual(mock_bay, returned_bay)
def test_get_resource_with_name(self, mock_get_by_uuid, mock_get_by_name, mock_request): mock_bay = mock.MagicMock mock_get_by_name.return_value = mock_bay returned_bay = utils.get_resource('Bay', 'fake-name') self.assertFalse(mock_get_by_uuid.called) mock_get_by_name.assert_called_once_with(mock_request.context, 'fake-name') self.assertEqual(mock_bay, returned_bay)
def wrapper(func, *args, **kwargs): baymodel_ident = args[1] patch = args[2] baymodel = api_utils.get_resource('BayModel', baymodel_ident) try: baymodel_dict = api_utils.apply_jsonpatch(baymodel.as_dict(), patch) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) _enforce_volume_driver_types(baymodel_dict) return func(*args, **kwargs)
def patch(self, cluster_ident): context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'certificate:rotate_ca', cluster, action='certificate:rotate_ca') if cluster.cluster_template.tls_disabled: raise exception.NotSupported("Rotating the CA certificate on a " "non-TLS cluster is not supported") pecan.request.rpcapi.rotate_ca_certificate(cluster)
def delete(self, cluster_ident): """Delete a cluster. :param cluster_ident: UUID of cluster or logical name of the cluster. """ context = pecan.request.context cluster = api_utils.get_resource('Cluster', cluster_ident) policy.enforce(context, 'cluster:delete', cluster, action='cluster:delete') pecan.request.rpcapi.cluster_delete_async(cluster.uuid)
def patch(self, cluster_id, nodegroup_id, patch): """Update NodeGroup. :param cluster_id: cluster id. :param : resource name. :param values: a json document to update a nodegroup. """ cluster = api_utils.get_resource('Cluster', cluster_id) nodegroup = self._patch(cluster.uuid, nodegroup_id, patch) pecan.request.rpcapi.nodegroup_update_async(cluster, nodegroup) return NodeGroup.convert(nodegroup)
def wrapper(func, *args, **kwargs): cluster_template_ident = args[1] patch = args[2] cluster_template = api_utils.get_resource('ClusterTemplate', cluster_template_ident) try: cluster_template_dict = api_utils.apply_jsonpatch( cluster_template.as_dict(), patch) except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) _enforce_volume_driver_types(cluster_template_dict) return func(*args, **kwargs)
def get_one(self, baymodel_ident): """Retrieve information about the given baymodel. :param baymodel_ident: UUID or logical name of a baymodel. """ context = pecan.request.context baymodel = api_utils.get_resource('BayModel', baymodel_ident) if not baymodel.public: policy.enforce(context, 'baymodel:get', baymodel, action='baymodel:get') return BayModel.convert_with_links(baymodel)
def _set_baymodel_id(self, value): if value and self._baymodel_id != value: try: baymodel = api_utils.get_resource('BayModel', value) self._baymodel_id = baymodel.uuid except exception.BayModelNotFound as e: # Change error code because 404 (NotFound) is inappropriate # response for a POST request to create a Bay e.code = 400 # BadRequest raise e elif value == wtypes.Unset: self._baymodel_id = wtypes.Unset