def dcnm_network_create_event(self, network_info):

        # 1. Add network info to database before sending request to
        # neutron to create the network.
        # Check if network is already created.
        pre_seg_id = network_info.get('segmentation_id')
        pre_project_name = network_info.get('project_name')
        pre_partition_name = network_info.get('partition_name')
        if not pre_seg_id or not pre_partition_name or not pre_project_name:
            LOG.error(_LE('Invalid network event: %s'), network_info)
            return

        # Check if partition name is the one that openstack created.
        if pre_partition_name != self.cfg.dcnm.default_partition_name:
            LOG.error(_LE('Failed to create network. Partition %(part)s is '
                          'not %(os_part)s which is created by openstack.'),
                      {'part': pre_partition_name,
                       'os_part': self.cfg.dcnm.default_partition_name})
            return

        query_net = self.get_network_by_segid(pre_seg_id)
        if query_net:
            # The network is already created no need to process the event.
            LOG.info(_LI('dcnm_network_create_event: network %(name)s was '
                     'created. Ignoring processing the event.'),
                     {'name': query_net.name})
            return

        dcnm_net_info = self.dcnm_client.get_network(pre_project_name,
                                                     pre_seg_id)
        if not dcnm_net_info:
            LOG.info(_LI('No network details for %(org)s and %(segid)s'),
                     {'org': pre_project_name, 'segid': pre_seg_id})
            return

        net_id = utils.get_uuid()
        pseg_id = dcnm_net_info.get('segmentId')
        seg_id = self._get_segmentation_id(pseg_id)
        cfgp = dcnm_net_info.get('profileName')
        net_name = dcnm_net_info.get('networkName')
        fwd_mod = self.dcnm_client.config_profile_fwding_mode_get(cfgp)
        tenant_name = dcnm_net_info.get('organizationName')
        tenant_id = self.get_project_id(tenant_name)

        # Get the subnet details.
        subnet = dcnm_net_info.get('dhcpScope')
        if not subnet:
            # The dhcpScope is not provided. Calculating the cidr based on
            # gateway ip and netmask.
            gw_addr = dcnm_net_info.get('gateway')
            net_mask = dcnm_net_info.get('netmaskLength')
            cidr = utils.make_cidr(gw_addr, net_mask)
            if not cidr:
                LOG.error(_LE('Failed to create network: '
                          'cidr is None for %(gw)s %(mask)s'),
                          {'gw': gw_addr, 'mask': net_mask})
                return
            subnet = dict(gateway=gw_addr, subnet=cidr)

        # Check if parameters are provided.
        if not (net_name and tenant_id and seg_id and subnet):
            LOG.error(_LE('Invalid value: network %(name)s tenant_id '
                      '%(tenant_id)s segmentation_id %(seg_id)s '
                          'subnet %(subnet)s.'), {'name': net_name,
                                                  'tenant_id': tenant_id,
                                                  'seg_id': seg_id,
                                                  'subnet': subnet})
            return

        # Update network cache and add the network to the database.
        net_ext_name = self.cfg.dcnm.dcnm_net_ext
        self.network[net_id] = dict(segmentation_id=seg_id,
                                    config_profile=cfgp,
                                    fwd_mod=fwd_mod,
                                    tenant_id=tenant_id,
                                    name=net_name + net_ext_name,
                                    id=net_id,
                                    source='DCNM')
        self.add_network_db(net_id, self.network[net_id], 'DCNM',
                            constants.RESULT_SUCCESS)

        # 2. Send network create request to neutron
        try:
            # With create_network (called below), the same request comes as
            # notification and it will be processed in the
            # create_network_event. The request should not be processed as it
            # is already processed here.
            # The only way to decide whether it is for a new network or not is
            # the segmentation_id (DCNM does not have uuid for network) which
            # is unique. For that reason it is needed to send segmentation_id
            # when creating network in openstack.
            # Moreover, we are using network_type=local and for that reason
            # provider:segmentation_id cannot be added as parameter when
            # creating network. One solution is to embed segmentation_id in the
            # network name. Then, when processing the notification, if the
            # request is from DCNM, the segmentation_id will be extracted from
            # network name. With that create_network_event can decide to
            # process or deny an event.
            updated_net_name = net_name + net_ext_name + str(seg_id)
            body = {'network': {'name': updated_net_name,
                                'tenant_id': tenant_id,
                                'admin_state_up': True}}
            dcnm_net = self.neutronclient.create_network(
                body=body).get('network')
            net_id = dcnm_net.get('id')

        except Exception as exc:
            # Failed to create network, do clean up.
            # Remove the entry from database and local cache.
            del self.network[net_id]
            self.delete_network_db(net_id)
            LOG.exception(_LE('dcnm_network_create_event: Failed to create '
                          '%(network)s. Reason %(err)s.'),
                          {'network': body, 'err': str(exc)})
            return

        LOG.debug('dcnm_network_create_event: Created network %(network)s', (
            body))

        # 3. Send subnet create request to neutron.
        pool = subnet.get('ipRange')
        allocation_pools = []
        if pool:
            allocation_pools = [{'start': s, 'end': e} for s, e in
                                [p.split('-') for p in pool.split(',')]]

        try:
            body = {'subnet': {'cidr': subnet.get('subnet'),
                               'gateway_ip': subnet.get('gateway'),
                               'ip_version': 4,
                               'network_id': net_id,
                               'tenant_id': tenant_id,
                               'enable_dhcp': not self.dcnm_dhcp,
                               'allocation_pools': allocation_pools, }}
            if not self.dcnm_dhcp:
                body.get('subnet').pop('allocation_pools')
            # Send requenst to create subnet in neutron.
            LOG.debug('Creating subnet %(subnet)s for DCNM request.', body)
            dcnm_subnet = self.neutronclient.create_subnet(
                body=body).get('subnet')
            subnet_id = dcnm_subnet.get('id')
            # Update subnet cache.
            self.subnet[subnet_id] = {}
            self.subnet[subnet_id].update(body.get('subnet'))
        except Exception as exc:
            # Failed to create network, do clean up if necessary.
            LOG.exception(_LE('Failed to create subnet %(subnet)s for DCNM '
                          'request. Error %(err)s'),
                          {'subnet': body['subnet'], 'err': str(exc)})

        LOG.debug('dcnm_network_create_event: Created subnet %(subnet)s', (
            body))
Process network create event from DCNM.
dataset/ETHPy150Open openstack/networking-cisco/networking_cisco/apps/saf/server/dfa_server.py/DfaServer.dcnm_network_create_event