Example #1
0
 def setUp(self):
     super(TestPnfServiceAppliance, self).setUp()
     logger.debug("setUp called")
     # Create Global system config object
     self.gsc_obj = self.api.global_system_config_read(
         GlobalSystemConfig().fq_name)
     self.default_gsc_name = 'default-global-system-config'
     # Create Service Appliance Set object
     self.sas_obj = ServiceApplianceSet('sas-' + self.id(), self.gsc_obj)
     self.sas_obj.set_service_appliance_set_virtualization_type(
         'physical-device')
     self.api.service_appliance_set_create(self.sas_obj)
     # Create PNF Physical Router object
     self.pnf_obj = PhysicalRouter('pnf-' + self.id(), self.gsc_obj)
     self.pnf_obj.set_physical_router_role('pnf')
     self.api.physical_router_create(self.pnf_obj)
     # Create spine Physical Router object
     self.spine_obj = PhysicalRouter('spine-' + self.id(), self.gsc_obj)
     self.api.physical_router_create(self.spine_obj)
     # create left, right PNF PI
     self.left_pnf_pi_obj = PhysicalInterface(
         'ge-0/0/1-' + self.id(), parent_obj=self.pnf_obj)
     self.right_pnf_pi_obj = PhysicalInterface(
         'ge-0/0/2-' + self.id(), parent_obj=self.pnf_obj)
     self.api.physical_interface_create(self.left_pnf_pi_obj)
     self.api.physical_interface_create(self.right_pnf_pi_obj)
     # create left, right spine PI
     self.left_spine_pi_obj = PhysicalInterface(
         'xe-0/0/1-' + self.id(), parent_obj=self.spine_obj)
     self.right_spine_pi_obj = PhysicalInterface(
         'xe-0/0/2-' + self.id(), parent_obj=self.spine_obj)
     self.api.physical_interface_create(self.left_spine_pi_obj)
     self.api.physical_interface_create(self.right_spine_pi_obj)
Example #2
0
 def test_more_than_one_sas_per_st(self):
     si_obj = self.api.service_instance_read(id=self.si_uuid)
     left_lr_obj = self.api.logical_router_read(id=self.left_lr_uuid)
     right_lr_obj = self.api.logical_router_read(id=self.right_lr_uuid)
     pt_obj = PortTuple('pt-' + self.id(), parent_obj=si_obj)
     pt_obj.add_logical_router(left_lr_obj)
     pt_obj.add_logical_router(right_lr_obj)
     kvp_array = []
     kvp = KeyValuePair("left-lr", self.left_lr_uuid)
     kvp_array.append(kvp)
     kvp = KeyValuePair("right-lr", self.right_lr_uuid)
     kvp_array.append(kvp)
     kvps = KeyValuePairs()
     kvps.set_key_value_pair(kvp_array)
     pt_obj.set_annotations(kvps)
     # Add another SAS to the ST
     gsc_obj = self.api.global_system_config_read(
         GlobalSystemConfig().fq_name)
     sas_obj = ServiceApplianceSet('sas1-' + self.id(), gsc_obj)
     sas_obj.set_service_appliance_set_virtualization_type(
         'physical-device')
     self.api.service_appliance_set_create(sas_obj)
     st_obj = self.api.service_template_read(id=self.st_uuid)
     st_obj.add_service_appliance_set(sas_obj)
     self.api.service_template_update(st_obj)
     st_obj = self.api.service_template_read(id=self.st_uuid)
     # Create PT
     self.api.port_tuple_create(pt_obj)
     #  Make sure no LI or IIP is created in this case
     li_list_len = \
         len(self.api.logical_interfaces_list().get('logical-interfaces'))
     self.assertEqual(li_list_len, 0)
     iip_list_len = \
         len(self.api.instance_ips_list().get('instance-ips'))
     self.assertEqual(iip_list_len, 0)
     # cleanup
     st_obj.del_service_appliance_set(sas_obj)
     self.api.service_template_update(st_obj)
     self.api.service_appliance_set_delete(id=sas_obj.uuid)
     self.api.port_tuple_delete(id=pt_obj.uuid)
     pass
