blob: c3f7708d6267c5a7940380c1dc0a2ed8c27e138c [file] [log] [blame]
Matteo Scandoloa86e0a12017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Scott Baker171d35e2016-06-20 17:36:29 -070017import os
18import socket
19import sys
20import base64
21import time
Scott Baker5809ed42017-03-07 10:45:00 -080022from synchronizers.new_base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
23from synchronizers.new_base.modelaccessor import *
Scott Baker171d35e2016-06-20 17:36:29 -070024from xos.logger import Logger, logging
25
26# hpclibrary will be in steps/..
27parentdir = os.path.join(os.path.dirname(__file__),"..")
28sys.path.insert(0,parentdir)
29
30logger = Logger(level=logging.INFO)
31
Scott Baker171d35e2016-06-20 17:36:29 -070032class SyncVTRTenant(SyncInstanceUsingAnsible):
33 provides=[VTRTenant]
34 observes=VTRTenant
35 requested_interval=0
36 template_name = "sync_vtrtenant.yaml"
Scott Baker171d35e2016-06-20 17:36:29 -070037
38 def __init__(self, *args, **kwargs):
39 super(SyncVTRTenant, self).__init__(*args, **kwargs)
40
Scott Baker171d35e2016-06-20 17:36:29 -070041 def get_vtr_service(self, o):
Scott Bakerc7958a92017-07-18 11:07:00 -070042 if not o.owner:
Scott Baker171d35e2016-06-20 17:36:29 -070043 return None
44
Scott Bakerc7958a92017-07-18 11:07:00 -070045 # cast from Service to VTRService
46 vtrs = VTRService.objects.filter(id=o.owner.id)
Scott Baker171d35e2016-06-20 17:36:29 -070047 if not vtrs:
48 return None
49
50 return vtrs[0]
51
Scott Baker5db44a92017-03-06 17:27:52 -080052 def get_target(self, o):
53 target = o.target
54 if target:
Scott Baker3bbf1e92017-03-07 12:06:06 -080055 model_name = getattr(target, "model_name", target.__class__.__name__)
Scott Bakerc7958a92017-07-18 11:07:00 -070056 if model_name in ["ServiceInstance", "CordSubscriberRoot"]:
57 # cast from ServiceInstance to CordSubscriberRoot
58 csrs = CordSubscriberRoot.objects.filter(id=target.id)
59 if csrs:
60 return csrs[0]
Scott Baker5db44a92017-03-06 17:27:52 -080061 return None
62
Scott Baker80cfb402017-09-25 15:21:48 -070063 def gather_information(self, service_instance):
64 """ gather_information: inspect a service chain for information that will be useful to the VTN service, and
65 try to do it in a service-agnostic way. We know what we're looking for (instances, ip addresses, etc) but
66 not necessarily where we will find it.
67 """
68
69 if not service_instance:
70 return {}
71
72 # extract useful information from the service_instance
73 info = {}
74 for link in service_instance.subscribed_links.all():
75 provider_si = link.provider_service_instance.leaf_model
76 for k in ["instance", "wan_vm_ip", "wan_container_ip", "s_tag", "c_tag", "container_name"]:
77 if hasattr(provider_si, k):
78 info[k] = getattr(provider_si, k)
79
80 # now, recurse to check the children
81 for link in service_instance.subscribed_links.all():
82 child_info = self.gather_information(link.provider_service_instance)
83
84 # prefer values we got from a parent to values we got from a child
85 for (k,v) in child_info.items():
86 if not k in info:
87 info[k] = v
88
89 return info
Scott Baker171d35e2016-06-20 17:36:29 -070090
91 def get_instance(self, o):
Scott Baker80cfb402017-09-25 15:21:48 -070092 """ get_instance: Called by the SyncInstanceUsingAnslbe sync step. """
93 return self.gather_information(self.get_target(o)).get("instance")
Scott Baker171d35e2016-06-20 17:36:29 -070094
95 def get_key_name(self, instance):
Scott Baker5809ed42017-03-07 10:45:00 -080096 if instance.slice and instance.slice.service and instance.slice.service.private_key_fn:
97 # Assume the service has shared its key with VTR.
98 # Look for the instance's service key name in VTR's key directory.
99 service_keyfn = instance.slice.service.private_key_fn
100 return os.path.join("/opt/xos/services/vtr/keys", os.path.basename(service_keyfn))
Scott Baker171d35e2016-06-20 17:36:29 -0700101 else:
102 raise Exception("VTR doesn't know how to get the private key for this instance")
103
104 def get_extra_attributes(self, o):
Scott Baker80cfb402017-09-25 15:21:48 -0700105 target = self.get_target(o)
106 target_info = self.gather_information(target)
Scott Baker171d35e2016-06-20 17:36:29 -0700107
Scott Baker80cfb402017-09-25 15:21:48 -0700108 instance = target_info.get("instance")
Scott Baker171d35e2016-06-20 17:36:29 -0700109 if not instance:
110 raise Exception("No instance")
111
Scott Baker80cfb402017-09-25 15:21:48 -0700112 # For container scope, we need to figure out the container name. There are three ways we can do this:
113 # 1) The service_instance can provide a `container_name` attribute
114 # 2) The service_instance can provide `container_prefix`, `s_tag`, and `c_tag` attributes.
115 # 3) The service_instance can provide `s_tag` and `c_tag` and we'll assume a default prefix of `vsg`
116 container_name = target_info.get("container_name")
117 if not container_name:
118 if (not target_info.get("s_tag")) or (not target_info.get("c_tag")):
119 raise Exception("No s_tag or no c_tag")
Scott Baker5db44a92017-03-06 17:27:52 -0800120
Scott Baker80cfb402017-09-25 15:21:48 -0700121 container_name = "%s-%s-%s" % (target_info.get("container_prefix", "vsg"), target_info["s_tag"], target_info["c_tag"])
Scott Baker171d35e2016-06-20 17:36:29 -0700122
Scott Baker80cfb402017-09-25 15:21:48 -0700123 fields = {"isolation": instance.isolation,
124 "container_name": container_name,
125 "result_fn": "%s-vtrserviceinstance-%s" % (o.test, str(o.id)),
126 "resultcode_fn": "code-%s-vtrserviceinstance-%s" % (o.test, str(o.id)) }
Scott Baker171d35e2016-06-20 17:36:29 -0700127
Scott Baker80cfb402017-09-25 15:21:48 -0700128 # copy in values that we learned from inspecting the service chain
129 for k in ["s_tag", "c_tag", "wan_vm_ip", "wan_container_ip"]:
130 if target_info.get(k):
131 fields[k] = target_info[k]
Scott Baker171d35e2016-06-20 17:36:29 -0700132
Scott Baker80cfb402017-09-25 15:21:48 -0700133 for attribute_name in ["scope", "test", "argument"]:
134 fields[attribute_name] = getattr(o, attribute_name)
Scott Baker171d35e2016-06-20 17:36:29 -0700135
136 return fields
137
138 def sync_fields(self, o, fields):
139 # the super causes the playbook to be run
140
141 super(SyncVTRTenant, self).sync_fields(o, fields)
142
143 def run_playbook(self, o, fields):
144 o.result = ""
145
146 result_fn = os.path.join("/opt/xos/synchronizers/vtr/result", fields["result_fn"])
147 if os.path.exists(result_fn):
148 os.remove(result_fn)
149
150 resultcode_fn = os.path.join("/opt/xos/synchronizers/vtr/result", fields["resultcode_fn"])
151 if os.path.exists(resultcode_fn):
152 os.remove(resultcode_fn)
153
154 super(SyncVTRTenant, self).run_playbook(o, fields)
155
156 if os.path.exists(result_fn):
157 o.result = open(result_fn).read()
158
159 if os.path.exists(resultcode_fn):
160 o.result_code = open(resultcode_fn).read()
161
162
163 def delete_record(self, m):
164 pass