def test_resources_exists(self):
        api = VncApiMock(
            self.args.auth_user,
            self.args.auth_password,
            self.args.auth_tenant,
            self.args.vnc_endpoint_ip,
            self.args.vnc_endpoint_port,
            self.args.auth_token_url
        )
        domain_fq_name = ['default-domain']
        domain = api.domain_read(fq_name=domain_fq_name)

        proj_uuid = api.project_create(Project("default", parent_obj=domain))
        proj = api.project_read(id=proj_uuid)

        # Create cluster-default-pod-network
        ipam_uuid = api.network_ipam_create(NetworkIpam("pod-ipam", proj))
        ipam = api.network_ipam_read(id=ipam_uuid)
        net = VirtualNetwork("cluster-default-pod-network", proj)
        # No subnets are associated with IPAM at this point.
        # Subnets will be updated in the IPAM, when cluster is created.
        net.add_network_ipam(ipam, VnSubnetsType([]))
        api.virtual_network_create(net)

        # Create cluster-default-service-network
        ipam_uuid = api.network_ipam_create(NetworkIpam("service-ipam", proj))
        ipam = api.network_ipam_read(id=ipam_uuid)
        net = VirtualNetwork("cluster-default-service-network", proj)
        # No subnets are associated with IPAM at this point.
        # Subnets will be updated in the IPAM, when cluster is created.
        net.add_network_ipam(ipam, VnSubnetsType([]))
        api.virtual_network_create(net)

        vnc_kubernetes.VncKubernetes(self.args, Mock())
Exemple #2
0
    def _create_virtual_network(self, vn_name, proj_obj, ipam_obj, \
                ipam_update, provider=None, subnets=None, \
                type='flat-subnet-only'):
        vn_exists = False
        vn = VirtualNetwork(name=vn_name,
                            parent_obj=proj_obj,
                            address_allocation_mode=type)
        try:
            vn_obj = self._vnc_lib.virtual_network_read(
                fq_name=vn.get_fq_name())
            vn_exists = True
        except NoIdError:
            # VN does not exist. Create one.
            vn_obj = vn

        if vn_exists:
            return vn_obj

        # Attach IPAM to virtual network.
        #
        # For flat-subnets, the subnets are specified on the IPAM and
        # not on the virtual-network to IPAM link. So pass an empty
        # list of VnSubnetsType.
        # For user-defined-subnets, use the provided subnets
        if ipam_update or \
           not self._is_ipam_exists(vn_obj, ipam_obj.get_fq_name()):
            if subnets and type == 'user-defined-subnet-only':
                vn_obj.add_network_ipam(ipam_obj, subnets)
            else:
                vn_obj.add_network_ipam(ipam_obj, VnSubnetsType([]))

        vn_obj.set_virtual_network_properties(
            VirtualNetworkType(forwarding_mode='l3'))

        fabric_snat = False
        if self.ip_fabric_snat:
            fabric_snat = True

        if not vn_exists:
            if self.ip_fabric_forwarding:
                if provider:
                    #enable ip_fabric_forwarding
                    vn_obj.add_virtual_network(provider)
            elif fabric_snat:
                #enable fabric_snat
                vn_obj.set_fabric_snat(True)
            else:
                #disable fabric_snat
                vn_obj.set_fabric_snat(False)
            # Create VN.
            self._vnc_lib.virtual_network_create(vn_obj)
        else:
            # TODO: Handle Network update
            pass

        vn_obj = self._vnc_lib.virtual_network_read(
            fq_name=vn_obj.get_fq_name())
        VirtualNetworkKM.locate(vn_obj.uuid)

        return vn_obj
