예제 #1
0
    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)
예제 #2
0
    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
예제 #3
0
    def _patch(self, cluster_uuid, nodegroup_id, patch):
        context = pecan.request.context
        policy.enforce(context, 'nodegroup:update', action='nodegroup:update')
        nodegroup = objects.NodeGroup.get(context, cluster_uuid, nodegroup_id)

        try:
            ng_dict = nodegroup.as_dict()
            new_nodegroup = NodeGroup(**api_utils.apply_jsonpatch(ng_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.NodeGroup.fields:
            try:
                patch_val = getattr(new_nodegroup, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if nodegroup[field] != patch_val:
                nodegroup[field] = patch_val
        _validate_node_count(nodegroup)

        return nodegroup
예제 #4
0
파일: container.py 프로젝트: sidx64/magnum
    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.
        """
        rpc_container = api_utils.get_rpc_resource('Container',
                                                   container_ident)
        try:
            container_dict = rpc_container.as_dict()
            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(container, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_container[field] != patch_val:
                rpc_container[field] = patch_val

        rpc_container.save()
        return Container.convert_with_links(rpc_container)
예제 #5
0
    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
예제 #6
0
파일: node.py 프로젝트: pkdevboxy/magnum
    def patch(self, node_uuid, patch):
        """Update an existing node.

        :param node_uuid: UUID of a node.
        :param patch: a json PATCH document to apply to this node.
        """
        rpc_node = objects.Node.get_by_uuid(pecan.request.context, node_uuid)
        try:
            node_dict = rpc_node.as_dict()
            node = Node(**api_utils.apply_jsonpatch(node_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.Node.fields:
            try:
                patch_val = getattr(node, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_node[field] != patch_val:
                rpc_node[field] = patch_val

        rpc_node.save()
        return Node.convert_with_links(rpc_node)
예제 #7
0
    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
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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
예제 #11
0
파일: bay.py 프로젝트: openstack/magnum
    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
예제 #12
0
파일: bay.py 프로젝트: larsbutler/magnum
    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
예제 #13
0
파일: cluster.py 프로젝트: ragnaray/magnum
    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
예제 #14
0
    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.
        """
        rpc_container = api_utils.get_rpc_resource('Container',
                                                   container_ident)
        try:
            container_dict = rpc_container.as_dict()
            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(container, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_container[field] != patch_val:
                rpc_container[field] = patch_val

        rpc_container.save()
        return Container.convert_with_links(rpc_container)
예제 #15
0
    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)
예제 #16
0
파일: validation.py 프로젝트: yamt/magnum
 def wrapper(func, *args, **kwargs):
     baymodel_ident = args[1]
     patch = args[2]
     baymodel = api_utils.get_rpc_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)
예제 #17
0
 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)
예제 #18
0
 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)
예제 #19
0
 def wrapper(func, *args, **kwargs):
     baymodel_ident = args[1]
     patch = args[2]
     baymodel = api_utils.get_rpc_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)
     baymodel = objects.BayModel(pecan.request.context, **baymodel_dict)
     _enforce_network_driver_types(baymodel)
     return func(*args, **kwargs)
예제 #20
0
파일: validation.py 프로젝트: yamt/magnum
 def wrapper(func, *args, **kwargs):
     baymodel_ident = args[1]
     patch = args[2]
     baymodel = api_utils.get_rpc_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)
     baymodel = objects.BayModel(pecan.request.context, **baymodel_dict)
     _enforce_network_driver_types(baymodel)
     return func(*args, **kwargs)
예제 #21
0
 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)
예제 #22
0
 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)
     cluster_template = objects.ClusterTemplate(pecan.request.context,
                                                **cluster_template_dict)
     _enforce_network_driver_types(cluster_template)
     return func(*args, **kwargs)
예제 #23
0
 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)
     cluster_template = objects.ClusterTemplate(pecan.request.context,
                                                **cluster_template_dict)
     _enforce_network_driver_types(cluster_template)
     return func(*args, **kwargs)
예제 #24
0
    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)
예제 #25
0
파일: cluster.py 프로젝트: sangtq-vn/magnum
    def _patch(self, cluster_ident, patch):
        context = pecan.request.context
        if context.is_admin:
            policy.enforce(context,
                           "cluster:update_all_projects",
                           action="cluster:update_all_projects")
            context.all_tenants = True

        cluster = api_utils.get_resource('Cluster', cluster_ident)
        policy.enforce(context,
                       'cluster:update',
                       cluster.as_dict(),
                       action='cluster:update')
        policy.enforce(context,
                       "cluster:update_health_status",
                       action="cluster:update_health_status")
        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)

        # NOTE(brtknr): cluster.node_count is the size of the whole cluster
        # which includes non-default nodegroups. However cluster_update expects
        # node_count to be the size of the default_ng_worker therefore return
        # this value unless the patch object says otherwise.
        node_count = cluster.default_ng_worker.node_count
        for p in patch:
            if p['path'] == '/node_count':
                node_count = p.get('value') or new_cluster.node_count

        return (cluster, node_count, new_cluster.health_status,
                new_cluster.health_status_reason)
