Skip to content

Commit

Permalink
Add has_pnf property to routing instances as required
Browse files Browse the repository at this point in the history
When a pnf service instance is added to a service chain, the corresponding service routing instance and
primary routing instance need to have has_pnf property set. Similarly, the property needs to be unset
when no pnf service instances are attached to the network.

Also added test case for the same but it is disabled for now because it needs service monitor changes
which are still not committed.

Change-Id: I806345df6e57b4e497282dfe490c4bb344925ddf
Closes-Bug: 1496695
  • Loading branch information
Sachin Bansal committed Oct 1, 2015
1 parent 2827724 commit 7a26ec7
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 59 deletions.
67 changes: 33 additions & 34 deletions src/config/common/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,49 +453,48 @@ def create_virtual_network(self, vn_name, vn_subnet):
return vn_obj
# end create_virtual_network

def _create_service(self, vn1, vn2, si_name, service_mode, service_type, auto_policy):
sti = [ServiceTemplateInterfaceType(
'left'), ServiceTemplateInterfaceType('right')]
st_prop = ServiceTemplateType(
service_type=service_type,
flavor='medium',
image_name='junk',
ordered_interfaces=True,
service_mode=service_mode, interface_type=sti)
service_template = ServiceTemplate(
name=si_name + 'template',
service_template_properties=st_prop)
self._vnc_lib.service_template_create(service_template)
scale_out = ServiceScaleOutType()
if service_mode == 'in-network':
if_list = [ServiceInstanceInterfaceType(virtual_network=vn1.get_fq_name_str()),
ServiceInstanceInterfaceType(virtual_network=vn2.get_fq_name_str())]
si_props = ServiceInstanceType(
auto_policy=auto_policy, interface_list=if_list,
scale_out=scale_out)
else:
if_list = [ServiceInstanceInterfaceType(),
ServiceInstanceInterfaceType()]
si_props = ServiceInstanceType(interface_list=if_list,
scale_out=scale_out)
service_instance = ServiceInstance(
name=si_name, service_instance_properties=si_props)
service_instance.add_service_template(service_template)
self._vnc_lib.service_instance_create(service_instance)
return service_instance.get_fq_name_str()
def _create_service(self, vn1, vn2, si_name, auto_policy, **kwargs):
sti = [ServiceTemplateInterfaceType(
'left'), ServiceTemplateInterfaceType('right')]
st_prop = ServiceTemplateType(
flavor='medium',
image_name='junk',
ordered_interfaces=True,
interface_type=sti, **kwargs)
service_template = ServiceTemplate(
name=si_name + 'template',
service_template_properties=st_prop)
self._vnc_lib.service_template_create(service_template)
scale_out = ServiceScaleOutType()
if kwargs.get('service_mode') == 'in-network':
if_list = [ServiceInstanceInterfaceType(virtual_network=vn1.get_fq_name_str()),
ServiceInstanceInterfaceType(virtual_network=vn2.get_fq_name_str())]
si_props = ServiceInstanceType(
auto_policy=auto_policy, interface_list=if_list,
scale_out=scale_out)
else:
if_list = [ServiceInstanceInterfaceType(),
ServiceInstanceInterfaceType()]
si_props = ServiceInstanceType(interface_list=if_list,
scale_out=scale_out)
service_instance = ServiceInstance(
name=si_name, service_instance_properties=si_props)
service_instance.add_service_template(service_template)
self._vnc_lib.service_instance_create(service_instance)
return service_instance.get_fq_name_str()