Exemple #3
0
    def test_out_of_order_rabbit_publish(self):
        """ Test to make sure api-server preserves the state of the
            object even if the CREATE msg is queued after UPDATE in rabbit
        """
        self.wait_till_api_server_idle()

        api_server = self._server_info['api_server']
        orig_dbe_create_publish = api_server._db_conn._msgbus.dbe_create_publish
        self.block_untill_update_publish = True

        def out_of_order_dbe_create_publish(obj_type, obj_ids, *args,
                                            **kwargs):
            if obj_type == 'virtual_network':
                while self.block_untill_update_publish:
                    gevent.sleep(1)
            return orig_dbe_create_publish(obj_type, obj_ids, *args, **kwargs)

        api_server._db_conn._msgbus.dbe_create_publish = \
                out_of_order_dbe_create_publish
        logger.info("Creating VN object, without publishing it to IFMAP.")
        vn_obj = VirtualNetwork('vn1')
        vn_obj.set_uuid(str(uuid.uuid4()))
        ipam_obj = NetworkIpam('ipam1')
        vn_obj.add_network_ipam(ipam_obj, VnSubnetsType())
        self._vnc_lib.network_ipam_create(ipam_obj)
        vn_create_greenlet = gevent.spawn(self._vnc_lib.virtual_network_create,
                                          vn_obj)
        gevent.sleep(0)
        logger.info("Update VN object, Expected to update the object in",
                    "Cassandra DB and skip publishing to IFMAP.")
        vn_obj = self._vnc_lib.virtual_network_read(id=vn_obj.uuid)
        vn_obj.display_name = 'test_update_1'
        self._vnc_lib.virtual_network_update(vn_obj)
        gevent.sleep(2)
        with testtools.ExpectedException(KeyError):
            api_server._db_conn._ifmap_db._id_to_metas[\
                    'contrail:virtual-network:default-domain:default-project:vn1']

        logger.info(
            "Unblock create notify to amqp, Create expected to read from DB",
            "and publish to IFMAP with the updated object info.")
        self.block_untill_update_publish = False
        vn_uuid = vn_create_greenlet.get(timeout=3)
        gevent.sleep(2)
        self.assertEqual(api_server._db_conn._ifmap_db._id_to_metas[\
                'contrail:virtual-network:default-domain:default-project:vn1'][\
                'display-name']['']._Metadata__value, 'test_update_1')

        logger.info(
            "update after publishing to IFAMAP, Expected to publish to IFMAP")
        vn_obj.display_name = 'test_update_2'
        self._vnc_lib.virtual_network_update(vn_obj)
        gevent.sleep(2)
        self.assertEqual(api_server._db_conn._ifmap_db._id_to_metas[\
                'contrail:virtual-network:default-domain:default-project:vn1'][\
                'display-name']['']._Metadata__value, 'test_update_2')
Exemple #4
0
 def _create_network_ipam(self, name, network_type, subnet, proj_obj,
                          vn_obj=None):
     ipam_obj = NetworkIpam(name=name, parent_obj=proj_obj)
     pfx, pfx_len = subnet.split('/')
     ipam_subnet = IpamSubnetType(subnet=SubnetType(pfx, int(pfx_len)))
     if network_type == 'flat-subnet':
         ipam_obj.set_ipam_subnet_method('flat-subnet')
         ipam_obj.set_ipam_subnets(IpamSubnets([ipam_subnet]))
     try:
         self._vnc_lib.network_ipam_create(ipam_obj)
     except RefsExistError:
         ipam_obj = self._vnc_lib.network_ipam_read(
             fq_name=ipam_obj.get_fq_name())
     if vn_obj:
         if network_type == 'flat-subnet':
             vn_obj.add_network_ipam(ipam_obj, VnSubnetsType([]))
         else:
             vn_obj.add_network_ipam(ipam_obj, VnSubnetsType([ipam_subnet]))
     return ipam_obj
    def test_out_of_order_rabbit_publish(self):
        """ Test to make sure api-server preserves the state of the
            object even if the CREATE msg is queued after UPDATE in rabbit
        """
        self.wait_till_api_server_idle()

        api_server = self._server_info['api_server']
        orig_dbe_create_publish = api_server._db_conn._msgbus.dbe_create_publish
        self.block_untill_update_publish = True

        def out_of_order_dbe_create_publish(obj_type, obj_ids, *args,
                                            **kwargs):
            if obj_type == 'virtual_network':
                while self.block_untill_update_publish:
                    gevent.sleep(1)
            return orig_dbe_create_publish(obj_type, obj_ids, *args, **kwargs)

        api_server._db_conn._msgbus.dbe_create_publish = \
                out_of_order_dbe_create_publish
        logger.info("Creating VN object, without publishing it to IFMAP.")
        vn_obj = VirtualNetwork('vn1')
        vn_obj.set_uuid(str(uuid.uuid4()))
        ipam_obj = NetworkIpam('ipam1')
        vn_obj.add_network_ipam(ipam_obj, VnSubnetsType())
        self._vnc_lib.network_ipam_create(ipam_obj)
        vn_create_greenlet = gevent.spawn(self._vnc_lib.virtual_network_create,
                                          vn_obj)
        gevent.sleep(0)
        logger.info("Update VN object, Expected to update the object in",
                    "Cassandra DB and skip publishing to IFMAP.")
        vn_obj = self._vnc_lib.virtual_network_read(id=vn_obj.uuid)
        vn_obj.display_name = 'test_update_1'
        self._vnc_lib.virtual_network_update(vn_obj)
        gevent.sleep(2)
        self.assertTill(self.ifmap_doesnt_have_ident, obj=vn_obj)

        logger.info(
            "Unblock create notify to amqp, Create expected to read from DB",
            "and publish to IFMAP with the updated object info.")
        self.block_untill_update_publish = False
        vn_uuid = vn_create_greenlet.get(timeout=3)
        self.assertTill(self.ifmap_ident_has_link,
                        obj=vn_obj,
                        link_name='display-name')
        self.assertTrue('test_update_1' in self.ifmap_ident_has_link(
            obj=vn_obj, link_name='display-name')['meta'])

        logger.info(
            "update after publishing to IFAMAP, Expected to publish to IFMAP")
        vn_obj.display_name = 'test_update_2'
        self._vnc_lib.virtual_network_update(vn_obj)
        self.assertTill(lambda: 'test_update_2' in self.ifmap_ident_has_link(
            obj=vn_obj, link_name='display-name')['meta'])