Example #3
0
 def setUp(self):
     super(TestPnfServiceInstance, self).setUp()
     logger.debug("setUp called")
     # Create Global system config object
     gsc_obj = self.api.global_system_config_read(
         GlobalSystemConfig().fq_name)
     # Create Service Appliance Set object
     sas_obj = ServiceApplianceSet('sas-' + self.id(), gsc_obj)
     sas_obj.set_service_appliance_set_virtualization_type(
         'physical-device')
     self.sas_uuid = self.api.service_appliance_set_create(sas_obj)
     # Create Service template object
     self.st_obj = ServiceTemplate(name='st-' + self.id())
     self.st_obj.set_service_appliance_set(sas_obj)
     svc_properties = ServiceTemplateType()
     svc_properties.set_service_virtualization_type('physical-device')
     if_type = ServiceTemplateInterfaceType()
     if_type.set_service_interface_type('left')
     svc_properties.add_interface_type(if_type)
     if_type = ServiceTemplateInterfaceType()
     if_type.set_service_interface_type('right')
     svc_properties.add_interface_type(if_type)
     self.st_obj.set_service_template_properties(svc_properties)
     self.st_uuid = self.api.service_template_create(self.st_obj)
    def test_create_service_instance(self):
        sas_name = 'sas-1' + self.id()
        sas_fq_name = ['default-global-system-config', sas_name]
        sas = ServiceApplianceSet(
            fq_name=sas_fq_name,
            parent_type='global-system-config',
            service_appliance_set_virtualization_type='physical-device')
        self._vnc_lib.service_appliance_set_create(sas)

        sa_name = 'sa-1' + self.id()
        sa_fq_name = ['default-global-system-config', sas_name, sa_name]
        sa = ServiceAppliance(
            fq_name=sa_fq_name,
            parent_type='service-appliance-set',
            service_appliance_virtualization_type='physical-device')

        sa.set_service_appliance_properties(
            KeyValuePairs([
                KeyValuePair(key='left-attachment-point', value=self.pi1_0_fq),
                KeyValuePair(key='right-attachment-point', value=self.pi1_1_fq)
            ]))
        attr = ServiceApplianceInterfaceType(interface_type='left')
        sa.add_physical_interface(self.pi2_0, attr)
        attr = ServiceApplianceInterfaceType(interface_type='right')
        sa.add_physical_interface(self.pi2_1, attr)
        self._vnc_lib.service_appliance_create(sa)
        tid, td = self.check_trans_info('Service Appliance',
                                        'Create',
                                        sa_name,
                                        pr_name=self.pr1.name)

        st_name = 'st-1' + self.id()
        st_fq_name = ['default-domain', st_name]
        st = ServiceTemplate(fq_name=st_fq_name)
        st.set_service_appliance_set(sas)
        st.set_service_config_managed(False)
        svc_properties = ServiceTemplateType()
        svc_properties.set_service_virtualization_type('physical-device')
        if_type = ServiceTemplateInterfaceType(interface_type='left')
        svc_properties.add_interface_type(if_type)
        if_type = ServiceTemplateInterfaceType(interface_type='right')
        svc_properties.add_interface_type(if_type)
        st.set_service_template_properties(svc_properties)
        self._vnc_lib.service_template_create(st)
        self.check_trans_info(trans_id=tid,
                              trans_descr=td,
                              pr_name=self.pr1.name)

        si_name = 'si-' + self.id()
        si_fqn = ['default-domain', 'default-project', si_name]
        si = ServiceInstance(fq_name=si_fqn)
        si.fq_name = si_fqn
        si.add_service_template(st)
        kvp_array = []
        kvp = KeyValuePair("left-svc-vlan", "100")
        kvp_array.append(kvp)
        kvp = KeyValuePair("right-svc-vlan", "101")
        kvp_array.append(kvp)
        kvp = KeyValuePair("left-svc-asns", "66000,66001")
        kvp_array.append(kvp)
        kvp = KeyValuePair("right-svc-asns", "66000,66002")
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        si.set_annotations(kvps)
        props = ServiceInstanceType()
        props.set_service_virtualization_type('physical-device')
        props.set_ha_mode("active-standby")
        si.set_service_instance_properties(props)
        self._vnc_lib.service_instance_create(si)
        self.check_trans_info(trans_id=tid,
                              trans_descr=td,
                              pr_name=self.pr1.name)

        pt_name = 'pt-' + self.id()
        pt = PortTuple(pt_name, parent_obj=si)
        pt.add_logical_router(self.lr1)
        pt.add_logical_router(self.lr2)
        kvp_array = []
        kvp = KeyValuePair("left-lr", self.lr1.uuid)
        kvp_array.append(kvp)
        kvp = KeyValuePair("right-lr", self.lr2.uuid)
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        pt.set_annotations(kvps)
        self._vnc_lib.port_tuple_create(pt)
        self.check_trans_info('Service Instance',
                              'Create',
                              si_name,
                              pr_name=self.pr1.name)

        self._vnc_lib.port_tuple_delete(id=pt.uuid)
        self.check_trans_info('Service Instance',
                              'Delete',
                              si_name,
                              pr_name=self.pr1.name)

        self._vnc_lib.service_appliance_delete(fq_name=sa.fq_name)
        self.check_trans_info('Service Appliance',
                              'Delete',
                              sa_name,
                              pr_name=self.pr1.name)