def create_network_policy(self, vn1, vn2, service_list=None, mirror_service=None,
service_mode=None, service_type=None, auto_policy=True):
auto_policy=False, **kwargs):
addr1 = AddressType(virtual_network=vn1.get_fq_name_str())
addr2 = AddressType(virtual_network=vn2.get_fq_name_str())
port = PortType(-1, 0)
service_name_list = []
si_list = service_list or []
if service_list:
for service in si_list:
service_name_list.append(self._create_service(vn1, vn2, service, service_mode, service_type, auto_policy))
service_name_list.append(self._create_service(vn1, vn2, service, auto_policy, **kwargs))
if mirror_service:
mirror_si = self._create_service(vn1, vn2, mirror_service, 'transparent', 'analyzer', True)
mirror_si = self._create_service(vn1, vn2, mirror_service, False, service_mode='transparent', service_type='analyzer')
action_list = ActionListType()
if mirror_service:
mirror = MirrorActionType(analyzer_name=mirror_si)
Expand All @@ -511,7 +510,7 @@ def create_network_policy(self, vn1, vn2, service_list=None, mirror_service=None
action_list=action_list)
pentry = PolicyEntriesType([prule])
np = NetworkPolicy(str(uuid.uuid4()), network_policy_entries=pentry)
if service_mode == 'in-network' and auto_policy == True:
if auto_policy:
return np
self._vnc_lib.network_policy_create(np)
return np
Expand Down
75 changes: 54 additions & 21 deletions src/config/schema-transformer/config_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,24 @@ def policy_to_acl_rule(self, prule, dynamic):
return result_acl_rule_list
# end policy_to_acl_rule

def update_pnf_presence(self):
has_pnf = False
for ri_name in self.routing_instances:
if ri_name == self._default_ri_name:
continue
ri = RoutingInstanceST.get(ri_name)
if ri is None:
continue
if ri.obj.get_routing_instance_has_pnf():
has_pnf = True
break
default_ri = RoutingInstanceST.get(self._default_ri_name)
if (default_ri and
default_ri.obj.get_routing_instance_has_pnf() != has_pnf):
default_ri.obj.set_routing_instance_has_pnf(has_pnf)
self._vnc_lib.routing_instance_update(default_ri.obj)
# end update_pnf_presence

def evaluate(self):
old_virtual_network_connections = self.expand_connections()
old_service_chains = self.service_chains
Expand Down Expand Up @@ -1122,6 +1140,7 @@ def evaluate(self):
# for remote_vn_name

self.update_route_table()
self.update_pnf_presence()
# end evaluate
# end class VirtualNetworkST

Expand Down Expand Up @@ -1586,10 +1605,11 @@ def update(self, obj=None):
pass

@classmethod
def create(cls, fq_name, vn_obj):
def create(cls, fq_name, vn_obj, has_pnf=False):
try:
name = fq_name.split(':')[-1]
ri_obj = RoutingInstance(name, parent_obj=vn_obj.obj)
ri_obj = RoutingInstance(name, parent_obj=vn_obj.obj,
routing_instance_has_pnf=has_pnf)
cls._vnc_lib.routing_instance_create(ri_obj)
return ri_obj
except RefsExistError:
Expand Down Expand Up @@ -1627,7 +1647,7 @@ def locate_route_target(self):
try:
if self.obj.parent_uuid != vn.obj.uuid:
# Stale object. Delete it.
self._vnc_lib.routing_instance_delete(id=rinst_obj.uuid)
self._vnc_lib.routing_instance_delete(id=self.obj.uuid)
self.obj = None
else:
old_rt_refs = copy.deepcopy(self.obj.get_route_target_refs())
Expand Down Expand Up @@ -1804,7 +1824,7 @@ def delete_obj(self):
# if other routing instances are referring to this target,
# it will be deleted when those instances are deleted
pass

# end delete_obj
# end class RoutingInstanceST


Expand Down Expand Up @@ -1979,7 +1999,10 @@ def check_create(self):
service_vm)
return None
vm_info_list.append(vm_info)
ret_dict[service] = {'mode': mode, 'vm_list': vm_info_list}
# end for service_vm
virtualization_type = si.get_virtualization_type()
ret_dict[service] = {'mode': mode, 'vm_list': vm_info_list,
'virtualization_type': virtualization_type}
return ret_dict
# check_create

