CORD-1923: Eliminate hardcoded dependencies between VTR and VSG
Change-Id: I25017fa8f03e3ca9a160b6ff7d5074ce9320ac8a
diff --git a/xos/synchronizer/steps/sync_vtrtenant.py b/xos/synchronizer/steps/sync_vtrtenant.py
index e3ff7af..c3f7708 100644
--- a/xos/synchronizer/steps/sync_vtrtenant.py
+++ b/xos/synchronizer/steps/sync_vtrtenant.py
@@ -60,26 +60,39 @@
return csrs[0]
return None
- def get_vcpe_service(self, o):
- target = self.get_target(o)
- if target and target.volt and target.volt.vcpe:
- return target.volt.vcpe
- return None
+ def gather_information(self, service_instance):
+ """ gather_information: inspect a service chain for information that will be useful to the VTN service, and
+ try to do it in a service-agnostic way. We know what we're looking for (instances, ip addresses, etc) but
+ not necessarily where we will find it.
+ """
+
+ if not service_instance:
+ return {}
+
+ # extract useful information from the service_instance
+ info = {}
+ for link in service_instance.subscribed_links.all():
+ provider_si = link.provider_service_instance.leaf_model
+ for k in ["instance", "wan_vm_ip", "wan_container_ip", "s_tag", "c_tag", "container_name"]:
+ if hasattr(provider_si, k):
+ info[k] = getattr(provider_si, k)
+
+ # now, recurse to check the children
+ for link in service_instance.subscribed_links.all():
+ child_info = self.gather_information(link.provider_service_instance)
+
+ # prefer values we got from a parent to values we got from a child
+ for (k,v) in child_info.items():
+ if not k in info:
+ info[k] = v
+
+ return info
def get_instance(self, o):
- target = self.get_target(o)
- if target and target.volt and target.volt.vcpe:
- return target.volt.vcpe.instance
- else:
- return None
+ """ get_instance: Called by the SyncInstanceUsingAnslbe sync step. """
+ return self.gather_information(self.get_target(o)).get("instance")
def get_key_name(self, instance):
-# if instance.slice.service and (instance.slice.service.kind==VCPE_KIND):
-# # We need to use the vsg service's private key. Onboarding won't
-# # by default give us another service's private key, so let's assume
-# # onboarding has been configured to add vsg_rsa to the vtr service.
-# return "/opt/xos/services/vtr/keys/vsg_rsa"
-
if instance.slice and instance.slice.service and instance.slice.service.private_key_fn:
# Assume the service has shared its key with VTR.
# Look for the instance's service key name in VTR's key directory.
@@ -89,47 +102,36 @@
raise Exception("VTR doesn't know how to get the private key for this instance")
def get_extra_attributes(self, o):
- vtr_service = self.get_vtr_service(o)
- vcpe_service = self.get_vcpe_service(o)
+ target = self.get_target(o)
+ target_info = self.gather_information(target)
- if not vcpe_service:
- raise Exception("No vcpeservice")
-
- instance = self.get_instance(o)
-
+ instance = target_info.get("instance")
if not instance:
raise Exception("No instance")
- target = self.get_target(o)
+ # For container scope, we need to figure out the container name. There are three ways we can do this:
+ # 1) The service_instance can provide a `container_name` attribute
+ # 2) The service_instance can provide `container_prefix`, `s_tag`, and `c_tag` attributes.
+ # 3) The service_instance can provide `s_tag` and `c_tag` and we'll assume a default prefix of `vsg`
+ container_name = target_info.get("container_name")
+ if not container_name:
+ if (not target_info.get("s_tag")) or (not target_info.get("c_tag")):
+ raise Exception("No s_tag or no c_tag")
- s_tags = []
- c_tags = []
- if target and target.volt:
- s_tags.append(target.volt.s_tag)
- c_tags.append(target.volt.c_tag)
+ container_name = "%s-%s-%s" % (target_info.get("container_prefix", "vsg"), target_info["s_tag"], target_info["c_tag"])
- fields = {"s_tags": s_tags,
- "c_tags": c_tags,
- "isolation": instance.isolation,
- "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]),
-# "dns_servers": [x.strip() for x in vcpe_service.dns_servers.split(",")],
- "result_fn": "%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]),
- "resultcode_fn": "code-%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]) }
+ fields = {"isolation": instance.isolation,
+ "container_name": container_name,
+ "result_fn": "%s-vtrserviceinstance-%s" % (o.test, str(o.id)),
+ "resultcode_fn": "code-%s-vtrserviceinstance-%s" % (o.test, str(o.id)) }
- # add in the sync_attributes that come from the vSG object
- # this will be wan_ip, wan_mac, wan_container_ip, wan_container_mac, ...
- if target and target.volt and target.volt.vcpe:
- for attribute_name in ["wan_vm_ip", "wan_container_ip"]:
- if hasattr(target.volt.vcpe, attribute_name):
- fields[attribute_name] = getattr(target.volt.vcpe, attribute_name)
+ # copy in values that we learned from inspecting the service chain
+ for k in ["s_tag", "c_tag", "wan_vm_ip", "wan_container_ip"]:
+ if target_info.get(k):
+ fields[k] = target_info[k]
- # add in the sync_attributes that come from the SubscriberRoot object
-# if target and hasattr(target, "sync_attributes"):
-# for attribute_name in target.sync_attributes:
-# fields[attribute_name] = getattr(target, attribute_name)
-
- for attribute_name in ["scope", "test", "argument"]: # o.sync_attributes:
- fields[attribute_name] = getattr(o,attribute_name)
+ for attribute_name in ["scope", "test", "argument"]:
+ fields[attribute_name] = getattr(o, attribute_name)
return fields