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