Expand All @@ -1990,7 +2013,6 @@ def create(self):
if si_info is None:
# if previously created but no longer valid, then destroy
self.destroy()
# already created
return

if si_info is None:
Expand Down Expand Up @@ -2029,13 +2051,14 @@ def _create(self, si_info):
for service in self.service_list:
service_name1 = vn1_obj.get_service_name(self.name, service)
service_name2 = vn2_obj.get_service_name(self.name, service)
ri_obj = RoutingInstanceST.create(service_name1, vn1_obj)
has_pnf = (si_info[service]['virtualization_type'] == 'physical-device')
ri_obj = RoutingInstanceST.create(service_name1, vn1_obj, has_pnf)
service_ri1 = RoutingInstanceST.locate(service_name1, ri_obj)
if service_ri1 is None or service_ri2 is None:
self.log_error("service_ri1 or service_ri2 is None")
return
service_ri2.add_connection(service_ri1)
ri_obj = RoutingInstanceST.create(service_name2, vn2_obj)
ri_obj = RoutingInstanceST.create(service_name2, vn2_obj, has_pnf)
service_ri2 = RoutingInstanceST.locate(service_name2, ri_obj)
if service_ri2 is None:
self.log_error("service_ri2 is None")
Expand Down Expand Up @@ -2882,24 +2905,34 @@ def delete_obj(self):
self.delete_properties()
# end delete_obj

def get_service_mode(self):
if hasattr(self, 'service_mode'):
return self.service_mode
st_name = self.service_template
if st_name is None:
def _update_service_template(self):
if self.service_template is None:
self._logger.error("service template is None for service instance "
+ self.name)
return None
return
try:
st_obj = self.read_vnc_obj(fq_name=st_name,
st_obj = self.read_vnc_obj(fq_name=self.service_template,
obj_type='service_template')
except NoIdError:
self._logger.error("NoIdError while reading service template "
+ st_name)
return None
self.service_mode = st_obj.get_service_template_properties(
).get_service_mode() or 'transparent'
return self.service_mode
+ self.service_template)
return
st_props = st_obj.get_service_template_properties()
self.service_mode = st_props.get_service_mode() or 'transparent'
self.virtualization_type = st_props.get_service_virtualization_type()
# end get_service_mode
# end ServiceInstanceST

def get_service_mode(self):
if hasattr(self, 'service_mode'):
return self.service_mode
self._update_service_template()
return getattr(self, 'service_mode', None)
# end get_service_mode

def get_virtualization_type(self):
if hasattr(self, 'virtualization_type'):
return self.virtualization_type
self._update_service_template()
return getattr(self, 'virtualization_type', None)
# end get_virtualization_type
# end ServiceInstanceST
54 changes: 50 additions & 4 deletions src/config/schema-transformer/test/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ def test_multi_service_in_policy(self):
vn2_obj = self.create_virtual_network(vn2_name, '20.0.0.0/24')

service_names = [self.id() + 's1', self.id() + 's2', self.id() + 's3']
np = self.create_network_policy(vn1_obj, vn2_obj, service_names, None, "in-network", auto_policy=False)
np = self.create_network_policy(vn1_obj, vn2_obj, service_names, auto_policy=False, service_mode='in-network')
seq = SequenceType(1, 1)
vnp = VirtualNetworkPolicyType(seq)
vn1_obj.set_network_policy(np, vnp)
Expand Down Expand Up @@ -742,7 +742,7 @@ def test_add_delete_route(self):
rvn = self.create_virtual_network(rvn_name, "20.0.0.0/24")

service_name = self.id() + 's1'
np = self.create_network_policy(lvn, rvn, [service_name], None, "in-network")
np = self.create_network_policy(lvn, rvn, [service_name], auto_policy=True, service_mode="in-network")

vn_name = self.id() + 'vn100'
vn = self.create_virtual_network(vn_name, "1.0.0.0/24")
Expand Down Expand Up @@ -1150,7 +1150,7 @@ def test_analyzer(self):
vn2_obj = self.create_virtual_network(vn2_name, '20.0.0.0/24')

