blob: e7be0c82002114647b74100d9bce5d16b17bc290 [file] [log] [blame]
Matteo Scandolof0441032017-08-08 13:05:26 -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 Bakerb63ea792016-08-11 10:24:48 -070017import os
18import base64
19import struct
20import socket
Scott Bakerb63ea792016-08-11 10:24:48 -070021from netaddr import IPAddress, IPNetwork
Scott Baker8b75e852016-08-16 15:04:59 -070022from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
Scott Bakeraf599eb2017-03-21 12:43:26 -070023from synchronizers.new_base.syncstep import *
Scott Bakerb63ea792016-08-11 10:24:48 -070024from xos.logger import observer_logger as logger
Scott Bakeraf599eb2017-03-21 12:43:26 -070025from synchronizers.new_base.ansible_helper import *
Scott Bakeraf599eb2017-03-21 12:43:26 -070026from synchronizers.new_base.modelaccessor import *
Scott Bakerb63ea792016-08-11 10:24:48 -070027
28class SyncControllerNetworks(OpenStackSyncStep):
29 requested_interval = 0
30 provides=[Network]
31 observes=ControllerNetwork
32 playbook='sync_controller_networks.yaml'
33
34 def alloc_subnet(self, uuid):
35 # 16 bits only
36 uuid_masked = uuid & 0xffff
37 a = 10
38 b = uuid_masked >> 8
39 c = uuid_masked & 0xff
40 d = 0
41
42 cidr = '%d.%d.%d.%d/24'%(a,b,c,d)
43 return cidr
44
45 def alloc_gateway(self, subnet):
46 # given a CIDR, allocate a default gateway using the .1 address within
47 # the subnet.
48 # 10.123.0.0/24 --> 10.123.0.1
49 # 207.141.192.128/28 --> 207.141.192.129
50 (network, bits) = subnet.split("/")
51 network=network.strip()
52 bits=int(bits.strip())
53 netmask = (~(pow(2,32-bits)-1) & 0xFFFFFFFF)
54 ip = struct.unpack("!L", socket.inet_aton(network))[0]
55 ip = ip & netmask | 1
56 return socket.inet_ntoa(struct.pack("!L", ip))
57
Scott Baker11cb69f2016-08-25 16:17:52 -070058 def get_segmentation_id(self, controller_network):
Scott Baker7bd1cd42016-08-29 15:30:45 -070059 driver = self.driver.admin_driver(controller = controller_network.controller)
Scott Baker11cb69f2016-08-25 16:17:52 -070060 neutron_network = driver.shell.neutron.list_networks(controller_network.network_id)["networks"][0]
Sapan Bhatia259205e2017-01-24 19:32:59 +010061 if "provider:segmentation_id" in neutron_network:
Scott Baker11cb69f2016-08-25 16:17:52 -070062 return neutron_network["provider:segmentation_id"]
63 else:
64 return None
65
Scott Bakerb63ea792016-08-11 10:24:48 -070066 def save_controller_network(self, controller_network):
67 network_name = controller_network.network.name
68 subnet_name = '%s-%d'%(network_name,controller_network.pk)
69 if controller_network.subnet and controller_network.subnet.strip():
70 # If a subnet is already specified (pass in by the creator), then
71 # use that rather than auto-generating one.
72 cidr = controller_network.subnet.strip()
73 print "CIDR_MS", cidr
74 else:
75 cidr = self.alloc_subnet(controller_network.pk)
76 print "CIDR_AMS", cidr
77
78 if controller_network.network.start_ip and controller_network.network.start_ip.strip():
79 start_ip = controller_network.network.start_ip.strip()
80 else:
81 start_ip = None
82
83 if controller_network.network.end_ip and controller_network.network.end_ip.strip():
84 end_ip = controller_network.network.end_ip.strip()
85 else:
86 end_ip = None
87
Scott Bakerb63ea792016-08-11 10:24:48 -070088 slice = controller_network.network.owner
Scott Baker02b68672017-11-29 15:09:38 -080089 controller_network.subnet = cidr
Scott Bakerb63ea792016-08-11 10:24:48 -070090
Scott Baker11cb69f2016-08-25 16:17:52 -070091 controller_network.gateway = self.alloc_gateway(cidr)
92
Scott Bakerb63ea792016-08-11 10:24:48 -070093 network_fields = {'endpoint':controller_network.controller.auth_url,
94 'endpoint_v3': controller_network.controller.auth_url_v3,
95 'admin_user':slice.creator.email,
96 'admin_password':slice.creator.remote_password,
97 'admin_project':slice.name,
98 'domain': controller_network.controller.domain,
99 'name':network_name,
100 'subnet_name':subnet_name,
101 'ansible_tag':'%s-%s@%s'%(network_name,slice.slicename,controller_network.controller.name),
102 'cidr':cidr,
Scott Baker11cb69f2016-08-25 16:17:52 -0700103 'gateway': controller_network.gateway,
Scott Bakerb63ea792016-08-11 10:24:48 -0700104 'start_ip':start_ip,
105 'end_ip':end_ip,
Matteo Scandoloceccb1f2017-06-05 10:35:44 -0700106 'use_vtn':True,
Scott Bakerb63ea792016-08-11 10:24:48 -0700107 'delete':False
108 }
109 return network_fields
110
111 def map_sync_outputs(self, controller_network,res):
112 network_id = res[0]['network']['id']
113 subnet_id = res[1]['subnet']['id']
114 controller_network.net_id = network_id
Scott Bakerb63ea792016-08-11 10:24:48 -0700115 controller_network.subnet_id = subnet_id
Sapan Bhatia54b0ffe2017-08-29 18:39:53 -0400116 controller_network.backend_status = 'OK'
117 controller_network.backend_code = 1
Scott Baker11cb69f2016-08-25 16:17:52 -0700118 if not controller_network.segmentation_id:
Scott Baker75bae452017-03-27 20:10:58 -0700119 controller_network.segmentation_id = str(self.get_segmentation_id(controller_network))
Scott Bakerb63ea792016-08-11 10:24:48 -0700120 controller_network.save()
121
122
123 def map_sync_inputs(self, controller_network):
Scott Baker3de3d582016-09-09 15:26:43 -0700124 # make sure to not sync a shared network
Scott Bakerb63ea792016-08-11 10:24:48 -0700125 if (controller_network.network.template.shared_network_name or controller_network.network.template.shared_network_id):
126 return SyncStep.SYNC_WITHOUT_RUNNING
Scott Baker3de3d582016-09-09 15:26:43 -0700127
Scott Bakerb63ea792016-08-11 10:24:48 -0700128 if not controller_network.controller.admin_user:
129 logger.info("controller %r has no admin_user, skipping" % controller_network.controller)
130 return
131
132 if controller_network.network.owner and controller_network.network.owner.creator:
133 return self.save_controller_network(controller_network)
134 else:
135 raise Exception('Could not save network controller %s'%controller_network)
136
137 def map_delete_inputs(self, controller_network):
Scott Baker3de3d582016-09-09 15:26:43 -0700138 # make sure to not delete a shared network
139 if (controller_network.network.template.shared_network_name or controller_network.network.template.shared_network_id):
Scott Bakerb63ea792016-08-11 10:24:48 -0700140 return
Scott Baker3de3d582016-09-09 15:26:43 -0700141
Scott Bakerb63ea792016-08-11 10:24:48 -0700142 try:
143 slice = controller_network.network.owner # XXX: FIXME!!
144 except:
145 raise Exception('Could not get slice for Network %s'%controller_network.network.name)
146
147 network_name = controller_network.network.name
148 subnet_name = '%s-%d'%(network_name,controller_network.pk)
149 cidr = controller_network.subnet
150 network_fields = {'endpoint':controller_network.controller.auth_url,
151 'admin_user':slice.creator.email, # XXX: FIXME
Scott Bakerda1a2162016-12-11 23:45:04 -0800152 'admin_project':slice.name, # XXX: FIXME
Scott Bakerb63ea792016-08-11 10:24:48 -0700153 'admin_password':slice.creator.remote_password,
154 'name':network_name,
155 'subnet_name':subnet_name,
156 'ansible_tag':'%s-%s@%s'%(network_name,slice.slicename,controller_network.controller.name),
157 'cidr':cidr,
158 'delete':True
159 }
160
161 return network_fields
162