예제 #26
0
    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
        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 flag
        if cluster_template.public != new_cluster_template.public:
            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)
예제 #27
0
    def patch(self, rc_ident, bay_ident, patch):
        """Update an existing rc.

        :param rc_ident: UUID or logical name of a ReplicationController.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this rc.
        """
        rc_dict = {}
        rc_dict["manifest"] = None
        rc_dict["manifest_url"] = None
        try:
            rc = ReplicationController(**api_utils.apply_jsonpatch(rc_dict, patch))
            if rc.manifest or rc.manifest_url:
                rc.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_rc = pecan.request.rpcapi.rc_update(rc_ident, bay_ident, rc.manifest)
        return ReplicationController.convert_with_links(rpc_rc)
예제 #28
0
    def patch(self, pod_ident, bay_ident, patch):
        """Update an existing pod.

        :param pod_ident: UUID or logical name of a pod.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this pod.
        """
        pod_dict = {}
        pod_dict['manifest'] = None
        pod_dict['manifest_url'] = None
        try:
            pod = Pod(**api_utils.apply_jsonpatch(pod_dict, patch))
            if pod.manifest or pod.manifest_url:
                pod.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_pod = pecan.request.rpcapi.pod_update(pod_ident, bay_ident,
                                                  pod.manifest)
        return Pod.convert_with_links(rpc_pod)
예제 #29
0
파일: service.py 프로젝트: sidx64/magnum
    def patch(self, service_ident, bay_ident, patch):
        """Update an existing service.

        :param service_ident: UUID or logical name of a service.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this service.
        """
        service_dict = {}
        service_dict['manifest'] = None
        service_dict['manifest_url'] = None
        try:
            service = Service(**api_utils.apply_jsonpatch(service_dict, patch))
            if service.manifest or service.manifest_url:
                service.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_service = pecan.request.rpcapi.service_update(
            service_ident, bay_ident, service.manifest)
        return Service.convert_with_links(rpc_service)
예제 #30
0
파일: pod.py 프로젝트: MatMaul/magnum
    def patch(self, pod_ident, bay_ident, patch):
        """Update an existing pod.

        :param pod_ident: UUID or logical name of a pod.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this pod.
        """
        pod_dict = {}
        pod_dict['manifest'] = None
        pod_dict['manifest_url'] = None
        try:
            pod = Pod(**api_utils.apply_jsonpatch(pod_dict, patch))
            if pod.manifest or pod.manifest_url:
                pod.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_pod = pecan.request.rpcapi.pod_update(pod_ident, bay_ident,
                                                  pod.manifest)
        return Pod.convert_with_links(rpc_pod)
예제 #31
0
    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.BaymodelPublishDenied()

        # 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)
예제 #32
0
파일: service.py 프로젝트: Gobella/magnum
    def patch(self, service_ident, bay_ident, patch):
        """Update an existing service.

        :param service_ident: UUID or logical name of a service.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this service.
        """
        service_dict = {}
        service_dict['manifest'] = None
        service_dict['manifest_url'] = None
        try:
            service = Service(**api_utils.apply_jsonpatch(service_dict, patch))
            if service.manifest or service.manifest_url:
                service.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_service = pecan.request.rpcapi.service_update(service_ident,
                                                          bay_ident,
                                                          service.manifest)
        return Service.convert_with_links(rpc_service)
예제 #33
0
    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)
예제 #34
0
    def patch(self, rc_ident, bay_ident, patch):
        """Update an existing rc.

        :param rc_ident: UUID or logical name of a ReplicationController.
        :param bay_ident: UUID or logical name of the Bay.
        :param patch: a json PATCH document to apply to this rc.
        """
        rc_dict = {}
        rc_dict['manifest'] = None
        rc_dict['manifest_url'] = None
        try:
            rc = ReplicationController(**api_utils.apply_jsonpatch(rc_dict,
                                                                   patch))
            if rc.manifest or rc.manifest_url:
                rc.parse_manifest()
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        rpc_rc = pecan.request.rpcapi.rc_update(rc_ident,
                                                bay_ident,
                                                rc.manifest)
        return ReplicationController.convert_with_links(rpc_rc)
예제 #35
0
    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)
예제 #36
0
파일: test_utils.py 프로젝트: zonca/magnum
 def test_apply_jsonpatch(self, mock_jsonpatch):
     doc = {'cluster_uuid': 'id', 'node_count': 1}
     patch = [{"path": "/node_count", "value": 2, "op": "replace"}]
     utils.apply_jsonpatch(doc, patch)
     mock_jsonpatch.assert_called_once_with(doc, patch)
예제 #37
0
 def test_apply_jsonpatch(self, mock_jsonpatch):
     doc = {'bay_uuid': 'id', 'node_count': 1}
     patch = [{"path": "/node_count", "value": 2, "op": "replace"}]
     utils.apply_jsonpatch(doc, patch)
     mock_jsonpatch.assert_called_once_with(doc, patch)