Example #5
0
    def setUp(self):
        def _carve_out_subnets(subnets, cidr):
            carved_subnets = []
            for subnet in subnets:
                slash_x_subnets = IPNetwork(subnet.get('cidr')).subnet(cidr)
                for slash_x_sn in slash_x_subnets:
                    carved_subnets.append({'cidr': str(slash_x_sn)})
            return carved_subnets
        # end _carve_out_subnets

        def _get_network_ipam(ipam_name, subnets, subnetting):
            def _new_subnet(cidr):
                split_cidr = cidr.split('/')
                return SubnetType(
                    ip_prefix=split_cidr[0],
                    ip_prefix_len=split_cidr[1])
            # end _new_subnet
            ipam = NetworkIpam(
                name=ipam_name,
                ipam_subnets=IpamSubnets([
                    IpamSubnetType(
                        subnet=_new_subnet(sn.get('cidr')),
                        default_gateway=sn.get('gateway'),
                        subnet_uuid=str(uuid.uuid1())
                    ) for sn in subnets if int(
                        sn.get('cidr').split('/')[-1]) < 31
                ]),
                ipam_subnet_method='flat-subnet',
                ipam_subnetting=subnetting
            )
            return ipam
        # end _add_network_ipam
        super(TestPnfPortTuple, self).setUp()
        logger.debug("setUp called")
        # Create Global objects
        default_gsc_name = 'default-global-system-config'
        gsc_obj = self.api.global_system_config_read(
            GlobalSystemConfig().fq_name)
        proj_obj = self.api.project_read(Project().fq_name)
        # Create PNF and spine Physical Router
        pnf_obj = PhysicalRouter('pnf-' + self.id(), gsc_obj)
        pnf_obj.set_physical_router_role('pnf')
        self.pnf_uuid = self.api.physical_router_create(pnf_obj)
        # Create spine Physical Router
        spine_obj = PhysicalRouter('spine-' + self.id(), gsc_obj)
        self.spine_uuid = self.api.physical_router_create(spine_obj)
        # Create left/right LR
        left_lr_name = 'left_lr-' + self.id()
        left_lr_obj = LogicalRouter(name=left_lr_name, parent_obj=proj_obj)
        left_lr_obj.add_physical_router(spine_obj)
        self.left_lr_uuid = self.api.logical_router_create(left_lr_obj)
        right_lr_name = 'right_lr-' + self.id()
        right_lr_obj = LogicalRouter(name=right_lr_name, parent_obj=proj_obj)
        right_lr_obj.add_physical_router(spine_obj)
        self.right_lr_uuid = self.api.logical_router_create(right_lr_obj)
        # create left, right PNF PI
        left_pnf_pi_obj = PhysicalInterface(
            'ge-0/0/1-' + self.id(), parent_obj=pnf_obj)
        right_pnf_pi_obj = PhysicalInterface(
            'ge-0/0/2-' + self.id(), parent_obj=pnf_obj)
        lo_pnf_pi_obj = PhysicalInterface('lo0', parent_obj=pnf_obj)
        self.left_pnf_pi_uuid = self.api.physical_interface_create(
            left_pnf_pi_obj)
        self.right_pnf_pi_uuid = self.api.physical_interface_create(
            right_pnf_pi_obj)
        self.lo_pnf_pi_uuid = self.api.physical_interface_create(lo_pnf_pi_obj)
        # create left, right spine PI
        left_spine_pi_obj = PhysicalInterface(
            'xe-0/0/1-' + self.id(), parent_obj=spine_obj)
        right_spine_pi_obj = PhysicalInterface(
            'xe-0/0/2-' + self.id(), parent_obj=spine_obj)
        self.left_spine_pi_uuid = self.api.physical_interface_create(
            left_spine_pi_obj)
        self.right_spine_pi_uuid = self.api.physical_interface_create(
            right_spine_pi_obj)
        # Create Service Appliance Set
        sas_obj = ServiceApplianceSet('sas-' + self.id(), gsc_obj)
        sas_obj.set_service_appliance_set_virtualization_type(
            'physical-device')
        self.sas_uuid = self.api.service_appliance_set_create(sas_obj)
        # Create Service template
        st_obj = ServiceTemplate(name='st-' + self.id())
        st_obj.set_service_appliance_set(sas_obj)
        svc_properties = ServiceTemplateType()
        svc_properties.set_service_virtualization_type('physical-device')
        if_type = ServiceTemplateInterfaceType()
        if_type.set_service_interface_type('left')
        svc_properties.add_interface_type(if_type)
        if_type = ServiceTemplateInterfaceType()
        if_type.set_service_interface_type('right')
        svc_properties.add_interface_type(if_type)
        st_obj.set_service_template_properties(svc_properties)
        self.st_uuid = self.api.service_template_create(st_obj)
        # Create Service Instance object
        si_fqn = ['default-domain', 'default-project', 'si-' + self.id()]
        si_obj = ServiceInstance(fq_name=si_fqn)
        si_obj.fq_name = si_fqn
        si_obj.add_service_template(st_obj)
        kvp_array = []
        kvp = KeyValuePair("left-svc-vlan", "100")
        kvp_array.append(kvp)
        kvp = KeyValuePair("right-svc-vlan", "101")
        kvp_array.append(kvp)
        kvp = KeyValuePair("left-svc-asns", "66000,66001")
        kvp_array.append(kvp)
        kvp = KeyValuePair("right-svc-asns", "66000,66002")
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        si_obj.set_annotations(kvps)
        props = ServiceInstanceType()
        props.set_service_virtualization_type('physical-device')
        props.set_ha_mode("active-standby")
        si_obj.set_service_instance_properties(props)
        self.si_uuid = self.api.service_instance_create(si_obj)
        # Create service appliance
        sa_obj = ServiceAppliance('sa-' + self.id(), parent_obj=sas_obj)
        kvp_array = []
        kvp = KeyValuePair(
            "left-attachment-point",
            default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/1-' +
            self.id())
        kvp_array.append(kvp)
        kvp = KeyValuePair(
            "right-attachment-point",
            default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/2-' +
            self.id())
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        sa_obj.set_service_appliance_properties(kvps)
        sa_obj.set_service_appliance_virtualization_type('physical-device')
        attr = ServiceApplianceInterfaceType(interface_type='left')
        sa_obj.add_physical_interface(left_pnf_pi_obj, attr)
        attr = ServiceApplianceInterfaceType(interface_type='right')
        sa_obj.add_physical_interface(right_pnf_pi_obj, attr)
        self.sa_uuid = self.api.service_appliance_create(sa_obj)
        # Create fabric and add it to spine and PNF
        fab_obj = Fabric('fab-' + self.id())
        self.fab_uuid = self.api.fabric_create(fab_obj)
        pnf_obj.add_fabric(fab_obj)
        self.api.physical_router_update(pnf_obj)
        spine_obj.add_fabric(fab_obj)
        self.api.physical_router_update(spine_obj)
        fab_obj = self.api.fabric_read(id=self.fab_uuid)
        # Create PNF service chain IPAM/network
        pnf_cidr = [{'cidr': "10.1.1.0/28"}]
        peer_subnets = _carve_out_subnets(pnf_cidr, 29)
        pnf_vn_obj = VirtualNetwork(
            name='fab-' + self.id() + '-pnf-servicechain-network',
            virtual_network_properties=VirtualNetworkType(
                forwarding_mode='l3'),
            address_allocation_mode='flat-subnet-only')
        self.pnf_vn_uuid = self.api.virtual_network_create(pnf_vn_obj)
        pnf_ipam_obj = _get_network_ipam(
            'fab-' +
            self.id() +
            '-pnf-servicechain-network-ipam',
            peer_subnets,
            True)
        self.pnf_ipam_uuid = self.api.network_ipam_create(pnf_ipam_obj)
        pnf_vn_obj.add_network_ipam(pnf_ipam_obj, VnSubnetsType([]))
        self.api.virtual_network_update(pnf_vn_obj)
        fab_obj = self.api.fabric_read(id=self.fab_uuid)
        fab_obj.add_virtual_network(
            pnf_vn_obj, FabricNetworkTag(
                network_type='pnf-servicechain'))
        self.api.fabric_update(fab_obj)
        # Create loopback IPAM/network
        lo_cidr = [{'cidr': "100.100.100.0/28"}]
        peer_subnets = _carve_out_subnets(lo_cidr, 28)
        lo_vn_obj = VirtualNetwork(
            name='fab-' + self.id() + '-loopback-network',
            virtual_network_properties=VirtualNetworkType(
                forwarding_mode='l3'),
            address_allocation_mode='flat-subnet-only')
        self.lo_vn_uuid = self.api.virtual_network_create(lo_vn_obj)
        lo_ipam_obj = _get_network_ipam(
            'fab-' +
            self.id() +
            '-loopback-network-ipam',
            peer_subnets,
            False)
        self.lo_ipam_uuid = self.api.network_ipam_create(lo_ipam_obj)
        lo_vn_obj.add_network_ipam(lo_ipam_obj, VnSubnetsType([]))
        self.api.virtual_network_update(lo_vn_obj)
        fab_obj = self.api.fabric_read(id=self.fab_uuid)
        fab_obj.add_virtual_network(
            lo_vn_obj, FabricNetworkTag(
                network_type='loopback'))
        self.api.fabric_update(fab_obj)