service_name = self.id() + 's1'
np = self.create_network_policy(vn1_obj, vn2_obj, None, service_name, 'transparent', 'analyzer')
np = self.create_network_policy(vn1_obj, vn2_obj, mirror_service=service_name, auto_policy=False, service_mode='transparent', service_type='analyzer')
seq = SequenceType(1, 1)
vnp = VirtualNetworkPolicyType(seq)
vn1_obj.set_network_policy(np, vnp)
Expand Down Expand Up @@ -1541,7 +1541,7 @@ def test_fip(self):
vn2_obj = self.create_virtual_network(vn2_name, '20.0.0.0/24')

service_name = self.id() + 's1'
np = self.create_network_policy(vn1_obj, vn2_obj, [service_name], None, 'in-network')
np = self.create_network_policy(vn1_obj, vn2_obj, [service_name], service_mode='in-network', auto_policy=True)

sc = self.wait_to_get_sc()
sc_ri_name = 'service-'+sc[0]+'-default-domain_default-project_' + service_name
Expand Down Expand Up @@ -1587,4 +1587,50 @@ def test_fip(self):
self.wait_to_remove_link(self.get_obj_imid(vmi), fip_fq_name)
self.check_vrf_assign_table(vmi.get_fq_name(), fip, False)

def _test_pnf_service(self):
# create vn1
vn1_name = self.id() + 'vn1'
vn1_obj = self.create_virtual_network(vn1_name, '10.0.0.0/24')

# create vn2
vn2_name = self.id() + 'vn2'
vn2_obj = self.create_virtual_network(vn2_name, '20.0.0.0/24')

service_name = self.id() + 's1'
np = self.create_network_policy(vn1_obj, vn2_obj, [service_name], service_virtualization_type='physical-device')
seq = SequenceType(1, 1)
vnp = VirtualNetworkPolicyType(seq)

vn1_obj.set_network_policy(np, vnp)
vn2_obj.set_network_policy(np, vnp)
self._vnc_lib.virtual_network_update(vn1_obj)
self._vnc_lib.virtual_network_update(vn2_obj)

sc = self.wait_to_get_sc()
sc_ri_name = 'service-'+sc[0]+'-default-domain_default-project_' + service_name
self.check_ri_state_vn_policy(self.get_ri_name(vn1_obj),
self.get_ri_name(vn1_obj, sc_ri_name))
self.check_ri_state_vn_policy(self.get_ri_name(vn2_obj, sc_ri_name),
self.get_ri_name(vn2_obj))

self.check_service_chain_prefix_match(fq_name=self.get_ri_name(vn2_obj, sc_ri_name),
prefix='10.0.0.0/24')
ri1 = self._vnc_lib.routing_instance_read(fq_name=self.get_ri_name(vn1_obj))
self.assertEqual(ri1.get_routing_instance_has_pnf(), True)

vn1_obj.del_network_policy(np)
vn2_obj.del_network_policy(np)
self._vnc_lib.virtual_network_update(vn1_obj)
self._vnc_lib.virtual_network_update(vn2_obj)
self.check_ri_refs_are_deleted(fq_name=self.get_ri_name(vn1_obj))
ri1 = self._vnc_lib.routing_instance_read(fq_name=self.get_ri_name(vn1_obj))
self.assertEqual(ri1.get_routing_instance_has_pnf(), False)

self.delete_network_policy(np)
self._vnc_lib.virtual_network_delete(fq_name=vn1_obj.get_fq_name())
self._vnc_lib.virtual_network_delete(fq_name=vn2_obj.get_fq_name())
self.check_vn_is_deleted(uuid=vn1_obj.uuid)
self.check_ri_is_deleted(fq_name=self.get_ri_name(vn2_obj))
# end test_pnf_service

# end class TestRouteTable

0 comments on commit 7a26ec7

Please sign in to comment.