Exemple #6
0
    def _create_isolated_ns_virtual_network(self, ns_name, vn_name,
                    proj_obj, ipam_obj=None, provider=None):
        """
        Create a virtual network for this namespace.
        """
        vn = VirtualNetwork(
            name=vn_name, parent_obj=proj_obj,
            virtual_network_properties=VirtualNetworkType(forwarding_mode='l3'),
            address_allocation_mode='flat-subnet-only')

        # Add annotatins on this isolated virtual-network.
        VirtualNetworkKM.add_annotations(self, vn, namespace=ns_name,
                                         name=ns_name, isolated='True')

        try:
            vn_uuid = self._vnc_lib.virtual_network_create(vn)
        except RefsExistError:
            vn_obj = self._vnc_lib.virtual_network_read(
                fq_name=vn.get_fq_name())
            vn_uuid = vn_obj.uuid
            vn = vn_obj

        # Instance-Ip for pods on this VN, should be allocated from
        # cluster pod ipam. Attach the cluster pod-ipam object
        # to this virtual network.
        vn.add_network_ipam(ipam_obj, VnSubnetsType([]))

        # enable ip-fabric-forwarding
        if provider:
            ip_fabric_forwarding = self._get_ip_fabric_forwarding(ns_name)
            if ip_fabric_forwarding == True:
                add_provider = True
            elif ip_fabric_forwarding == False:
                add_provider = False
            else:
                add_provider = self._args.ip_fabric_forwarding

            if add_provider:
                vn.add_virtual_network(provider)
            else:
                vn_refs = vn.get_virtual_network_refs()
                for vn_ref in vn_refs or []:
                    vn_ref_obj = self._vnc_lib.virtual_network_read(id=vn_ref['uuid'])
                    vn.del_virtual_network(vn_ref_obj)

        # Update VN.
        self._vnc_lib.virtual_network_update(vn)

        # Cache the virtual network.
        VirtualNetworkKM.locate(vn_uuid)

        return vn
 def test_resources_exists(self):
     api = VncApiMock(self.args.auth_user, self.args.auth_password,
                      self.args.auth_tenant, self.args.vnc_endpoint_ip,
                      self.args.vnc_endpoint_port, self.args.auth_token_url)
     domain_uuid = api.domain_create(Domain("default-domain"))
     domain = api.domain_read(id=domain_uuid)
     proj_uuid = api.project_create(Project("default", parent_obj=domain))
     proj = api.project_read(id=proj_uuid)
     ipam_uuid = api.network_ipam_create(NetworkIpam("pod-ipam", proj))
     ipam = api.network_ipam_read(id=ipam_uuid)
     net = VirtualNetwork("cluster-network", proj)
     net.add_network_ipam(ipam, VnSubnetsType([]))
     api.virtual_network_create(net)
     vnc_kubernetes.VncKubernetes(self.args, Mock())
