示例#1
0
    def patch(self, template_ident, patch=None):
        """Update an existing deploy template.

        :param template_ident: UUID or logical name of a deploy template.
        :param patch: a json PATCH document to apply to this deploy template.
        """
        api_utils.check_policy('baremetal:deploy_template:update')

        api_utils.patch_validate_allowed_fields(patch, PATCH_ALLOWED_FIELDS)

        context = api.request.context
        rpc_template = api_utils.get_rpc_deploy_template_with_suffix(
            template_ident)

        template = rpc_template.as_dict()

        # apply the patch
        template = api_utils.apply_jsonpatch(template, patch)

        # validate the result with the patch schema
        for step in template.get('steps', []):
            api_utils.patched_validate_with_schema(
                step, api_utils.DEPLOY_STEP_SCHEMA)
        api_utils.patched_validate_with_schema(template, TEMPLATE_SCHEMA,
                                               TEMPLATE_VALIDATOR)

        api_utils.patch_update_changed_fields(
            template,
            rpc_template,
            fields=objects.DeployTemplate.fields,
            schema=TEMPLATE_SCHEMA)

        # NOTE(mgoddard): There could be issues with concurrent updates of a
        # template. This is particularly true for the complex 'steps' field,
        # where operations such as modifying a single step could result in
        # changes being lost, e.g. two requests concurrently appending a step
        # to the same template could result in only one of the steps being
        # added, due to the read/modify/write nature of this patch operation.
        # This issue should not be present for 'simple' string fields, or
        # complete replacement of the steps (the only operation supported by
        # the openstack baremetal CLI). It's likely that this is an issue for
        # other resources, even those modified in the conductor under a lock.
        # This is due to the fact that the patch operation is always applied in
        # the API. Ways to avoid this include passing the patch to the
        # conductor to apply while holding a lock, or a collision detection
        # & retry mechansim using e.g. the updated_at field.
        notify.emit_start_notification(context, rpc_template, 'update')
        with notify.handle_error_notification(context, rpc_template, 'update'):
            rpc_template.save()

        api_template = convert_with_links(rpc_template)
        notify.emit_end_notification(context, rpc_template, 'update')

        return api_template
示例#2
0
    def delete(self, template_ident):
        """Delete a deploy template.

        :param template_ident: UUID or logical name of a deploy template.
        """
        api_utils.check_policy('baremetal:deploy_template:delete')

        context = api.request.context
        rpc_template = api_utils.get_rpc_deploy_template_with_suffix(
            template_ident)
        notify.emit_start_notification(context, rpc_template, 'delete')
        with notify.handle_error_notification(context, rpc_template, 'delete'):
            rpc_template.destroy()
        notify.emit_end_notification(context, rpc_template, 'delete')
示例#3
0
    def get_one(self, template_ident, fields=None):
        """Retrieve information about the given deploy template.

        :param template_ident: UUID or logical name of a deploy template.
        :param fields: Optional, a list with a specified set of fields
            of the resource to be returned.
        """
        api_utils.check_policy('baremetal:deploy_template:get')

        api_utils.check_allowed_fields(fields)

        rpc_template = api_utils.get_rpc_deploy_template_with_suffix(
            template_ident)

        return DeployTemplate.convert_with_links(rpc_template, fields=fields)
    def patch(self, template_ident, patch=None):
        """Update an existing deploy template.

        :param template_ident: UUID or logical name of a deploy template.
        :param patch: a json PATCH document to apply to this deploy template.
        """
        api_utils.check_policy('baremetal:deploy_template:update')

        context = pecan.request.context
        rpc_template = api_utils.get_rpc_deploy_template_with_suffix(
            template_ident)

        try:
            template_dict = rpc_template.as_dict()
            template = DeployTemplate(
                **api_utils.apply_jsonpatch(template_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)
        template.validate(template)
        self._update_changed_fields(template, rpc_template)

        # NOTE(mgoddard): There could be issues with concurrent updates of a
        # template. This is particularly true for the complex 'steps' field,
        # where operations such as modifying a single step could result in
        # changes being lost, e.g. two requests concurrently appending a step
        # to the same template could result in only one of the steps being
        # added, due to the read/modify/write nature of this patch operation.
        # This issue should not be present for 'simple' string fields, or
        # complete replacement of the steps (the only operation supported by
        # the openstack baremetal CLI). It's likely that this is an issue for
        # other resources, even those modified in the conductor under a lock.
        # This is due to the fact that the patch operation is always applied in
        # the API. Ways to avoid this include passing the patch to the
        # conductor to apply while holding a lock, or a collision detection
        # & retry mechansim using e.g. the updated_at field.
        notify.emit_start_notification(context, rpc_template, 'update')
        with notify.handle_error_notification(context, rpc_template, 'update'):
            rpc_template.save()

        api_template = DeployTemplate.convert_with_links(rpc_template)
        notify.emit_end_notification(context, rpc_template, 'update')

        return api_template