blob: b6f427d14b0eb0d20f37c9913d105a3d9d3254a0 [file] [log] [blame]
Andy Bavierdd9b4d92016-09-13 14:51:18 -04001import os
2import requests
3import socket
4import sys
5import base64
6import json
Scott Baker61b41a92017-03-14 13:04:57 -07007from synchronizers.new_base.syncstep import SyncStep
8from synchronizers.new_base.modelaccessor import *
Andy Bavierdd9b4d92016-09-13 14:51:18 -04009from xos.logger import Logger, logging
10
11logger = Logger(level=logging.INFO)
12
13class SyncONOSNetcfg(SyncStep):
Andy Bavier51d7ebb2016-12-06 16:20:34 -050014 provides=[VTNService]
15 observes=VTNService
16 watches=[ModelLink(Node,via='node'), ModelLink(AddressPool,via='addresspool')]
Andy Bavierdd9b4d92016-09-13 14:51:18 -040017 requested_interval=0
18
19 def __init__(self, **args):
20 SyncStep.__init__(self, **args)
21
Andy Bavier51d7ebb2016-12-06 16:20:34 -050022 def handle_watched_object(self, o):
23 logger.info("handle_watched_object is invoked for object %s" % (str(o)),extra=o.tologdict())
24 if (type(o) is Node): # For Node add/delete/modify
25 self.call()
26 if (type(o) is AddressPool): # For public gateways
27 self.call()
28
Andy Baviere45ce912016-09-13 17:25:43 -040029 def get_node_tag(self, node, tagname):
Andy Bavierdd9b4d92016-09-13 14:51:18 -040030 tags = Tag.select_by_content_object(node).filter(name=tagname)
31 return tags[0].value
32
33 def get_tenants_who_want_config(self):
34 tenants = []
35 # attribute is comma-separated list
36 for ta in TenantAttribute.objects.filter(name="autogenerate"):
37 if ta.value:
38 for config in ta.value.split(','):
39 if config == "vtn-network-cfg":
40 tenants.append(ta.tenant)
41 return tenants
42
43 def save_tenant_attribute(self, tenant, name, value):
44 tas = TenantAttribute.objects.filter(tenant=tenant, name=name)
45 if tas:
46 ta = tas[0]
47 if ta.value != value:
48 logger.info("updating %s with attribute" % name)
49 ta.value = value
50 ta.save()
51 else:
52 logger.info("saving autogenerated config %s" % name)
53 ta = TenantAttribute(tenant=tenant, name=name, value=value)
54 ta.save()
55
56 # This function currently assumes a single Deployment and Site
57 def get_onos_netcfg(self, vtn):
58 privateGatewayMac = vtn.privateGatewayMac
59 localManagementIp = vtn.localManagementIp
60 ovsdbPort = vtn.ovsdbPort
61 sshPort = vtn.sshPort
62 sshUser = vtn.sshUser
63 sshKeyFile = vtn.sshKeyFile
64 mgmtSubnetBits = vtn.mgmtSubnetBits
65 xosEndpoint = vtn.xosEndpoint
66 xosUser = vtn.xosUser
67 xosPassword = vtn.xosPassword
68
Scott Bakerff016682016-11-28 09:53:13 -080069 controllerPort = vtn.controllerPort
70 if ":" in controllerPort:
71 (c_hostname, c_port) = controllerPort.split(":",1)
72 controllerPort = socket.gethostbyname(c_hostname) + ":" + c_port
73 else:
74 controllerPort = ":" + controllerPort
75
Andy Bavierdd9b4d92016-09-13 14:51:18 -040076 data = {
77 "apps" : {
78 "org.opencord.vtn" : {
79 "cordvtn" : {
80 "privateGatewayMac" : privateGatewayMac,
81 "localManagementIp": localManagementIp,
82 "ovsdbPort": ovsdbPort,
83 "ssh": {
84 "sshPort": sshPort,
85 "sshUser": sshUser,
86 "sshKeyFile": sshKeyFile
87 },
88 "xos": {
89 "endpoint": xosEndpoint,
90 "user": xosUser,
91 "password": xosPassword
92 },
93 "publicGateways": [],
Scott Bakerff016682016-11-28 09:53:13 -080094 "nodes" : [],
95 "controllers": [controllerPort]
Andy Bavierdd9b4d92016-09-13 14:51:18 -040096 }
97 }
98 }
99 }
100
101 # Generate apps->org.opencord.vtn->cordvtn->openstack
102 controllers = Controller.objects.all()
103 if controllers:
104 controller = controllers[0]
105 keystone_server = controller.auth_url
106 user_name = controller.admin_user
107 tenant_name = controller.admin_tenant
108 password = controller.admin_password
109 openstack = {
110 "endpoint": keystone_server,
111 "tenant": tenant_name,
112 "user": user_name,
113 "password": password
114 }
115 data["apps"]["org.opencord.vtn"]["cordvtn"]["openstack"] = openstack
116
117 # Generate apps->org.opencord.vtn->cordvtn->nodes
118 nodes = Node.objects.all()
119 for node in nodes:
120 nodeip = socket.gethostbyname(node.name)
121
122 try:
Andy Baviere45ce912016-09-13 17:25:43 -0400123 bridgeId = self.get_node_tag(node, "bridgeId")
124 dataPlaneIntf = self.get_node_tag(node, "dataPlaneIntf")
125 dataPlaneIp = self.get_node_tag(node, "dataPlaneIp")
Andy Bavierdd9b4d92016-09-13 14:51:18 -0400126 except:
127 logger.error("not adding node %s to the VTN configuration" % node.name)
128 continue
129
130 node_dict = {
131 "hostname": node.name,
132 "hostManagementIp": "%s/%s" % (nodeip, mgmtSubnetBits),
133 "bridgeId": bridgeId,
134 "dataPlaneIntf": dataPlaneIntf,
135 "dataPlaneIp": dataPlaneIp
136 }
Scott Bakerdcbc52b2016-10-12 17:30:34 -0700137
138 # this one is optional
139 try:
140 node_dict["hostManagementIface"] = self.get_node_tag(node, "hostManagementIface")
141 except IndexError:
142 pass
143
Andy Bavierdd9b4d92016-09-13 14:51:18 -0400144 data["apps"]["org.opencord.vtn"]["cordvtn"]["nodes"].append(node_dict)
145
146 # Generate apps->org.onosproject.cordvtn->cordvtn->publicGateways
147 # Pull the gateway information from vRouter
Andy Bavier59012632016-09-14 08:41:56 -0400148 try:
149 from services.vrouter.models import VRouterService
150
151 vrouters = VRouterService.get_service_objects().all()
152 if vrouters:
153 for gateway in vrouters[0].get_gateways():
154 gatewayIp = gateway['gateway_ip'].split('/',1)[0]
155 gatewayMac = gateway['gateway_mac']
156 gateway_dict = {
157 "gatewayIp": gatewayIp,
158 "gatewayMac": gatewayMac
159 }
160 data["apps"]["org.opencord.vtn"]["cordvtn"]["publicGateways"].append(gateway_dict)
161 except:
162 logger.info("No VRouter service present, not adding publicGateways to config")
Andy Bavierdd9b4d92016-09-13 14:51:18 -0400163
164 return json.dumps(data, indent=4, sort_keys=True)
165
166 def call(self, **args):
167 vtn_service = VTNService.get_service_objects().all()
168 if not vtn_service:
169 raise Exception("No VTN Service")
170
171 vtn_service = vtn_service[0]
172
173 # Check for autogenerate attribute
174 netcfg = self.get_onos_netcfg(vtn_service)
175
176 tenants = self.get_tenants_who_want_config()
177 for tenant in tenants:
178 self.save_tenant_attribute(tenant, "rest_onos/v1/network/configuration/", netcfg)