Exemple #8
0
 def create_vn_with_subnets(self,
                            id,
                            vn_name,
                            ipam_obj,
                            subnet,
                            subnetmask=24):
     vn_obj = VirtualNetwork(vn_name)
     vn_obj_properties = VirtualNetworkType()
     vn_obj_properties.set_vxlan_network_identifier(2000 + id)
     vn_obj_properties.set_forwarding_mode('l2_l3')
     vn_obj.set_virtual_network_properties(vn_obj_properties)
     vn_obj.add_network_ipam(
         ipam_obj,
         VnSubnetsType([IpamSubnetType(SubnetType(subnet, subnetmask))]))
     vn_uuid = self._vnc_lib.virtual_network_create(vn_obj)
     return self._vnc_lib.virtual_network_read(id=vn_uuid)
Exemple #9
0
    def _create_isolated_ns_virtual_network(self, ns_name, vn_name, proj_obj):
        """
        Create a virtual network for this namespace.
        """
        vn = VirtualNetwork(name=vn_name,
                            parent_obj=proj_obj,
                            virtual_network_properties=VirtualNetworkType(
                                forwarding_mode='l3'),
                            address_allocation_mode='flat-subnet-only')

        # Add annotatins on this isolated virtual-network.
        VirtualNetworkKM.add_annotations(self,
                                         vn,
                                         namespace=ns_name,
                                         name=ns_name,
                                         isolated='True')

        try:
            vn_uuid = self._vnc_lib.virtual_network_create(vn)
        except RefsExistError:
            vn_obj = self._vnc_lib.virtual_network_read(
                fq_name=vn.get_fq_name())
            vn_uuid = vn_obj.uuid

        # Instance-Ip for pods on this VN, should be allocated from
        # cluster pod ipam. Attach the cluster pod-ipam object
        # to this virtual network.
        ipam_fq_name = vnc_kube_config.pod_ipam_fq_name()
        ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name)
        vn.add_network_ipam(ipam_obj, VnSubnetsType([]))

        # Update VN.
        self._vnc_lib.virtual_network_update(vn)
        try:
            ip_fabric_vn_obj = self._vnc_lib. \
                virtual_network_read(fq_name=self._ip_fabric_fq_name)
            self._create_attach_policy(proj_obj, ip_fabric_vn_obj, vn)
        except NoIdError:
            pass

        # Cache the virtual network.
        VirtualNetworkKM.locate(vn_uuid)

        # Cache network info in namespace entry.
        self._set_namespace_virtual_network(ns_name, vn.get_fq_name())

        return vn_uuid
