Neutron - ML2 插件 create_network 函数剖析

ML2 插件 create_network 函数主要完成的工作有:

  • 分配待创建的 Network 的 Segment ID
  • 将待创建的 Network 的信息(含 Segment ID)存入对应的数据库表中
  • 通过 RPC 调用相应的代理做具体的配置工作

第三步后续会介绍

create_network 函数的主干流程如下,主要功能就是将相关信息入库。

def create_network(self, context, network):
    ...
    result, mech_context = self._create_network_db(context, network)
    ...

_create_network_db 函数的代码如下:

    def _create_network_db(self, context, network):
        ...
        with db_api.context_manager.writer.using(context):
            net_db = self.create_network_db(context, network)
            ...
            self.type_manager.create_network_segments(context, net_data,
                                                      tenant_id)
            ...
            self._process_l3_create(context, result, net_data)

        return result, mech_context

1. create_network_db 函数

    def create_network_db(self, context, network):
        # single request processing
        n = network['network']
        with db_api.CONTEXT_WRITER.using(context):
            args = {'tenant_id': n['tenant_id'],
                    'id': n.get('id') or uuidutils.generate_uuid(),
                    'name': n['name'],
                    'mtu': n.get('mtu'),
                    'admin_state_up': n['admin_state_up'],
                    'status': n.get('status', constants.NET_STATUS_ACTIVE),
                    'description': n.get('description')}
            network = models_v2.Network(**args)
            context.session.add(network)
            if n['shared']:
                np_rbac_args = {'project_id': network.project_id,
                                'object_id': network.id,
                                'action': 'access_as_shared',
                                'target_tenant': '*'}
                np_rbac_obj = network_obj.NetworkRBAC(context, **np_rbac_args)
                np_rbac_obj.create()
        return network

这个函数做了两件事情:

  • 将 Network 基本信息存入表 networks 中
  • 如果这个 network 是共享的(shared=true),那么在表 networkrbacs 中存入相关信息,且字段 action = ‘access_as_shared’

n['shared'] 对应就是 Network 模型中的 shared 字段:一个布尔值,如果为 true,则表示这个网络可以被所有租户共享。

表 networkrbacs 表示网络操作权限,其中的 object_id 是外键,指向表 networks 中的主键 id;若字段 actions = ‘access_as_shared’ 表示 object_id 所代表的 Network是全租户共享的。

Neutron - ML2 插件 create_network 函数剖析_第1张图片

2. _process_l3_create 函数

    def _process_l3_create(self, context, net_data, req_data):

        # external 对应 Network 模型中的 router:external 字段
        external = req_data.get(extnet_apidef.EXTERNAL)

        if external:
            # 向表 externnetworks 添加记录
            net_obj.ExternalNetwork(
                context, network_id=net_data['id']).create()
            net_rbac_args = {'project_id': net_data['tenant_id'],
                             'object_id': net_data['id'],
                             'action': 'access_as_external',
                             'target_tenant': '*'}
            # 向表 networkrbacs 添加记录
            net_obj.NetworkRBAC(context, **net_rbac_args).create()
        net_data[extnet_apidef.EXTERNAL] = external

这段代码中的 external 就是 network model 中的 router: external 字段,当它等于 true 时, 表示这个网络是关联 Router 上的外部网络。

Neutron - ML2 插件 create_network 函数剖析_第2张图片

3. self.type_manger.create_network_segments 函数

_create_network_db 函数主干流程的第三步是调用 self.type_manger.create_network_segments 函数。create_network_segments 代码如下:

    def create_network_segments(self, context, network, tenant_id):
        """Call type drivers to create network segments."""
        # 从传入的参数 network 中获取 segments
        # 传入参数 network 是指用户调用网络的 RESTful API 传的参数
        segments = self._process_provider_create(network)
        with db_api.context_manager.writer.using(context):
            # 如果传入参数中有 segments,则说明:
            # (1)用户具备管理员权限(2)创建的是运营商拓展网络
            network_id = network['id']
            if segments:
                for segment_index, segment in enumerate(segments):
                    # 调用 Type Driver 的 reserve_provider_segment 函数,将 segment 分配下来
                    segment = self.reserve_provider_segment(
                        context, segment)
                    self._add_network_segment(context, network_id, segment,
                                              segment_index)
            # 如果传入的是 Router 外部网关网络,并且配置了网络类型
            elif (cfg.CONF.ml2.external_network_type and
                  self._get_attribute(network, extnet_apidef.EXTERNAL)):
                segment = self._allocate_ext_net_segment(context)
                self._add_network_segment(context, network_id, segment)
            else:
                segment = self._allocate_tenant_net_segment(context)
                self._add_network_segment(context, network_id, segment)

Neutron - ML2 插件 create_network 函数剖析_第3张图片

你可能感兴趣的:(计算机网络,数据库)