Example #6
0
class TestPnfServiceAppliance(TestServiceApplianceBase):
    def setUp(self):
        super(TestPnfServiceAppliance, self).setUp()
        logger.debug("setUp called")
        # Create Global system config object
        self.gsc_obj = self.api.global_system_config_read(
            GlobalSystemConfig().fq_name)
        self.default_gsc_name = 'default-global-system-config'
        # Create Service Appliance Set object
        self.sas_obj = ServiceApplianceSet('sas-' + self.id(), self.gsc_obj)
        self.sas_obj.set_service_appliance_set_virtualization_type(
            'physical-device')
        self.api.service_appliance_set_create(self.sas_obj)
        # Create PNF Physical Router object
        self.pnf_obj = PhysicalRouter('pnf-' + self.id(), self.gsc_obj)
        self.pnf_obj.set_physical_router_role('pnf')
        self.api.physical_router_create(self.pnf_obj)
        # Create spine Physical Router object
        self.spine_obj = PhysicalRouter('spine-' + self.id(), self.gsc_obj)
        self.api.physical_router_create(self.spine_obj)
        # create left, right PNF PI
        self.left_pnf_pi_obj = PhysicalInterface(
            'ge-0/0/1-' + self.id(), parent_obj=self.pnf_obj)
        self.right_pnf_pi_obj = PhysicalInterface(
            'ge-0/0/2-' + self.id(), parent_obj=self.pnf_obj)
        self.api.physical_interface_create(self.left_pnf_pi_obj)
        self.api.physical_interface_create(self.right_pnf_pi_obj)
        # create left, right spine PI
        self.left_spine_pi_obj = PhysicalInterface(
            'xe-0/0/1-' + self.id(), parent_obj=self.spine_obj)
        self.right_spine_pi_obj = PhysicalInterface(
            'xe-0/0/2-' + self.id(), parent_obj=self.spine_obj)
        self.api.physical_interface_create(self.left_spine_pi_obj)
        self.api.physical_interface_create(self.right_spine_pi_obj)

    def tearDown(self):
        super(TestPnfServiceAppliance, self).tearDown()
        logger.debug("TearDown called")
        # delete PNF PI
        self.api.physical_interface_delete(id=self.left_pnf_pi_obj.uuid)
        self.api.physical_interface_delete(id=self.right_pnf_pi_obj.uuid)
        # delete spine PI
        self.api.physical_interface_delete(id=self.left_spine_pi_obj.uuid)
        self.api.physical_interface_delete(id=self.right_spine_pi_obj.uuid)
        # delete PNF PR and spine PR
        self.api.physical_router_delete(id=self.spine_obj.uuid)
        self.api.physical_router_delete(id=self.pnf_obj.uuid)
        # delete sas
        self.api.service_appliance_set_delete(id=self.sas_obj.uuid)

    def test_valid_sa(self):
        sa_obj = ServiceAppliance('sa-' + self.id(), parent_obj=self.sas_obj)
        kvp_array = []
        kvp = KeyValuePair(
            "left-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/1-' +
            self.id())
        kvp_array.append(kvp)
        kvp = KeyValuePair(
            "right-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/2-' +
            self.id())
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        sa_obj.set_service_appliance_properties(kvps)
        sa_obj.set_service_appliance_virtualization_type('physical-device')

        # Add PNF PI refs
        attr = ServiceApplianceInterfaceType(interface_type='left')
        sa_obj.add_physical_interface(self.left_pnf_pi_obj, attr)
        attr = ServiceApplianceInterfaceType(interface_type='right')
        sa_obj.add_physical_interface(self.right_pnf_pi_obj, attr)

        # Create SA
        self.api.service_appliance_create(sa_obj)
        self.left_pnf_pi_obj = self.api.physical_interface_read(
            id=self.left_pnf_pi_obj.uuid)
        self.right_pnf_pi_obj = self.api.physical_interface_read(
            id=self.right_pnf_pi_obj.uuid)

        # Check if spine PI <-> PNF PI link has been created
        self.assertEqual(
            self.left_pnf_pi_obj.physical_interface_refs[0].get('uuid'),
            self.left_spine_pi_obj.uuid)
        self.assertEqual(
            self.right_pnf_pi_obj.physical_interface_refs[0].get('uuid'),
            self.right_spine_pi_obj.uuid)

        # Delete service appliance
        self.api.service_appliance_delete(id=sa_obj.uuid)

        # Check if spine PI <-> PNF PI link got removed
        self.left_pnf_pi_obj = self.api.physical_interface_read(
            id=self.left_pnf_pi_obj.uuid)
        self.right_pnf_pi_obj = self.api.physical_interface_read(
            id=self.right_pnf_pi_obj.uuid)
        self.assertFalse(
            hasattr(
                self.left_pnf_pi_obj,
                "physical_interface_refs"))
        self.assertFalse(
            hasattr(
                self.right_pnf_pi_obj,
                "physical_interface_refs"))

    def test_sa_with_invalid_kvp(self):
        sa_obj = ServiceAppliance('sa-' + self.id(), parent_obj=self.sas_obj)
        kvp_array = []
        kvp = KeyValuePair(
            "left-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/1-' +
            self.id())
        kvp_array.append(kvp)
        kvp = KeyValuePair(
            "right-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/2-' +
            self.id())
        # The next line is intentionally commented out
        # kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        sa_obj.set_service_appliance_properties(kvps)
        sa_obj.set_service_appliance_virtualization_type('physical-device')

        # Add PNF PI refs
        attr = ServiceApplianceInterfaceType(interface_type='left')
        sa_obj.add_physical_interface(self.left_pnf_pi_obj, attr)
        attr = ServiceApplianceInterfaceType(interface_type='right')
        sa_obj.add_physical_interface(self.right_pnf_pi_obj, attr)

        # Create SA should raise exception
        self.assertRaises(
            BadRequest,
            self.api.service_appliance_create,
            sa_obj)

    def test_sa_with_invalid_pr_role(self):
        sa_obj = ServiceAppliance('sa-' + self.id(), parent_obj=self.sas_obj)
        kvp_array = []
        kvp = KeyValuePair(
            "left-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/1-' +
            self.id())
        kvp_array.append(kvp)
        kvp = KeyValuePair(
            "right-attachment-point",
            self.default_gsc_name +
            ':' +
            'spine-' +
            self.id() +
            ':' +
            'xe-0/0/2-' +
            self.id())
        kvp_array.append(kvp)
        kvps = KeyValuePairs()
        kvps.set_key_value_pair(kvp_array)
        sa_obj.set_service_appliance_properties(kvps)
        sa_obj.set_service_appliance_virtualization_type('physical-device')

        # Add PNF PI refs
        attr = ServiceApplianceInterfaceType(interface_type='left')
        sa_obj.add_physical_interface(self.left_pnf_pi_obj, attr)
        attr = ServiceApplianceInterfaceType(interface_type='right')
        sa_obj.add_physical_interface(self.right_pnf_pi_obj, attr)

        # Overwrite the role as leaf instead of pnf
        self.pnf_obj.set_physical_router_role('leaf')
        self.api.physical_router_update(self.pnf_obj)
        # Create SA should raise exception
        self.assertRaises(BadRequest,
                          self.api.service_appliance_create,
                          sa_obj)