Exemple #10
0
 def _create_subnet_data(self, vn_subnet):
     subnets = [vn_subnet] if isinstance(vn_subnet,
                                         basestring) else vn_subnet
     subnet_infos = []
     for subnet in subnets:
         cidr = IPNetwork(subnet)
         subnet_infos.append(
             IpamSubnetType(
                 subnet=SubnetType(
                     str(cidr.network),
                     int(cidr.prefixlen),
                 ),
                 default_gateway=str(IPAddress(cidr.last - 1)),
                 subnet_uuid=str(uuid.uuid4()),
             ))
     subnet_data = VnSubnetsType(subnet_infos)
     return subnet_data
    def test_rbac_on_back_ref(self):
        admin_iip_count = 10
        iip_uuids = set()
        user_api = self._get_api_client(
            'user-%s' % self.id(),
            'password',
            'project-%s' % self.id(),
            'member')
        user_project = self.admin_api.project_read(id=user_api.project_id)

        user_vn = VirtualNetwork(
            'user-vn-%s' % self.id(), parent_obj=user_project)
        user_ni = NetworkIpam('ni-%s' % self.id(), parent_obj=user_project)
        user_api.network_ipam_create(user_ni)
        user_vn.add_network_ipam(
            user_ni,
            VnSubnetsType(
                [IpamSubnetType(SubnetType('1.1.1.0', 28))]))
        user_api.virtual_network_create(user_vn)
        user_vmi_view = VirtualMachineInterface(
            'user-vmi-%s' % self.id(), parent_obj=user_project)
        user_vmi_view.add_virtual_network(user_vn)
        user_api.virtual_machine_interface_create(user_vmi_view)

        user_iip = InstanceIp('user-iip-%s' % self.id())
        user_iip.add_virtual_network(user_vn)
        user_iip.add_virtual_machine_interface(user_vmi_view)
        user_api.instance_ip_create(user_iip)
        iip_uuids.add(user_iip.uuid)

        for i in range(admin_iip_count):
            admin_iip = InstanceIp('admin-iip-%d-%s' % (i, self.id()))
            admin_iip.add_virtual_network(user_vn)
            admin_iip.add_virtual_machine_interface(user_vmi_view)
            self.admin_api.instance_ip_create(admin_iip)
            iip_uuids.add(admin_iip.uuid)

        user_iips = user_vmi_view.get_instance_ip_back_refs()
        self.assertEqual(len(user_iips), 1)
        self.assertEqual(user_iips[0]['uuid'], user_iip.uuid)
        admin_vmi_view = self.admin_api.virtual_machine_interface_read(
            id=user_vmi_view.uuid)
        admin_iips = admin_vmi_view.get_instance_ip_back_refs()
        self.assertEqual(len(admin_iips), admin_iip_count + 1)
        self.assertEqual({iip['uuid'] for iip in admin_iips}, iip_uuids)
    def create_vn_with_subnets(self, id, vn_name, ipam_obj, subnet,
                               subnetmask=24):
        vn_obj = VirtualNetwork(vn_name)
        vn_obj_properties = VirtualNetworkType()
        vn_obj_properties.set_vxlan_network_identifier(2000 + id)
        vn_obj_properties.set_forwarding_mode('l2_l3')

        vn_obj.set_virtual_network_properties(vn_obj_properties)
        vn_obj.add_network_ipam(ipam_obj, VnSubnetsType(
            [IpamSubnetType(SubnetType(subnet, subnetmask))]))
        vn_uuid = self._vnc_lib.virtual_network_create(vn_obj)
        vn_obj_rd = self._vnc_lib.virtual_network_read(id=vn_uuid)
        # make sure RT for vn is created
        rt = []
        try:
            rt = self._get_route_target(vn_obj_rd)
        except Exception:
            pass
        return vn_obj, self._vnc_lib.virtual_network_read(id=vn_uuid), rt
Exemple #13
0
    def test_get_floating_ip_project_ref(self):
        # create project
        project = Project(name='project-{}'.format(self.id()))
        p_uuid = self._vnc_lib.project_create(project)
        project.set_uuid(p_uuid)

        # create virtual network
        vn = VirtualNetwork(name='vn-{}'.format(self.id()),
                            parent_obj=project)
        vn.add_network_ipam(NetworkIpam(), VnSubnetsType([
            IpamSubnetType(SubnetType('1.1.1.0', 28)),
        ]))
        vn_uuid = self._vnc_lib.virtual_network_create(vn)
        vn.set_uuid(vn_uuid)

        # create floating IP pool
        fip_pool = FloatingIpPool(name='fip_p-{}'.format(self.id()),
                                  parent_obj=vn)
        fip_p_uuid = self._vnc_lib.floating_ip_pool_create(fip_pool)
        fip_pool.set_uuid(fip_p_uuid)

        # finally, create floating IP
        fip = FloatingIp(name='fip-{}'.format(self.id()),
                         parent_obj=fip_pool)
        fip_uuid = self._vnc_lib.floating_ip_create(fip)

        # get floating IPs
        fip_list = self._vnc_lib.floating_ips_list(obj_uuids=[fip_uuid],
                                                   fields=['project_refs'],
                                                   detail=True)
        self.assertEqual(len(fip_list), 1)
        project_refs = fip_list[0].get_project_refs()
        self.assertEqual(len(project_refs), 1)

        self.assertEqual(project_refs[0]['uuid'], p_uuid)
        self.assertEqual(project_refs[0]['to'], project.fq_name)
