heat使用trust流程简析


       heat是openstack中的一个编排模块,里面有一个比较有意思的特性:弹性伸缩。
但是当heat触发弹性伸的时候,如果遇到创建虚拟机,则应该使用创建这个弹性伸缩组的用户/租户的权限来进行创建。
这就要求heat需要保存创建弹性伸缩组的用户信息,并且连密码也需要保存,这种方式比较古老。
        通过keystone v3提供的新特性:trust,可以授权指定用户具有某一个项目下的特定操作权限。
本文主要描述了下该trust在heat中的简单流程。


一、api入口
位于 heat/api/openstack/v1/stacks.py 中的 create 方法


    @util.policy_enforce
    def create(self, req, body):
        data = InstantiationData(body)
        args = self.prepare_args(data)
        result = self.rpc_client.create_stack(
            req.context,
            data.stack_name(),
            data.template(),
            data.environment(),
            data.files(),
            args,
            environment_files=data.environment_files())
        formatted_stack = stacks_view.format_stack(
            req,
            {rpc_api.STACK_ID: result}
        )
        return {'stack': formatted_stack}

二、通过rpc走到heat-engine中的service回调接口
   路径:heat/engine/service.py 

    @context.request_context
    def create_stack(self, cnxt, stack_name, template, params, files,
                     args, environment_files=None,
                     owner_id=None, nested_depth=0, user_creds_id=None,
                     stack_user_project_id=None, parent_resource_name=None,
                     template_id=None):
        """Create a new stack using the template provided.
        Note that at this stage the template has already been fetched from the
        heat-api process if using a template-url.
        :param cnxt: RPC context.
        :param stack_name: Name of the stack you want to create.
        :param template: Template of stack you want to create.
        :param params: Stack Input Params
        :param files: Files referenced from the template
        :param args: Request parameters/args passed from API
        :param environment_files: optional ordered list of environment file
               names included in the files dict
        :type  environment_files: list or None
        :param owner_id: parent stack ID for nested stacks, only expected when
                         called from another heat-engine (not a user option)
        :param nested_depth: the nested depth for nested stacks, only expected
                         when called from another heat-engine
        :param user_creds_id: the parent user_creds record for nested stacks
        :param stack_user_project_id: the parent stack_user_project_id for
                         nested stacks
        :param parent_resource_name: the parent resource name
        :param template_id: the ID of a pre-stored template in the DB
        """
        LOG.info(_LI('Creating stack %s'), stack_name)


        def _create_stack_user(stack):
            if not stack.stack_user_project_id:
                try:
                    stack.create_stack_user_project_id()
                except exception.AuthorizationFailure as ex:
                    stack.state_set(stack.action, stack.FAILED,
                                    six.text_type(ex))

        def _stack_create(stack, msg_queue=None):
            # Create/Adopt a stack, and create the periodic task if successful
            if stack.adopt_stack_data:
                stack.adopt()
            elif stack.status != stack.FAILED:
                stack.create(msg_queue=msg_queue)


            if (stack.action in (stack.CREATE, stack.ADOPT)
                    and stack.status == stack.COMPLETE):
                if self.stack_watch:
                    # Schedule a periodic watcher task for this stack
                    self.stack_watch.start_watch_task(stack.id, cnxt)
            else:
                LOG.info(_LI("Stack create failed, status %s"), stack.status)


        convergence = cfg.CONF.convergence_engine


        stack = self._parse_template_and_validate_stack(
            cnxt, stack_name, template, params, files, environment_files,
            args, owner_id, nested_depth, user_creds_id,
            stack_user_project_id, convergence, parent_resource_name,
            template_id)


        self.resource_enforcer.enforce_stack(stack)
        
        # 这里创建trust
        stack_id = stack.store()
        if cfg.CONF.reauthentication_auth_method == 'trusts':
            stack = parser.Stack.load(
                cnxt, stack_id=stack_id, use_stored_context=True)
        _create_stack_user(stack)
        if convergence:
            action = stack.CREATE
            if stack.adopt_stack_data:
                action = stack.ADOPT
            stack.thread_group_mgr = self.thread_group_mgr
            stack.converge_stack(template=stack.t, action=action)
        else:
            msg_queue = eventlet.queue.LightQueue()
            th = self.thread_group_mgr.start_with_lock(cnxt, stack,
                                                       self.engine_id,
                                                       _stack_create, stack,
                                                       msg_queue=msg_queue)
            th.link(self.thread_group_mgr.remove_msg_queue,
                    stack.id, msg_queue)
            self.thread_group_mgr.add_msg_queue(stack.id, msg_queue)


        return dict(stack.identifier())


三、保存栈信息,并创建信任授权信息
    @profiler.trace('Stack.store', hide_args=False)
    def store(self, backup=False, exp_trvsl=None,
              ignore_traversal_check=False):
        """Store the stack in the database and return its ID.


        If self.id is set, we update the existing stack.
        """
        s = self.get_kwargs_for_cloning(keep_status=True, only_db=True)
        s['name'] = self.name
        s['backup'] = backup
        s['updated_at'] = self.updated_time
        if self.t.id is None:
            stack_object.Stack.encrypt_hidden_parameters(self.t)
            s['raw_template_id'] = self.t.store(self.context)
        else:
            s['raw_template_id'] = self.t.id


        if self.id:
            if exp_trvsl is None and not ignore_traversal_check:
                exp_trvsl = self.current_traversal


            if self.convergence:
                # do things differently for convergence
                updated = stack_object.Stack.select_and_update(
                    self.context, self.id, s, exp_trvsl=exp_trvsl)


                if not updated:
                    return None
            else:
                stack_object.Stack.update_by_id(self.context, self.id, s)


        else:
            if not self.user_creds_id:
                # Create a context containing a trust_id and trustor_user_id
                # if trusts are enabled
                
                # 调用keystone 的代码,使用trust创建租户间的信任
                # create_trust_context 里面即为trust授权,具体的流程机制见文档末尾的链接
                if cfg.CONF.deferred_auth_method == 'trusts':
                    keystone = self.clients.client('keystone')
                    trust_ctx = keystone.create_trust_context()
                    new_creds = ucreds_object.UserCreds.create(trust_ctx)
                else:
                    new_creds = ucreds_object.UserCreds.create(self.context)
                s['user_creds_id'] = new_creds.id
                self.user_creds_id = new_creds.id


            if self.convergence:
                    # create a traversal ID
                    self.current_traversal = uuidutils.generate_uuid()
                    s['current_traversal'] = self.current_traversal


            new_s = stack_object.Stack.create(self.context, s)
            self.id = new_s.id
            self.created_time = new_s.created_at


        if self.tags:
            stack_tag_object.StackTagList.set(self.context, self.id, self.tags)


        self._set_param_stackid()


        return self.id
              
四、相关资料
    openstack keystone trust信任机制相关资料:
    http://www.tuicool.com/articles/N3aM7b
    https://docs.openstack.org/admin-guide/orchestration-auth-model.html
    


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值