Exemple #14
0
    def test_public_snat_routes(self):

        # create private vn
        vn_private_name = self.id() + 'vn1'
        vn_private = self.create_virtual_network(vn_private_name, "1.0.0.0/24")

        # create virtual machine interface
        vmi_name = self.id() + 'vmi1'
        vmi = VirtualMachineInterface(
            vmi_name,
            parent_type='project',
            fq_name=['default-domain', 'default-project', vmi_name])
        vmi.add_virtual_network(vn_private)
        self._vnc_lib.virtual_machine_interface_create(vmi)

        # create public vn
        vn_public_name = 'vn-public'
        vn_public = VirtualNetwork(vn_public_name)
        vn_public.set_router_external(True)
        ipam_obj = NetworkIpam('ipam')
        self._vnc_lib.network_ipam_create(ipam_obj)
        vn_public.add_network_ipam(
            ipam_obj,
            VnSubnetsType([IpamSubnetType(SubnetType("192.168.7.0", 24))]))
        self._vnc_lib.virtual_network_create(vn_public)

        # create logical router, set route targets,
        # add private network and extend lr to public network
        lr_name = self.id() + 'lr1'
        lr = LogicalRouter(lr_name)
        rtgt_list = RouteTargetList(route_target=['target:1:1'])
        lr.set_configured_route_target_list(rtgt_list)
        lr.add_virtual_machine_interface(vmi)
        lr.add_virtual_network(vn_public)
        self._vnc_lib.logical_router_create(lr)

        @retries(5)
        def _match_route_table(rtgt_list, ri_name):
            lri = self._vnc_lib.routing_instance_read(fq_name_str=ri_name)
            sr = lri.get_static_route_entries()
            if sr is None:
                raise Exception("sr is None")
            route = sr.route[0]
            self.assertEqual(route.prefix, "0.0.0.0/0")
            self.assertEqual(route.next_hop, "100.64.0.4")
            for rtgt in rtgt_list:
                self.assertIn(rtgt, route.route_target)

        @retries(5)
        def _wait_to_get_si():
            si_list = self._vnc_lib.service_instances_list()
            si = si_list.get("service-instances")[0]
            si = self._vnc_lib.service_instance_read(id=si.get("uuid"))
            return si

        @retries(5)
        def _wait_to_delete_si():
            si_list = self._vnc_lib.service_instances_list()
            try:
                si = si_list.get("service-instances")[0]
                si = self._vnc_lib.service_instance_read(id=si.get("uuid"))
                raise
            except Exception:
                pass

        @retries(5)
        def _wait_to_delete_ip(vn_fq_name):
            vn = self._vnc_lib.virtual_network_read(fq_name=vn_fq_name)
            ip_refs = vn.get_instance_ip_back_refs()
            if ip_refs:
                raise
            return

        # end

        si = _wait_to_get_si()
        si_props = si.get_service_instance_properties().get_interface_list()[1]
        ri_name = si_props.virtual_network + ":" + \
            si_props.virtual_network.split(':')[-1]
        lr_rtgt = self._vnc_lib.logical_router_read(
            id=lr.uuid).route_target_refs[0]['to'][0]
        _match_route_table(['target:1:1', lr_rtgt], ri_name)

        rtgt_list = RouteTargetList(route_target=['target:2:2'])
        lr.set_configured_route_target_list(rtgt_list)
        self._vnc_lib.logical_router_update(lr)
        _match_route_table(['target:2:2', lr_rtgt], ri_name)

        lr.del_virtual_network(vn_public)
        self._vnc_lib.logical_router_update(lr)
        _wait_to_delete_si()

        # cleanup
        self._vnc_lib.logical_router_delete(fq_name=lr.get_fq_name())
        self._vnc_lib.virtual_machine_interface_delete(
            fq_name=vmi.get_fq_name())
        _wait_to_delete_ip(vn_private.get_fq_name())
        self._vnc_lib.virtual_network_delete(fq_name=vn_private.get_fq_name())
        _wait_to_delete_ip(vn_public.get_fq_name())
        self._vnc_lib.virtual_network_delete(fq_name=vn_public.get_fq_name())
Exemple #15
0
    def _create_isolated_ns_virtual_network(self,
                                            ns_name,
                                            vn_name,
                                            vn_type,
                                            proj_obj,
                                            ipam_obj=None,
                                            provider=None,
                                            enforce_policy=False):
        """
        Create/Update a virtual network for this namespace.
        """
        vn_exists = False
        vn = VirtualNetwork(name=vn_name,
                            parent_obj=proj_obj,
                            virtual_network_properties=VirtualNetworkType(
                                forwarding_mode='l3'),
                            address_allocation_mode='flat-subnet-only')
        try:
            vn_obj = self._vnc_lib.virtual_network_read(
                fq_name=vn.get_fq_name())
            vn_exists = True
        except NoIdError:
            # VN does not exist. Create one.
            vn_obj = vn
        # Add annotatins on this isolated virtual-network.
        VirtualNetworkKM.add_annotations(self,
                                         vn,
                                         namespace=ns_name,
                                         name=ns_name,
                                         isolated='True')
        # Instance-Ip for pods on this VN, should be allocated from
        # cluster pod ipam. Attach the cluster pod-ipam object
        # to this virtual network.
        vn_obj.add_network_ipam(ipam_obj, VnSubnetsType([]))

        fabric_snat = False
        if vn_type == 'pod-network':
            if self._is_ip_fabric_snat_enabled(ns_name):
                fabric_snat = True

        if not vn_exists:
            if provider:
                # enable ip_fabric_forwarding
                vn_obj.add_virtual_network(provider)
            elif fabric_snat:
                # enable fabric_snat
                vn_obj.set_fabric_snat(True)
            else:
                # disable fabric_snat
                vn_obj.set_fabric_snat(False)
            vn_uuid = self._vnc_lib.virtual_network_create(vn_obj)
            # Cache the virtual network.
            VirtualNetworkKM.locate(vn_uuid)
        else:
            ip_fabric_enabled = False
            if provider:
                vn_refs = vn_obj.get_virtual_network_refs()
                ip_fabric_fq_name = provider.fq_name
                for vn in vn_refs or []:
                    vn_fq_name = vn['to']
                    if vn_fq_name == ip_fabric_fq_name:
                        ip_fabric_enabled = True
                        break
            if not ip_fabric_enabled and fabric_snat:
                # enable fabric_snat
                vn_obj.set_fabric_snat(True)
            else:
                # disable fabric_snat
                vn_obj.set_fabric_snat(False)
            # Update VN.
            self._vnc_lib.virtual_network_update(vn_obj)
            vn_uuid = vn_obj.get_uuid()

        vn_obj = self._vnc_lib.virtual_network_read(id=vn_uuid)

        # If required, enforce security policy at virtual network level.
        if enforce_policy:
            self._vnc_lib.set_tags(
                vn_obj,
                self._labels.get_labels_dict(
                    VncSecurityPolicy.cluster_aps_uuid))

        return vn_obj
    def test_network_create(self):
        subnet = '192.168.1.0'
        prefix = 24
        subnet_1 = '10.1.1.0'
        vn_name = 'my-fe'
        vn = VirtualNetwork(vn_name, self._proj_obj)
        ipam_sn_1 = IpamSubnetType(subnet=SubnetType(subnet, prefix))
        ipam_sn_2 = IpamSubnetType(subnet=SubnetType(subnet_1, prefix))
        vn.add_network_ipam(
            self._ipam_obj, VnSubnetsType([ipam_sn_1, ipam_sn_2]))
        self._vnc_lib.virtual_network_create(vn)
        net_obj = self._vnc_lib.virtual_network_read(id=vn.uuid)
        # Ensure entries present in KV
        kvp = self._vnc_lib.kv_retrieve()
        self.assertIn(
            '%s 192.168.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])
        self.assertIn('%s 10.1.1.0/24' % (vn.uuid), [p['value'] for p in kvp])

        # Ensure entry present in KV
        key = net_obj.uuid + " " + subnet + '/' + str(prefix)
        subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[
            0].subnet_uuid
        key_tmp = self._vnc_lib.kv_retrieve(subnet_uuid)
        self.assertEqual(key, key_tmp)

        key = net_obj.uuid + " " + subnet_1 + '/' + str(prefix)
        subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[
            1].subnet_uuid
        key_tmp = self._vnc_lib.kv_retrieve(subnet_uuid)
        self.assertEqual(key, key_tmp)

        # Test delete
        self._vnc_lib.virtual_network_delete(id=vn.uuid)
        # Ensure all entries are gone
        kvp = self._vnc_lib.kv_retrieve()
        self.assertNotIn(
            '%s 192.168.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])
        self.assertNotIn(
            '%s 10.1.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])

        # Test update
        vn_name = 'my-be'
        subnet_2 = '9.1.1.0'
        vn = VirtualNetwork(vn_name, self._proj_obj)
        ipam_sn_1 = IpamSubnetType(subnet=SubnetType(subnet_2, prefix))
        vn.add_network_ipam(self._ipam_obj, VnSubnetsType([ipam_sn_1]))
        self._vnc_lib.virtual_network_create(vn)
        net_obj = self._vnc_lib.virtual_network_read(id=vn.uuid)

        # Ensure entry in KV
        kvp = self._vnc_lib.kv_retrieve()
        self.assertIn('%s 9.1.1.0/24' % (vn.uuid), [p['value'] for p in kvp])
        key = net_obj.uuid + " " + subnet_2 + '/' + str(prefix)
        subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[
            0].subnet_uuid
        key_tmp = self._vnc_lib.kv_retrieve(subnet_uuid)
        self.assertEqual(key, key_tmp)

        subnet_3 = '8.1.1.0'
        ipam_sn_2 = IpamSubnetType(subnet=SubnetType(subnet_3, prefix))
        ipam_refs = net_obj.get_network_ipam_refs()
        if ipam_refs:
            for ipam_ref in ipam_refs:
                ipam_ref['attr'].set_ipam_subnets([ipam_sn_2])
                net_obj._pending_field_updates.add('network_ipam_refs')
        self._vnc_lib.virtual_network_update(net_obj)
        # Ensure entry in KV
        kvp = self._vnc_lib.kv_retrieve()
        self.assertIn('%s 8.1.1.0/24' % (vn.uuid), [p['value'] for p in kvp])
        key = net_obj.uuid + " " + subnet_3 + '/' + str(prefix)
        net_obj = self._vnc_lib.virtual_network_read(id=net_obj.uuid)
        subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[
            0].subnet_uuid
        key_tmp = self._vnc_lib.kv_retrieve(subnet_uuid)
        self.assertEqual(key, key_tmp)

        # Test delete
        self._vnc_lib.virtual_network_delete(id=vn.uuid)
        kvp = self._vnc_lib.kv_retrieve()
        self.assertNotIn(
            '%s 9.1.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])
        self.assertNotIn(
            '%s 8.1.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])

        # Test ref_update
        vn_name = 'my-ref'
        vn = VirtualNetwork(vn_name, self._proj_obj)
        self._vnc_lib.virtual_network_create(vn)
        net_obj = self._vnc_lib.virtual_network_read(id=vn.uuid)

        subnet_3 = '99.1.1.0'
        ipam_sn_3 = IpamSubnetType(subnet=SubnetType(subnet_3, prefix))
        self._vnc_lib.ref_update(
            'virtual-network',
            net_obj.uuid,
            'network-ipam-refs',
            None,
            self._ipam_obj.get_fq_name(),
            'ADD',
            VnSubnetsType(
                [ipam_sn_3]))
        # Ensure entries in KV
        kvp = self._vnc_lib.kv_retrieve()
        self.assertIn('%s 99.1.1.0/24' % (vn.uuid), [p['value'] for p in kvp])
        key = net_obj.uuid + " " + subnet_3 + '/' + str(prefix)
        net_obj = self._vnc_lib.virtual_network_read(id=net_obj.uuid)
        subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[
            0].subnet_uuid
        key_tmp = self._vnc_lib.kv_retrieve(subnet_uuid)
        self.assertEqual(key, key_tmp)

        self._vnc_lib.ref_update(
            'virtual-network',
            net_obj.uuid,
            'network-ipam-refs',
            None,
            self._ipam_obj.get_fq_name(),
            'DELETE')
        kvp = self._vnc_lib.kv_retrieve()
        self.assertNotIn(
            '%s 99.1.1.0/24' %
            (vn.uuid), [
                p['value'] for p in kvp])

        # Test delete
        self._vnc_lib.virtual_network_delete(id=vn.uuid)