blob: 8374dd338c81145dbe9ce11bb81662232559968d [file] [log] [blame]
Ales Komarekad46d2e2017-03-09 17:16:38 +01001#!/usr/bin/python
2# Copyright 2017 Mirantis, Inc.
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
Sergey Matov16896ac2018-02-15 15:46:31 +040016from vnc_api.vnc_api import *
17from vnc_api.gen.resource_xsd import *
18from cfgm_common.exceptions import *
19from cfgm_common.rbaclib import *
20import cfgm_common
21
Ales Komarekad46d2e2017-03-09 17:16:38 +010022from netaddr import IPNetwork
Pavel Svimbersky483a19e2017-08-22 09:50:29 +020023from vnc_api.vnc_api import PhysicalRouter, PhysicalInterface, LogicalInterface
24from vnc_api.vnc_api import EncapsulationPrioritiesType
Vasyl Saienkob10b7202017-09-05 14:19:03 +030025from vnc_api.vnc_api import VirtualMachineInterface, MacAddressesType
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +020026from vnc_api.vnc_api import ServiceApplianceSet, KeyValuePairs, KeyValuePair
Ales Komarekad46d2e2017-03-09 17:16:38 +010027
28try:
29 from vnc_api import vnc_api
Petr Jediný5f3efe32017-05-26 17:55:09 +020030 from vnc_api.vnc_api import LinklocalServiceEntryType, \
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +010031 LinklocalServicesTypes, GlobalVrouterConfig, GlobalSystemConfig
Ales Komarekad46d2e2017-03-09 17:16:38 +010032 from vnc_api.gen.resource_client import VirtualRouter, AnalyticsNode, \
Jan Cachb3092722018-01-31 12:46:16 +010033 ConfigNode, DatabaseNode, BgpRouter, VirtualNetwork, FloatingIpPool
Ales Komarekad46d2e2017-03-09 17:16:38 +010034 from vnc_api.gen.resource_xsd import AddressFamilies, BgpSessionAttributes, \
Marek Celoud3097e5b2018-01-09 13:52:14 +010035 BgpSession, BgpPeeringAttributes, BgpRouterParams, AuthenticationData, \
Jan Cacha859e6b2018-01-09 17:34:18 +010036 AuthenticationKeyItem, VirtualNetworkType, IpamSubnetType, SubnetType, \
Jan Cachb3092722018-01-31 12:46:16 +010037 VnSubnetsType, RouteTargetList, ShareType
Pavel Svimbersky483a19e2017-08-22 09:50:29 +020038
Ales Komarekad46d2e2017-03-09 17:16:38 +010039 HAS_CONTRAIL = True
40except ImportError:
41 HAS_CONTRAIL = False
42
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +010043
44try:
45 from vnc_api.gen.resource_xsd import GracefulRestartParametersType
46 HAS_OLD = False
47except ImportError:
48 HAS_OLD = True
49
Ales Komarekad46d2e2017-03-09 17:16:38 +010050__opts__ = {}
51
52
53def __virtual__():
54 '''
55 Only load this module if vnc_api library is installed.
56 '''
57 if HAS_CONTRAIL:
58 return 'contrail'
59
60 return False
61
62
63def _auth(**kwargs):
64 '''
65 Set up Contrail API credentials.
66 '''
67 user = kwargs.get('user')
68 password = kwargs.get('password')
69 tenant_name = kwargs.get('project')
70 api_host = kwargs.get('api_server_ip')
71 api_port = kwargs.get('api_server_port')
72 api_base_url = kwargs.get('api_base_url')
73 use_ssl = False
74 auth_host = kwargs.get('auth_host_ip')
75 vnc_lib = vnc_api.VncApi(user, password, tenant_name,
Anton Samoylov7476f132019-03-11 20:03:02 +040076 api_host, api_port, api_base_url, wait_for_connect=False,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +020077 api_server_use_ssl=use_ssl, auth_host=auth_host)
Ales Komarekad46d2e2017-03-09 17:16:38 +010078
79 return vnc_lib
80
81
Pavel Svimbersky483a19e2017-08-22 09:50:29 +020082def _get_config(vnc_client, global_system_config='default-global-system-config'):
Ales Komarekad46d2e2017-03-09 17:16:38 +010083 try:
84 gsc_obj = vnc_client.global_system_config_read(id=global_system_config)
85 except vnc_api.NoIdError:
86 gsc_obj = vnc_client.global_system_config_read(fq_name_str=global_system_config)
87 except:
88 gsc_obj = None
89
90 return gsc_obj
91
92
93def _get_rt_inst_obj(vnc_client):
Ales Komarekad46d2e2017-03-09 17:16:38 +010094 # TODO pick fqname hardcode from common
95 rt_inst_obj = vnc_client.routing_instance_read(
96 fq_name=['default-domain', 'default-project',
97 'ip-fabric', '__default__'])
98
99 return rt_inst_obj
100
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +0200101
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300102def _get_fq_name(vnc_client, resource_name, project_name, domain='default-domain'):
103 res = [domain]
104 if project_name:
105 res.append(project_name)
106 if resource_name:
107 res.append(resource_name)
108 return res
109
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +0200110
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300111def _get_project_obj(vnc_client, name, domain='default-domain'):
112 return vnc_client.project_read(fq_name=[domain, name])
113
Ales Komarekad46d2e2017-03-09 17:16:38 +0100114
115def _get_ip(ip_w_pfx):
116 return str(IPNetwork(ip_w_pfx).ip)
117
118
Jan Cachb3092722018-01-31 12:46:16 +0100119def _create_floating_ip_pool(name, vn_obj, **kwargs):
120 vnc_client = _auth(**kwargs)
121 # create floating ip pool
122 fip_obj = FloatingIpPool(name=name, parent_obj=vn_obj)
123 vnc_client.floating_ip_pool_create(fip_obj)
124
125
Ales Komarekad46d2e2017-03-09 17:16:38 +0100126def virtual_router_list(**kwargs):
127 '''
128 Return a list of all Contrail virtual routers
129
130 CLI Example:
131
132 .. code-block:: bash
133
134 salt '*' contrail.virtual_router_list
135 '''
136 ret = {}
137 vnc_client = _auth(**kwargs)
138 vrouter_objs = vnc_client._objects_list('virtual-router', detail=True)
139 for vrouter_obj in vrouter_objs:
140 ret[vrouter_obj.name] = {
141 'ip_address': vrouter_obj.virtual_router_ip_address,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200142 'dpdk_enabled': vrouter_obj.virtual_router_dpdk_enabled,
143 'uuid': vrouter_obj.uuid
144
Ales Komarekad46d2e2017-03-09 17:16:38 +0100145 }
146 return ret
147
148
149def virtual_router_get(name, **kwargs):
150 '''
151 Return a specific Contrail virtual router
152
153 CLI Example:
154
155 .. code-block:: bash
156
157 salt '*' contrail.virtual_router_get cmp01
158 '''
159 ret = {}
160 vrouter_objs = virtual_router_list(**kwargs)
161 if name in vrouter_objs:
162 ret[name] = vrouter_objs.get(name)
163 if len(ret) == 0:
164 return {'Error': 'Error in retrieving virtual router.'}
165 return ret
166
167
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200168def virtual_router_create(name, ip_address, router_type=None, dpdk_enabled=False, **kwargs):
Ales Komarekad46d2e2017-03-09 17:16:38 +0100169 '''
170 Create specific Contrail virtual router
171
172 CLI Example:
173
174 .. code-block:: bash
175
176 salt '*' contrail.virtual_router_create cmp02 10.10.10.102
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200177 router_types:
178 - tor-agent
179 - tor-service-node
180 - embedded
Ales Komarekad46d2e2017-03-09 17:16:38 +0100181 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200182 ret = {'name': name,
183 'changes': {},
184 'result': True,
185 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100186 vnc_client = _auth(**kwargs)
187 gsc_obj = _get_config(vnc_client)
188 vrouter_objs = virtual_router_list(**kwargs)
Pavel Svimberskya3140552017-08-28 16:55:44 +0200189 router_types = ['tor-agent', 'tor-service-node', 'embedded']
190 if router_type not in router_types:
191 router_type = None
Ales Komarekad46d2e2017-03-09 17:16:38 +0100192 if name in vrouter_objs:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200193 vrouter = virtual_router_get(name)
194 vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[name]['uuid'])
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200195 changes = {}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200196 if vrouter_obj.get_virtual_router_ip_address() != ip_address:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200197 changes['ip_address'] = {'from': vrouter_obj.get_virtual_router_ip_address(), "to": ip_address}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200198 vrouter_obj.set_virtual_router_ip_address(ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200199 if vrouter_obj.get_virtual_router_type() != router_type:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200200 changes['router_type'] = {"from": vrouter_obj.get_virtual_router_type(), "to": router_type}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200201 vrouter_obj.set_virtual_router_type(router_type)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200202 if vrouter_obj.get_virtual_router_dpdk_enabled() != dpdk_enabled:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200203 changes['dpdk_enabled'] = {"from": vrouter_obj.get_virtual_router_dpdk_enabled(), "to": dpdk_enabled}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200204 vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200205 if len(changes) != 0:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200206 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200207 ret['result'] = None
208 ret['comment'] = "Virtual router " + name + " will be updated"
209 else:
210 ret['comment'] = "VirtualRouter " + name + " has been updated"
211 ret['changes'] = changes
212 vnc_client.virtual_router_update(vrouter_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200213 return ret
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200214 ret['comment'] = 'Virtual router ' + name + ' already exists and is updated'
215 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100216 else:
217 vrouter_obj = VirtualRouter(
218 name, gsc_obj,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200219 virtual_router_ip_address=ip_address,
220 virtual_router_type=router_type)
Ales Komarekad46d2e2017-03-09 17:16:38 +0100221 vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200222 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200223 ret['result'] = None
224 ret['comment'] = "VirtualRouter " + name + " will be created"
225 else:
226 vnc_client.virtual_router_create(vrouter_obj)
227 ret['comment'] = "VirtualRouter " + name + " has been created"
228 ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}}
229 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100230
231
232def virtual_router_delete(name, **kwargs):
233 '''
234 Delete specific Contrail virtual router
235
236 CLI Example:
237
238 .. code-block:: bash
239
240 salt '*' contrail.virtual_router_delete cmp01
241 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200242 ret = {'name': name,
243 'changes': {},
244 'result': True,
245 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100246 vnc_client = _auth(**kwargs)
247 gsc_obj = _get_config(vnc_client)
248 vrouter_obj = VirtualRouter(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200249 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200250 ret['result'] = None
251 ret['comment'] = "VirtualRouter " + name + " will be deleted"
252 else:
253 vnc_client.virtual_router_delete(fq_name=vrouter_obj.get_fq_name())
254 ret['comment'] = "VirtualRouter " + name + " has been deleted"
255 ret['changes'] = {'VirtualRouter': {'old': name, 'new': ''}}
256 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200257
258
259def physical_router_list(**kwargs):
260 '''
261 Return a list of all Contrail physical routers
262
263 CLI Example:
264
265 .. code-block:: bash
266
267 salt '*' contrail.physical_router_list
268 '''
269 ret = {}
270 vnc_client = _auth(**kwargs)
271 prouter_objs = vnc_client._objects_list('physical-router', detail=True)
272 for prouter_obj in prouter_objs:
273 ret[prouter_obj.name] = {
274 'uuid': prouter_obj._uuid,
275 'management_ip': prouter_obj._physical_router_management_ip,
276 'product_name': prouter_obj._physical_router_product_name,
277 }
278
279 return ret
280
281
282def physical_router_get(name, **kwargs):
283 '''
284 Return a specific Contrail physical router
285
286 CLI Example:
287
288 .. code-block:: bash
289
290 salt '*' contrail.physical_router_get router_name
291 '''
292 ret = {}
293 vnc_client = _auth(**kwargs)
294 prouter_objs = vnc_client._objects_list('physical-router', detail=True)
295 for prouter_obj in prouter_objs:
296 if name == prouter_obj.name:
297 ret[name] = prouter_obj.__dict__
298 if len(ret) == 0:
299 return {'Error': 'Error in retrieving physical router.'}
300 return ret
301
302
303def physical_router_create(name, parent_type=None,
304 management_ip=None,
305 dataplane_ip=None, # VTEP address in web GUI
306 vendor_name=None,
307 product_name=None,
308 vnc_managed=None,
309 junos_service_ports=None,
310 agents=None, **kwargs):
311 '''
312 Create specific Contrail physical router
313
314 CLI Example:
315
316 .. code-block:: bash
317
318 salt '*' contrail.physical_router_create OVSDB_router management_ip=10.167.4.202 dataplane_ip=172.16.20.15 vendor_name=MyVendor product_name=MyProduct agents="['tor01','tns01']"
319 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200320 ret = {'name': name,
321 'changes': {},
322 'result': True,
323 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200324 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200325 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200326 prouter_objs = physical_router_list(**kwargs)
327 if name in prouter_objs:
328 prouter = physical_router_get(name)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200329 changes = {}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200330 prouter_obj = vnc_client._object_read('physical-router', id=prouter[name]['_uuid'])
331 if prouter_obj.physical_router_management_ip != management_ip:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200332 changes['management_ip'] = {'from': prouter_obj.physical_router_management_ip, "to": management_ip}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200333 prouter_obj.set_physical_router_management_ip(management_ip)
334 if prouter_obj.physical_router_dataplane_ip != dataplane_ip:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200335 changes['dataplane_ip'] = {'from': prouter_obj.physical_router_dataplane_ip, "to": dataplane_ip}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200336 prouter_obj.set_physical_router_dataplane_ip(dataplane_ip)
337 if prouter_obj.get_physical_router_vendor_name() != vendor_name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200338 changes['vendor_name'] = {'from': prouter_obj.get_physical_router_vendor_name(), "to": vendor_name}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200339 prouter_obj.set_physical_router_vendor_name(vendor_name)
340 if prouter_obj.get_physical_router_product_name() != product_name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200341 changes['product_name'] = {'from': prouter_obj.get_physical_router_product_name(), "to": product_name}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200342 prouter_obj.set_physical_router_product_name(product_name)
343 if prouter_obj.get_physical_router_vnc_managed() != vnc_managed:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200344 changes['vnc_managed'] = {'from': prouter_obj.get_physical_router_vnc_managed(), "to": vnc_managed}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200345 prouter_obj.set_physical_router_vnc_managed(vnc_managed)
346 if prouter_obj.get_physical_router_junos_service_ports() != junos_service_ports:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200347 changes['junos_service_ports'] = {'from': prouter_obj.get_physical_router_junos_service_ports(),
348 'to': junos_service_ports}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200349 prouter_obj.set_physical_router_junos_service_ports(junos_service_ports)
350
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200351 if len(changes) != 0:
352 if __opts__['test']:
353 ret['result'] = None
354 ret['comment'] = "Physical router " + name + " will be updated"
355 else:
356 ret['comment'] = 'Physical router ' + name + ' already exists and is updated'
357 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200358
359 vrouter_objs = vnc_client._objects_list('virtual-router', detail=True) # all vrouter objects
360 c_agents = [] # referenced vrouters
361 for c_agent in prouter_obj.get_virtual_router_refs():
362 c_agents.append(c_agent['uuid'])
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200363 # agent_objs = [] # required state of references
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200364 for vrouter_obj in vrouter_objs:
365 if vrouter_obj._display_name in agents and vrouter_obj._uuid not in c_agents:
366 prouter_obj.add_virtual_router(vrouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200367 changes['vrouter ' + vrouter_obj._display_name] = "Reference added"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200368 if vrouter_obj._display_name not in agents and vrouter_obj._uuid in c_agents:
369 prouter_obj.del_virtual_router(vrouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200370 changes['vrouter ' + vrouter_obj._display_name] = "Reference removed"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200371 vnc_client.physical_router_update(prouter_obj)
372
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200373 if __opts__['test']:
374 ret['result'] = None
375 ret['comment'] = "VirtualRouter " + name + " will be created"
376 else:
377 vnc_client.virtual_router_create(vrouter_obj)
378 ret['comment'] = "VirtualRouter " + name + " has been created"
379 ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}}
380
381 if len(changes) == 0:
382 ret['comment'] = "Physical router exists and is updated"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200383 return ret
384 else:
385 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200386 ret['result'] = None
387 ret['comment'] = "Physical router " + name + " will be created"
388 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200389 prouter_obj = PhysicalRouter(
390 name=name,
391 parent_obj=None,
392 physical_router_management_ip=management_ip,
393 physical_router_dataplane_ip=dataplane_ip,
394 physical_router_vendor_name=vendor_name,
395 physical_router_product_name=product_name,
396 physical_router_vnc_managed=vnc_managed,
397 physical_router_junos_service_ports=junos_service_ports,
398 )
399 for agent in agents:
400 vrouter = virtual_router_get(agent)
401 vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[agent]['uuid'])
402 prouter_obj.add_virtual_router(vrouter_obj)
403 vnc_client.physical_router_create(prouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200404 ret['comment'] = "Physical router " + name + " has been created"
405 ret['changes'] = {'PhysicalRouter': {'old': '', 'new': name}}
406 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200407
408
409def physical_router_delete(name, **kwargs):
410 '''
411 Delete specific Contrail physical router
412
413 CLI Example:
414
415 .. code-block:: bash
416
417 salt '*' contrail.physical_router_delete router_name
418 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200419 ret = {'name': name,
420 'changes': {},
421 'result': True,
422 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200423 vnc_client = _auth(**kwargs)
424 gsc_obj = _get_config(vnc_client)
425 prouter_obj = PhysicalRouter(name, gsc_obj)
426 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200427 ret['result'] = None
428 ret['comment'] = "Physical router " + name + " will be deleted"
429 else:
430 vnc_client.physical_router_delete(fq_name=prouter_obj.get_fq_name())
431 ret['comment'] = "Physical router " + name + " has been deleted"
432 ret['changes'] = {'Physical router': {'old': name, 'new': ''}}
433 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200434
435
436def physical_interface_list(**kwargs):
437 '''
438 Return a list of all Contrail physical interface
439
440 CLI Example:
441
442 .. code-block:: bash
443
444 salt '*' contrail.physical_interface_list
445 '''
446 ret = {}
447 vnc_client = _auth(**kwargs)
448 pinterface_objs = vnc_client._objects_list('physical-interface', detail=True)
449 for pinterface_obj in pinterface_objs:
450 ret[pinterface_obj.name] = {
451 'uuid': pinterface_obj._uuid,
452 'fq_name': pinterface_obj.fq_name,
453 'parent_type': pinterface_obj.parent_type,
454 }
455
456 return ret
457
458
459def physical_interface_get(name, physical_router, **kwargs):
460 '''
461 Return a specific Contrail physical interface
462
463 CLI Example:
464
465 .. code-block:: bash
466
467 salt '*' contrail.physical_interface_get interface_name physical_router_name
468 '''
469 ret = {}
470 vnc_client = _auth(**kwargs)
471 pinterf_objs = vnc_client._objects_list('physical-interface', detail=True)
472 for pinterf_obj in pinterf_objs:
473 if name == pinterf_obj.name and physical_router in pinterf_obj.fq_name:
474 ret[name] = pinterf_obj.__dict__
475 if len(ret) == 0:
476 return {'Error': 'Error in retrieving physical interface.'}
477 return ret
478
479
480def physical_interface_create(name, physical_router, **kwargs):
481 '''
482 Create specific Contrail physical interface
483
484 CLI Example:
485
486 .. code-block:: bash
487
488 salt '*' contrail.physical_interface_create ge-0/0/10 physical_router_name
489 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200490 ret = {'name': name,
491 'changes': {},
492 'result': True,
493 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200494 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200495 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200496 pinterf_obj = physical_interface_get(name, physical_router, **kwargs)
497 if 'Error' not in pinterf_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200498 ret['comment'] = 'Physical interface ' + name + ' on ' + physical_router + ' already exists'
499 return ret
500
501 if __opts__['test']:
502 ret['result'] = None
503 ret['comment'] = "Physical interface " + name + " will be created"
504 return ret
505
506 prouter = physical_router_get(physical_router)
507 prouter_obj = vnc_client._object_read('physical-router', id=prouter[physical_router]['_uuid'])
508 pinterf_obj = PhysicalInterface(name, prouter_obj)
509 vnc_client.physical_interface_create(pinterf_obj)
510 ret['comment'] = "Physical interface " + name + " has been created"
511 ret['changes'] = {'Physical interface': {'old': '', 'new': name}}
512 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200513
514
515def physical_interface_delete(name, physical_router, **kwargs):
516 '''
517 Delete specific Contrail physical interface
518
519 CLI Example:
520 .. code-block:: bash
521
522 salt '*' contrail.physical_interface_delete ge-0/0/0 phr01
523 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200524 ret = {'name': name,
525 'changes': {},
526 'result': True,
527 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200528 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200529 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200530 piface = physical_interface_get(name, physical_router)
531 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200532 ret['result'] = None
533 ret['comment'] = "Physical interface " + name + " will be deleted"
534 else:
535 vnc_client.physical_interface_delete(id=piface[name]['_uuid'])
536 ret['comment'] = "Physical router " + name + " has been deleted"
537 ret['changes'] = {'Physical router': {'old': name, 'new': ''}}
538 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200539
540
541def logical_interface_list(**kwargs):
542 '''
543 Return a list of all Contrail logical interfaces
544
545 CLI Example:
546
547 .. code-block:: bash
548
549 salt '*' contrail.logical_interface_list
550 '''
551 ret = []
552 vnc_client = _auth(**kwargs)
553 liface_objs = vnc_client._objects_list('logical-interface', detail=True)
554 for liface_obj in liface_objs:
555 ret.append({
556 'name': liface_obj.name,
557 'uuid': liface_obj._uuid,
558 'fq_name': liface_obj.fq_name,
559 'parent_type': liface_obj.parent_type,
560 })
561 return ret
562
563
564def logical_interface_get(name, parent_names, parent_type=None, **kwargs):
565 '''
566 Return a specific Contrail logical interface
567
568 CLI Example:
569
570 .. code-block:: bash
571
572 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01']
573 or
574 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['ge-0/0/0','phr01']
575 or
576 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01'] parent_type=physcal-interface
577 '''
578 ret = {}
579 vnc_client = _auth(**kwargs)
580 liface_objs = vnc_client._objects_list('logical-interface', detail=True)
581 count = 0
582 for liface_obj in liface_objs:
583 if name == liface_obj.name and set(parent_names).issubset(liface_obj.fq_name):
584 if parent_type and parent_type == liface_obj.parent_type:
585 count += 1
586 ret[liface_obj.name] = liface_obj.__dict__
587 if not parent_type:
588 count += 1
589 ret[liface_obj.name] = liface_obj.__dict__
590 if len(ret) == 0:
591 return {'Error': 'Error in retrieving logical interface.'}
592 if count > 1:
593 return {
594 'Error': 'Error Was found more then one logical interface. Please put more parent_name or put parent_type to chose one of them.'}
595 return ret
596
597
598def logical_interface_create(name, parent_names, parent_type='physical-interface', vlan_tag=None, interface_type="l2",
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300599 vmis=None, **kwargs):
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200600 '''
601 Create specific Contrail logical interface
602
603 CLI Example:
604
605 .. code-block:: bash
606
607 salt '*' contrail.logical_interface_create ge-0/0/10.11 parent_names="['ge-0/0/0','phr1']" parent_type=physical-interface vlan_tag=1025 interface_type=L2
608 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200609 ret = {'name': name,
610 'changes': {},
611 'result': True,
612 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200613 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200614 # gsc_obj = _get_config(vnc_client)
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300615
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200616 liface_obj = logical_interface_get(name, parent_names, parent_type, **kwargs)
617 if 'Error' not in liface_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200618 ret['comment'] = 'Logical interface ' + name + ' already exists'
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200619 else:
620 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200621 ret['result'] = None
622 ret['comment'] = "Logical interface " + name + " will be created"
623 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200624 parent_obj = None
625 for router in parent_names:
626 parent_router = physical_router_get(router)
627 if 'Error' not in parent_router:
628 parent_obj = vnc_client._object_read('physical-router', id=parent_router[router]['_uuid'])
629 break
630 if not parent_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200631 ret['result'] = False
632 ret['comment'] = 'Physical router have to be defined'
633 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200634 if parent_type == 'physical-interface':
635 for interface in parent_names:
636 parent_interface = physical_interface_get(interface, parent_obj.name)
637 if 'Error' not in parent_interface:
638 parent_obj = vnc_client._object_read('physical-interface', id=parent_interface[interface]['_uuid'])
639 break
640 if interface_type.lower() == "l3":
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200641 ret['result'] = False
642 ret['comment'] = "Virtual Network have to be defined for L3 interface type"
643 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200644
645 liface_obj = LogicalInterface(name, parent_obj, vlan_tag, interface_type.lower())
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300646
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200647 if vmis:
648 for vmi_name, vmi in vmis.iteritems():
649 vmi = vnc_client.virtual_machine_interface_read(
650 fq_name=_get_fq_name(vnc_client, resource_name=vmi_name,
651 project_name=kwargs.get('tenant', 'admin')))
652 liface_obj.add_virtual_machine_interface(vmi)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200653 vnc_client.logical_interface_create(liface_obj)
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300654
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200655 ret['comment'] = "Logical interface " + name + " has been created"
656 ret['changes'] = {'Logical interface': {'old': '', 'new': name}}
657 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200658
659
660def logical_interface_delete(name, parent_names, parent_type=None, **kwargs):
661 '''
662 Delete specific Contrail logical interface
663
664 CLI Example:
665
666 .. code-block:: bash
667
668 salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['ge-0/0/0','phr01']
669 or
670 salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['phr01'] parent_type=physical-router
671
672 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200673 ret = {'name': name,
674 'changes': {},
675 'result': True,
676 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200677 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200678 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200679 liface = logical_interface_get(name, parent_names, parent_type)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200680
681 if __opts__['test']:
682 ret['result'] = None
683 ret['comment'] = "Logical interface " + name + " will be deleted"
684 return ret
685 vnc_client.logical_interface_delete(id=liface[name]['_uuid'])
686 ret['comment'] = "Logical interface " + name + " has been deleted"
687 ret['changes'] = {'LogicalInterface ': {'old': name, 'new': ''}}
688 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200689
690
691def global_vrouter_config_list(**kwargs):
692 '''
693 Return a list of all Contrail global vrouter configs
694
695 CLI Example:
696
697 .. code-block:: bash"
698
699 salt '*' global_vrouter_config_list
700 '''
701 ret = {}
702 vnc_client = _auth(**kwargs)
703 vrouter_conf_objs = vnc_client._objects_list('global-vrouter-config', detail=True)
704 for vrouter_conf_obj in vrouter_conf_objs:
Anton Samoylovce3d7772018-11-23 00:00:02 +0400705 ret[vrouter_conf_obj.name] = vrouter_conf_obj.__dict__
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200706 return ret
707
708
709def global_vrouter_config_get(name, **kwargs):
710 '''
711 Return a specific Contrail global vrouter config
712
713 CLI Example:
714
715 .. code-block:: bash
716
717 salt '*' contrail.global_vrouter_get global-vrouter-config
718 '''
719 ret = {}
720 vrouter_conf_objs = global_vrouter_config_list(**kwargs)
721 if name in vrouter_conf_objs:
722 ret[name] = vrouter_conf_objs.get(name)
723 if len(ret) == 0:
724 return {'Error': 'Error in retrieving global vrouter config.'}
725 return ret
726
727
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +0100728def global_vrouter_config_create(name, parent_type, encap_priority, vxlan_vn_id_mode, flow_export_rate, *fq_names, **kwargs):
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200729 '''
730 Create specific Contrail global vrouter config
731
732 CLI Example:
733
734 .. code-block:: bash
735
Anton Samoylov02fb79b2019-04-15 12:42:54 +0400736 salt '*' contrail.global_vrouter_config_create \
737 name=global-vrouter-config parent_type=global-system-config \
738 encap_priority="MPLSoUDP,MPLSoGRE" vxlan_vn_id_mode="automatic" \
739 flow_export_rate=None \
740 fq_names="['default-global-system-config', 'default-global-vrouter-config']"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200741 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200742 ret = {'name': name,
743 'changes': {},
744 'result': True,
745 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200746 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200747 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200748 vrouter_conf_objs = global_vrouter_config_list(**kwargs)
749 if name in vrouter_conf_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200750 ret['comment'] = 'Global vrouter config ' + name + ' already exists'
751 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200752 else:
753 vrouter_conf_obj = GlobalVrouterConfig(
754 name=name,
755 parent_obj=None,
756 encapsulation_priorities=EncapsulationPrioritiesType(encapsulation=encap_priority.split(",")),
757 fq_name=fq_names,
758 vxlan_network_identifier_mode=vxlan_vn_id_mode,
759 parent_type=parent_type,
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +0100760 flow_export_rate=flow_export_rate,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200761 )
762 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200763 ret['result'] = None
764 ret['comment'] = "Global vRouter config " + name + " will be created"
765 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200766 vnc_client.global_vrouter_config_create(vrouter_conf_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200767 ret['comment'] = "Global vRouter config " + name + " has been created"
768 ret['changes'] = {'Global vRouter config': {'old': '', 'new': name}}
769 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200770
771
772def global_vrouter_config_delete(name, **kwargs):
773 '''
774 Delete specific Contrail global vrouter config
775
776 CLI Example:
777
778 .. code-block:: bash
779
780 salt '*' contrail.global_vrouter_config_delete global-vrouter-config
781 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200782 ret = {'name': name,
783 'changes': {},
784 'result': True,
785 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200786 vnc_client = _auth(**kwargs)
787 gsc_obj = _get_config(vnc_client)
788 vrouter_conf_obj = GlobalVrouterConfig(name, gsc_obj)
789 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200790 ret['result'] = None
791 ret['comment'] = "Global vRouter config " + name + " will be deleted"
792 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200793 vnc_client.global_vrouter_config_delete(
794 fq_name=vrouter_conf_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200795 ret['comment'] = "Global vRouter config " + name + " has been deleted"
796 ret['changes'] = {'Global vRouter config': {'old': name, 'new': ''}}
797 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100798
799
800def analytics_node_list(**kwargs):
801 '''
802 Return a list of all Contrail analytics nodes
803
804 CLI Example:
805
806 .. code-block:: bash
807
808 salt '*' contrail.analytics_node_list
809 '''
810 ret = {}
811 vnc_client = _auth(**kwargs)
812 node_objs = vnc_client._objects_list('analytics-node', detail=True)
813 for node_obj in node_objs:
814 ret[node_obj.name] = node_obj.__dict__
815 return ret
816
817
818def analytics_node_get(name, **kwargs):
819 '''
820 Return a specific Contrail analytics node
821
822 CLI Example:
823
824 .. code-block:: bash
825
826 salt '*' contrail.analytics_node_get nal01
827 '''
828 ret = {}
829 vrouter_objs = analytics_node_list(**kwargs)
830 if name in vrouter_objs:
831 ret[name] = vrouter_objs.get(name)
832 if len(ret) == 0:
833 return {'Error': 'Error in retrieving analytics node.'}
834 return ret
835
836
837def analytics_node_create(name, ip_address, **kwargs):
838 '''
839 Create specific Contrail analytics node
840
841 CLI Example:
842
843 .. code-block:: bash
844
845 salt '*' contrail.analytics_node_create ntw03 10.10.10.103
846 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200847
848 ret = {'name': name,
849 'changes': {},
850 'result': True,
851 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100852 vnc_client = _auth(**kwargs)
853 gsc_obj = _get_config(vnc_client)
854 analytics_node_objs = analytics_node_list(**kwargs)
855 if name in analytics_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200856 ret['comment'] = 'Analytics node %s already exists'
857 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100858 else:
859 analytics_node_obj = AnalyticsNode(
860 name, gsc_obj,
861 analytics_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200862 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200863 ret['result'] = None
864 ret['comment'] = "AnalyticsNode " + name + " will be created"
865 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100866 vnc_client.analytics_node_create(analytics_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200867 ret['comment'] = "AnalyticsNode " + name + " has been created"
868 ret['changes'] = {'Analytics Node': {'old': '', 'new': name}}
869 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100870
871
872def analytics_node_delete(name, **kwargs):
873 '''
874 Delete specific Contrail analytics node
875
876 CLI Example:
877
878 .. code-block:: bash
879
880 salt '*' contrail.analytics_node_delete cmp01
881 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200882 ret = {'name': name,
883 'changes': {},
884 'result': True,
885 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100886 vnc_client = _auth(**kwargs)
887 gsc_obj = _get_config(vnc_client)
888 analytics_node_obj = AnalyticsNode(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200889 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200890 ret['result'] = None
891 ret['comment'] = "AnalyticsNode " + name + " will be deleted"
892 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100893 vnc_client.analytics_node_delete(
894 fq_name=analytics_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200895 ret['comment'] = "AnalyticsNode " + name + " has been deleted"
896 ret['changes'] = {'Analytics Node': {'old': name, 'new': ''}}
897 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100898
899
900def config_node_list(**kwargs):
901 '''
902 Return a list of all Contrail config nodes
903
904 CLI Example:
905
906 .. code-block:: bash
907
908 salt '*' contrail.config_node_list
909 '''
910 ret = {}
911 vnc_client = _auth(**kwargs)
912 node_objs = vnc_client._objects_list('config-node', detail=True)
913 for node_obj in node_objs:
914 ret[node_obj.name] = node_obj.__dict__
915 return ret
916
917
918def config_node_get(name, **kwargs):
919 '''
920 Return a specific Contrail config node
921
922 CLI Example:
923
924 .. code-block:: bash
925
926 salt '*' contrail.config_node_get nal01
927 '''
928 ret = {}
929 vrouter_objs = config_node_list(**kwargs)
930 if name in vrouter_objs:
931 ret[name] = vrouter_objs.get(name)
932 if len(ret) == 0:
933 return {'Error': 'Error in retrieving config node.'}
934 return ret
935
936
937def config_node_create(name, ip_address, **kwargs):
938 '''
939 Create specific Contrail config node
940
941 CLI Example:
942
943 .. code-block:: bash
944
945 salt '*' contrail.config_node_create ntw03 10.10.10.103
946 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200947 ret = {'name': name,
948 'changes': {},
949 'result': True,
950 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100951 vnc_client = _auth(**kwargs)
952 gsc_obj = _get_config(vnc_client)
953 config_node_objs = config_node_list(**kwargs)
954 if name in config_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200955 ret['comment'] = 'Config node ' + name + ' already exists'
956 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100957 else:
958 config_node_obj = ConfigNode(
959 name, gsc_obj,
960 config_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200961 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200962 ret['comment'] = "ConfigNode " + name + " will be created"
963 ret['result'] = None
964 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100965 vnc_client.config_node_create(config_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200966 ret['comment'] = "ConfigNode " + name + " has been created"
967 ret['changes'] = {'ConfigNode': {'old': '', 'new': name}}
968 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100969
970
971def config_node_delete(name, **kwargs):
972 '''
973 Delete specific Contrail config node
974
975 CLI Example:
976
977 .. code-block:: bash
978
979 salt '*' contrail.config_node_delete cmp01
980 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200981 ret = {'name': name,
982 'changes': {},
983 'result': True,
984 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100985 vnc_client = _auth(**kwargs)
986 gsc_obj = _get_config(vnc_client)
987 config_node_obj = ConfigNode(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200988 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200989 ret['comment'] = "ConfigNode " + name + " will be deleted"
990 ret['result'] = None
991 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100992 vnc_client.config_node_delete(
993 fq_name=config_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200994 ret['comment'] = "ConfigNode " + name + " has been deleted"
995 ret['changes'] = {'ConfigNode': {'old': name, 'new': ''}}
996 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100997
998
999def bgp_router_list(**kwargs):
1000 '''
1001 Return a list of all Contrail BGP routers
1002
1003 CLI Example:
1004
1005 .. code-block:: bash
1006
1007 salt '*' contrail.bgp_router_list
1008 '''
1009 ret = {}
1010 vnc_client = _auth(**kwargs)
1011 bgp_router_objs = vnc_client._objects_list('bgp-router', detail=True)
1012 for bgp_router_obj in bgp_router_objs:
1013 ret[bgp_router_obj.name] = bgp_router_obj.__dict__
1014 return ret
1015
1016
1017def bgp_router_get(name, **kwargs):
1018 '''
1019 Return a specific Contrail BGP router
1020
1021 CLI Example:
1022
1023 .. code-block:: bash
1024
1025 salt '*' contrail.bgp_router_get nal01
1026 '''
1027 ret = {}
1028 bgp_router_objs = bgp_router_list(**kwargs)
1029 if name in bgp_router_objs:
1030 ret[name] = bgp_router_objs.get(name)
1031 if len(ret) == 0:
1032 return {'Error': 'Error in retrieving BGP router.'}
1033 return ret
1034
1035
Marek Celoud3097e5b2018-01-09 13:52:14 +01001036def bgp_router_create(name, type, ip_address, asn=64512, key_type=None, key=None, **kwargs):
Ales Komarekad46d2e2017-03-09 17:16:38 +01001037 '''
1038 Create specific Contrail control node
1039
1040 CLI Example:
1041
1042 .. code-block:: bash
1043
1044 salt '*' contrail.bgp_router_create ntw03 control-node 10.10.10.103
1045 salt '*' contrail.bgp_router_create mx01 router 10.10.10.105
1046 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001047 ret = {'name': name,
1048 'changes': {},
1049 'result': True,
1050 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001051 vnc_client = _auth(**kwargs)
1052
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001053 address_families = ['route-target', 'inet-vpn', 'e-vpn', 'erm-vpn',
1054 'inet6-vpn']
1055 if type != 'control-node':
1056 address_families.remove('erm-vpn')
1057
Marek Celoud3097e5b2018-01-09 13:52:14 +01001058 key_type = None if key_type == 'None' else key_type
1059 key = None if key == 'None' else key
1060
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001061 bgp_addr_fams = AddressFamilies(address_families)
1062 bgp_sess_attrs = [
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001063 BgpSessionAttributes(address_families=bgp_addr_fams)]
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001064 bgp_sessions = [BgpSession(attributes=bgp_sess_attrs)]
1065 bgp_peering_attrs = BgpPeeringAttributes(session=bgp_sessions)
1066 rt_inst_obj = _get_rt_inst_obj(vnc_client)
1067
Marek Celoud3097e5b2018-01-09 13:52:14 +01001068 bgp_auth_data = None
1069
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001070 if type == 'control-node':
1071 vendor = 'contrail'
1072 elif type == 'router':
1073 vendor = 'mx'
Marek Celoud3097e5b2018-01-09 13:52:14 +01001074 if key_type == 'md5':
1075 key_id = 0
1076 key_items = AuthenticationKeyItem(key_id, key)
1077 bgp_auth_data = AuthenticationData(key_type, [key_items])
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001078 else:
1079 vendor = 'unknown'
1080
1081 router_params = BgpRouterParams(router_type=type,
1082 vendor=vendor, autonomous_system=int(asn),
1083 identifier=_get_ip(ip_address),
1084 address=_get_ip(ip_address),
Marek Celoud3097e5b2018-01-09 13:52:14 +01001085 port=179, address_families=bgp_addr_fams,
1086 auth_data=bgp_auth_data)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001087
Ales Komarekad46d2e2017-03-09 17:16:38 +01001088 bgp_router_objs = bgp_router_list(**kwargs)
1089 if name in bgp_router_objs:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001090 bgp_router_obj = vnc_client._object_read('bgp-router', id=bgp_router_objs[name]['_uuid'])
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001091
1092 if bgp_router_obj.bgp_router_parameters.autonomous_system != asn:
1093 ret['changes'].update({"autonomous_system": {'old': bgp_router_obj.bgp_router_parameters.autonomous_system, 'new': asn}})
1094 if bgp_router_obj.bgp_router_parameters.vendor != vendor:
1095 ret['changes'].update({"vendor": {'old': bgp_router_obj.bgp_router_parameters.vendor, 'new': vendor}})
1096 if bgp_router_obj.bgp_router_parameters.address != ip_address:
1097 ret['changes'].update({"ip_address": {'old': bgp_router_obj.bgp_router_parameters.address, 'new': ip_address}})
Marek Celoud3097e5b2018-01-09 13:52:14 +01001098 try:
1099 if bgp_router_obj.bgp_router_parameters.auth_data.key_type != key_type:
1100 ret['changes'].update({"key_type": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_type, 'new': key_type}})
1101 except:
1102 if key_type != None:
1103 ret['changes'].update({"key_type": {'old': None, 'new': key_type}})
1104 if key_type == 'md5':
1105 try:
1106 if bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key != key:
1107 ret['changes'].update({"key_type": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key, 'new': key}})
1108 except:
1109 ret['changes'].update({"key_type": {'old': None, 'new': key}})
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001110
1111 if len(ret['changes']) == 0:
1112 return ret
1113
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001114 bgp_router_obj.set_bgp_router_parameters(router_params)
1115 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001116 ret['result'] = None
1117 ret['comment'] = "BGP router " + name + " will be updated"
1118 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001119 vnc_client.bgp_router_update(bgp_router_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001120 ret['comment'] = "BGP router " + name + " has been updated"
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001121 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001122 else:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001123 bgp_router_obj = BgpRouter(name, rt_inst_obj, bgp_router_parameters=router_params)
1124 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001125 ret['result'] = None
1126 ret['comment'] = "BGP router " + name + " will be created"
1127 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001128 vnc_client.bgp_router_create(bgp_router_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001129 ret['comment'] = "BGP router " + name + " has been created"
1130 ret['changes'] = {'BGP router': {'old': name, 'new': ''}}
1131 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001132
1133
1134def bgp_router_delete(name, **kwargs):
1135 '''
1136 Delete specific Contrail control node
1137
1138 CLI Example:
1139
1140 .. code-block:: bash
1141
1142 salt '*' contrail.bgp_router_delete mx01
1143 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001144 ret = {'name': name,
1145 'changes': {},
1146 'result': True,
1147 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001148 vnc_client = _auth(**kwargs)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001149
1150 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001151 ret['result'] = None
1152 ret['comment'] = "BGP router " + name + " will be deleted"
1153 return ret
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001154
1155 bgp_router = bgp_router_get(name)
1156 if name in bgp_router:
1157 vnc_client.bgp_router_delete(fq_name=bgp_router[name]['fq_name'])
1158 ret['comment'] = "BGP router " + name + " has been deleted"
1159 ret['changes'] = {'BGP router': {'old': '', 'new': name}}
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001160 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001161
Ales Komarekad46d2e2017-03-09 17:16:38 +01001162
1163def database_node_list(**kwargs):
1164 '''
1165 Return a list of all Contrail database nodes
1166
1167 CLI Example:
1168
1169 .. code-block:: bash
1170
1171 salt '*' contrail.database_node_list
1172 '''
1173 ret = {}
1174 vnc_client = _auth(**kwargs)
1175 node_objs = vnc_client._objects_list('database-node', detail=True)
1176 for node_obj in node_objs:
1177 ret[node_obj.name] = node_obj.__dict__
1178 return ret
1179
1180
1181def database_node_get(name, **kwargs):
1182 '''
1183 Return a specific Contrail database node
1184
1185 CLI Example:
1186
1187 .. code-block:: bash
1188
1189 salt '*' contrail.database_node_get nal01
1190 '''
1191 ret = {}
1192 vrouter_objs = database_node_list(**kwargs)
1193 if name in vrouter_objs:
1194 ret[name] = vrouter_objs.get(name)
1195 if len(ret) == 0:
1196 return {'Error': 'Error in retrieving database node.'}
1197 return ret
1198
1199
1200def database_node_create(name, ip_address, **kwargs):
1201 '''
1202 Create specific Contrail database node
1203
1204 CLI Example:
1205
1206 .. code-block:: bash
1207
1208 salt '*' contrail.database_node_create ntw03 10.10.10.103
1209 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001210 ret = {'name': name,
1211 'changes': {},
1212 'result': True,
1213 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001214 vnc_client = _auth(**kwargs)
1215 gsc_obj = _get_config(vnc_client)
1216 database_node_objs = database_node_list(**kwargs)
1217 if name in database_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001218 ret['comment'] = 'Database node ' + name + ' already exists'
1219 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001220 else:
1221 database_node_obj = DatabaseNode(
1222 name, gsc_obj,
1223 database_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001224 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001225 ret['result'] = None
1226 ret['comment'] = "DatabaseNode " + name + " will be created"
1227 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001228 vnc_client.database_node_create(database_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001229 ret['comment'] = "DatabaseNode " + name + " has been created"
1230 ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}}
1231 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001232
1233
1234def database_node_delete(name, **kwargs):
1235 '''
1236 Delete specific Contrail database node
1237
1238 CLI Example:
1239
1240 .. code-block:: bash
1241
1242 salt '*' contrail.database_node_delete cmp01
1243 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001244 ret = {'name': name,
1245 'changes': {},
1246 'result': True,
1247 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001248 vnc_client = _auth(**kwargs)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001249 gsc_obj = _get_config(vnc_client)
1250 database_node_obj = DatabaseNode(name, gsc_obj)
1251 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001252 ret['result'] = None
1253 ret['comment'] = "DatabaseNode " + name + " will be deleted"
1254 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001255 vnc_client.database_node_delete(
1256 fq_name=database_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001257 ret['comment'] = "DatabaseNode " + name + " has been deleted"
1258 ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}}
1259 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001260
1261
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001262def _get_vrouter_config(vnc_client, gvc_name=None):
Petr Jediný5f3efe32017-05-26 17:55:09 +02001263 try:
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001264 if not gvc_name:
1265 gvc_list = global_vrouter_config_list()
1266 gvc_name = gvc_list.values()[0]['name']
1267
Petr Jediný5f3efe32017-05-26 17:55:09 +02001268 config = vnc_client.global_vrouter_config_read(
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001269 fq_name=['default-global-system-config', gvc_name])
Petr Jediný5f3efe32017-05-26 17:55:09 +02001270 except Exception:
1271 config = None
1272
1273 return config
1274
1275
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001276def linklocal_service_list(global_vrouter_config_name=None, **kwargs):
Petr Jediný5f3efe32017-05-26 17:55:09 +02001277 '''
1278 Return a list of all Contrail link local services
1279
1280 CLI Example:
1281
1282 .. code-block:: bash
1283
1284 salt '*' contrail.linklocal_service_list
1285 '''
1286 ret = {}
1287 vnc_client = _auth(**kwargs)
1288
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001289 current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001290 if current_config is None:
1291 return ret
1292
1293 service_list_res = current_config.get_linklocal_services()
1294 if service_list_res is None:
1295 service_list_obj = {'linklocal_service_entry': []}
1296 else:
1297 service_list_obj = service_list_res.__dict__
1298 for _, value in service_list_obj.iteritems():
1299 for entry in value:
1300 service = entry.__dict__
1301 if 'linklocal_service_name' in service:
1302 ret[service['linklocal_service_name']] = service
1303 return ret
1304
1305
1306def linklocal_service_get(name, **kwargs):
1307 '''
1308 Return a specific Contrail link local service
1309
1310 CLI Example:
1311
1312 .. code-block:: bash
1313
1314 salt '*' contrail.linklocal_service_get llservice
1315 '''
1316 ret = {}
1317 services = linklocal_service_list(**kwargs)
1318 if name in services:
1319 ret[name] = services.get(name)
1320 if len(ret) == 0:
1321 return {'Error': 'Error in retrieving link local service "{0}"'.format(name)}
1322 return ret
1323
1324
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001325def linklocal_service_create(name, lls_ip, lls_port, ipf_dns_or_ip, ipf_port, global_vrouter_config_name=None, **kwargs):
Petr Jediný5f3efe32017-05-26 17:55:09 +02001326 '''
1327 Create specific Contrail link local service
1328
1329 CLI Example:
1330
1331 .. code-block:: bash
1332
1333 salt '*' contrail.linklocal_service_create \
1334 llservice 10.10.10.103 22 '["20.20.20.20", "30.30.30.30"]' 22
1335 salt '*' contrail.linklocal_service_create \
1336 llservice 10.10.10.103 22 link-local.service.dns-name 22
1337 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001338 ret = {'name': name,
1339 'changes': {},
1340 'result': True,
1341 'comment': ''}
Petr Jediný5f3efe32017-05-26 17:55:09 +02001342 vnc_client = _auth(**kwargs)
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001343 current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001344 service_entry = LinklocalServiceEntryType(
1345 linklocal_service_name=name,
1346 linklocal_service_ip=lls_ip,
1347 linklocal_service_port=lls_port,
1348 ip_fabric_service_port=ipf_port)
1349 if isinstance(ipf_dns_or_ip, basestring):
1350 service_entry.ip_fabric_DNS_service_name = ipf_dns_or_ip
1351 elif isinstance(ipf_dns_or_ip, list):
1352 service_entry.ip_fabric_service_ip = ipf_dns_or_ip
1353 service_entry.ip_fabric_DNS_service_name = ''
1354
1355 if current_config is None:
1356 new_services = LinklocalServicesTypes([service_entry])
1357 new_config = GlobalVrouterConfig(linklocal_services=new_services)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001358 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001359 ret['result'] = None
1360 ret['comment'] = "Link local service " + name + " will be created"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001361 else:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001362 ret['comment'] = "Link local service " + name + " has been created"
1363 ret['changes'] = {'LinkLocalSevice': {'old': '', 'new': name}}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001364 vnc_client.global_vrouter_config_create(new_config)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001365 else:
1366 _current_service_list = current_config.get_linklocal_services()
1367 if _current_service_list is None:
1368 service_list = {'linklocal_service_entry': []}
1369 else:
1370 service_list = _current_service_list.__dict__
1371 new_services = [service_entry]
1372 for key, value in service_list.iteritems():
1373 if key != 'linklocal_service_entry':
1374 continue
1375 for _entry in value:
1376 entry = _entry.__dict__
1377 if 'linklocal_service_name' in entry:
1378 if entry['linklocal_service_name'] == name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001379 ret['comment'] = 'Link local service ' + name + ' already exists'
1380 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001381 new_services.append(_entry)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001382 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001383 ret['result'] = None
1384 ret['comment'] = "LinkLocalSevices " + name + " will be created"
Petr Jediný5f3efe32017-05-26 17:55:09 +02001385 service_list[key] = new_services
1386 new_config = GlobalVrouterConfig(linklocal_services=service_list)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001387 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001388 ret['result'] = None
1389 ret['comment'] = "LinkLocalSevices " + name + " will be updated"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001390 else:
1391 vnc_client.global_vrouter_config_update(new_config)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001392 ret['comment'] = "LinkLocalSevices " + name + " has been created"
1393 ret['changes'] = {'LinkLocalSevices': {'old': '', 'new': name}}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001394 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001395
1396
1397def linklocal_service_delete(name, **kwargs):
1398 '''
1399 Delete specific link local service entry
1400
1401 CLI Example:
1402
1403 .. code-block:: bash
1404
1405 salt '*' contrail.linklocal_service_delete llservice
1406 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001407 ret = {'name': name,
1408 'changes': {},
1409 'result': True,
1410 'comment': ''}
1411 lls = linklocal_service_get(name)
1412 print (lls)
1413 if name in lls:
1414 if __opts__['test']:
1415 print " ------------ Test only ------------"
1416 ret['result'] = None
1417 ret['comment'] = "Link local service " + name + " will be deleted"
1418 return ret
1419 else:
1420 return ret
1421
Petr Jediný5f3efe32017-05-26 17:55:09 +02001422 vnc_client = _auth(**kwargs)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001423 current_config = _get_vrouter_config(vnc_client)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001424 if current_config is not None:
1425 _current_service_list = current_config.get_linklocal_services()
1426 if _current_service_list is None:
1427 service_list = {'linklocal_service_entry': []}
1428 else:
1429 service_list = _current_service_list.__dict__
1430 new_services = []
1431 for key, value in service_list.iteritems():
1432 if key != 'linklocal_service_entry':
1433 continue
1434 for _entry in value:
1435 entry = _entry.__dict__
1436 if 'linklocal_service_name' in entry:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001437 if entry['linklocal_service_name'] != name:
Petr Jediný5f3efe32017-05-26 17:55:09 +02001438 new_services.append(_entry)
1439 service_list[key] = new_services
1440 new_config = GlobalVrouterConfig(linklocal_services=service_list)
1441 vnc_client.global_vrouter_config_update(new_config)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001442 ret['comment'] = "Link local service " + name + " will be deleted"
1443 ret['changes'] = {'LinkLocalService': {'old': '', 'new': name}}
1444 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001445
1446
1447def virtual_machine_interface_list(**kwargs):
1448 '''
1449 Return a list of all Contrail virtual machine interfaces
1450
1451 CLI Example:
1452
1453 .. code-block:: bash
1454
1455 salt '*' contrail.virtual_machine_interfaces
1456 '''
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001457 ret = []
1458 vnc_client = _auth(**kwargs)
1459 project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin'))
1460 project_uuid = project.get_uuid()
1461
1462 vm_ifaces = vnc_client.virtual_machine_interfaces_list(
1463 detail=True, parent_id=project_uuid)
1464
1465 for vm_iface in vm_ifaces:
1466 ret.append(vm_iface.__dict__)
1467
1468 return ret
1469
1470
1471def virtual_machine_interface_create(name,
1472 virtual_network,
1473 mac_address=None,
1474 ip_address=None,
1475 security_group=None,
1476 **kwargs):
1477 '''
1478 Create specific Contrail virtual machine interface (Port)
1479
1480 CLI Example:
1481
1482 .. code-block:: bash
1483
1484 salt '*' contrail.virtual_machine_interface_create port01 net01 mac_address='01:02:03:04:05:06'
1485 router_types:
1486 - tor-agent
1487 - tor-service-node
1488 - embedded
1489 '''
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001490 ret = {}
1491 vnc_client = _auth(**kwargs)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001492 project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin'))
1493
1494 vm_int = VirtualMachineInterface(name, parent_obj=project)
1495
1496 if mac_address:
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001497 mac_address_obj = MacAddressesType([mac_address])
1498 vm_int.set_virtual_machine_interface_mac_addresses(mac_address_obj)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001499
1500 if security_group:
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001501 sgo = vnc_client.security_group_read(fq_name=_get_fq_name(
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001502 vnc_client, security_group, kwargs.get('tenant', 'admin')))
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001503 vm_int.set_security_group(sgo)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001504
1505 vnet_uuid = virtual_network_get(virtual_network, **kwargs)[virtual_network]['_uuid']
1506 vnet_obj = vnc_client.virtual_network_read(id=vnet_uuid)
1507 vm_int.set_virtual_network(vnet_obj)
1508
1509 vmi_uuid = vnc_client.virtual_machine_interface_create(vm_int)
1510 vmi = vnc_client.virtual_machine_interface_read(id=vmi_uuid)
1511
1512 vm_int.set_port_security_enabled(False)
1513 vnc_client.virtual_machine_interface_update(vm_int)
1514
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001515 # Allocate IP to VMI
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001516 ip = vnc_api.InstanceIp(name + '.ip')
1517 ip.set_virtual_machine_interface(vmi)
1518 ip.set_virtual_network(vnet_obj)
1519
1520 ip_uuid = vnc_client.instance_ip_create(ip)
1521
1522 if ip_address:
1523 ip.set_instance_ip_address(ip_address)
1524 vnc_client.instance_ip_update(ip)
1525
1526 return vmi.__dict__
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001527
1528
1529def virtual_network_list(**kwargs):
1530 '''
1531 Return a list of all Contrail virtual network
1532
1533 CLI Example:
1534
1535 .. code-block:: bash
1536
1537 salt '*' contrail.virtual_network
1538 '''
1539
1540 ret = {}
1541 vnc_client = _auth(**kwargs)
1542 virtual_networks = vnc_client._objects_list('virtual-network', detail=True)
1543 for virtual_network in virtual_networks:
1544 ret[virtual_network.name] = virtual_network.__dict__
1545 return ret
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001546
1547
1548def virtual_network_get(name, **kwargs):
1549 '''
1550 Return a specific Contrail virtual network
1551
1552 CLI Example:
1553
1554 .. code-block:: bash
1555
1556 salt '*' contrail.virtual_network_get net01
1557 '''
1558 ret = {}
1559 vnet_objs = virtual_network_list(**kwargs)
1560 if name in vnet_objs:
1561 ret[name] = vnet_objs.get(name)
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001562 if len(ret) != 1:
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001563 return {'result': False,
1564 'Error': 'Error in retrieving virtual networks.'}
1565 return ret
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001566
1567
Jan Cacha859e6b2018-01-09 17:34:18 +01001568def virtual_network_create(name, conf=None, **kwargs):
1569 '''
1570 Create Contrail virtual network
1571 CLI Example:
1572 .. code-block:: bash
1573 salt '*' contrail.virtual_network_create name
1574
1575 salt.cmdRun(pepperEnv, 'ntw01*', 'salt-call contrail.virtual_network_create
1576 "testicek" "{"external":"True","ip":"172.16.111.0","prefix":24,
1577 "asn":64512,"target":10000}" ')
1578
1579 Parameters:
1580 name required - name of the new network
1581
1582 conf (dict) optional:
1583 domain (string) optional - which domain use for vn creation
1584 project (string) optional - which project use for vn creation
1585 ipam_domain (string) optional - domain for ipam
1586 ipam_project (string) optional - project for ipam
1587 ipam_name (string) optional - ipam name
1588 ip_prefix (string) optional - format is xxx.xxx.xxx.xxx
1589 ip_prefix_len (int) optional - format is xx
1590 asn (int) optional - autonomus system number
1591 target (int) optional - route target number
1592 external (boolean) optional - set if network is external
1593
1594 allow_transit (boolean) optional - enable allow transit
1595 forwarding_mode (any of ['l2_l3','l2','l3']) optional
1596 - packet forwarding mode for this virtual network
1597 rpf (any of ['enabled','disabled']) optional
1598 - Enable or disable Reverse Path Forwarding check
1599 for this network
1600 mirror_destination (boolean) optional
1601 - Mark the vn as mirror destination network
1602 '''
1603 if conf is None:
1604 conf = {}
1605
1606 # check for domain, is missing set to default-domain
1607 if 'domain' in conf:
1608 vn_domain = str(conf['domain'])
1609 else:
1610 vn_domain = 'default-domain'
1611 # check for project, is missing set to admin
1612 if 'project' in conf:
1613 vn_project = str(conf['project'])
1614 else:
1615 vn_project = 'admin'
1616 # check for ipam domain,default is default-domain
1617 if 'ipam_domain' in conf:
1618 ipam_domain = str(conf['ipam_domain'])
1619 else:
1620 ipam_domain = 'default-domain'
1621 # check for ipam domain,default is default-domain
1622 if 'ipam_project' in conf:
1623 ipam_project = str(conf['ipam_project'])
1624 else:
1625 ipam_project = 'default-project'
1626
1627 if 'ipam_name' in conf:
1628 ipam_name = conf['ipam_name']
1629 else:
1630 ipam_name = 'default-network-ipam'
1631
1632 ret = {'name': name,
1633 'changes': {},
1634 'result': True,
1635 'comment': ''}
1636
1637 # list of existing vn networks
1638 vn_networks = []
1639 vnc_client = _auth(**kwargs)
Jan Cach03412162018-01-12 10:29:22 +01001640 prj_obj = vnc_client.project_read(fq_name=[vn_domain,
1641 vn_project])
Jan Cacha859e6b2018-01-09 17:34:18 +01001642 # check if the network exists
1643 vn_networks_list = vnc_client._objects_list('virtual_network')
Jan Cachece0d242018-01-12 14:58:36 +01001644 fq = [vn_domain, vn_project, name]
Jan Cacha859e6b2018-01-09 17:34:18 +01001645 for network in vn_networks_list['virtual-networks']:
1646 if fq == network['fq_name']:
1647 ret['comment'] = ("Virtual network with name "
1648 + name + " already exists")
1649 return ret
1650
Jan Cach03412162018-01-12 10:29:22 +01001651 vn_obj = VirtualNetwork(name, prj_obj)
Jan Cacha859e6b2018-01-09 17:34:18 +01001652 vn_type_obj = VirtualNetworkType()
1653 # get ipam from default project and domain
1654 ipam = vnc_client.network_ipam_read(fq_name=[ipam_domain,
1655 ipam_project,
1656 ipam_name])
1657
1658 # create subnet
1659 if 'ip_prefix' in conf and 'ip_prefix_len' in conf:
1660 ipam_subnet_type = IpamSubnetType(subnet=SubnetType(
1661 ip_prefix=conf['ip_prefix'],
1662 ip_prefix_len=conf['ip_prefix_len']))
1663
1664 vn_subnets_type_obj = VnSubnetsType(ipam_subnets=[ipam_subnet_type])
1665 vn_obj.add_network_ipam(ipam, vn_subnets_type_obj)
1666
1667 # add route target to the network
1668 if 'asn' in conf and 'target' in conf:
1669 route_target_list_obj = RouteTargetList(["target:{0}:{1}"
1670 .format(conf['asn'],
1671 conf['target'])])
1672 vn_obj.set_route_target_list(route_target_list_obj)
1673
1674 if 'external' in conf:
1675 vn_obj.set_router_external(conf['external'])
1676
1677 if 'allow_transit' in conf:
1678 vn_type_obj.set_allow_transit(conf['allow_transit'])
1679
1680 if 'forwarding_mode' in conf:
1681 if conf['forwarding_mode'] in ['l2_l3', 'l2', 'l3']:
1682 vn_type_obj.set_forwarding_mode(conf['forwarding_mode'])
1683
1684 if 'rpf' in conf:
1685 vn_type_obj.set_rpf(conf['rpf'])
1686
1687 if 'mirror_destination' in conf:
1688 vn_type_obj.set_mirror_destination(conf['mirror_destination'])
1689
1690 vn_obj.set_virtual_network_properties(vn_type_obj)
1691
1692 # create virtual network
1693 if __opts__['test']:
1694 ret['result'] = None
1695 ret['comment'] = ("Virtual network with name {0} will be created"
1696 .format(name))
1697 else:
1698 vnc_client.virtual_network_create(vn_obj)
Jan Cachb3092722018-01-31 12:46:16 +01001699 # if network is external create floating ip pool
1700 if 'external' in conf:
1701 if conf['external']:
1702 pool_name = 'default'
1703 _create_floating_ip_pool(pool_name,
1704 vn_obj,
1705 **kwargs)
1706
Jan Cacha859e6b2018-01-09 17:34:18 +01001707 ret['comment'] = ("Virtual network with name {0} was created"
1708 .format(name))
1709 return ret
1710
1711
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001712def service_appliance_set_list(**kwargs):
1713 '''
1714 Return a list of Contrail service appliance set
1715
1716 CLI Example:
1717
1718 .. code-block:: bash
1719
1720 salt '*' contrail.service_appliance_set_list
1721 '''
1722 ret = {}
1723 vnc_client = _auth(**kwargs)
1724 service_appliance_sets = vnc_client._objects_list('service-appliance-set', detail=True)
1725 for service_appliance_set in service_appliance_sets:
1726 ret[service_appliance_set.name] = service_appliance_set.__dict__
1727 return ret
1728
1729
1730def service_appliance_set_get(name, **kwargs):
1731 '''
1732 Return a specific Contrail service appliance set
1733
1734 CLI Example:
1735
1736 .. code-block:: bash
1737
1738 salt '*' contrail.service_appliance_set_get name
1739 '''
1740 ret = {}
1741 sas_objs = service_appliance_set_list(**kwargs)
1742 if name in sas_objs:
1743 ret[name] = sas_objs.get(name)
1744 if len(ret) != 1:
1745 return {'result': False,
1746 'Error': "Error in the retrieving service apliance set."}
1747 return ret
1748
1749
1750def service_appliance_set_create(name, properties=None, driver=None, ha_mode=None, **kwargs):
1751 '''
1752 Create Contrail service appliance set
1753
1754 CLI Example:
1755
1756 .. code-block:: bash
1757
1758 salt '*' contrail.service_appliance_set_create name
1759 '''
1760 ret = {'name': name,
1761 'changes': {},
1762 'result': True,
1763 'comment': ''}
1764 vnc_client = _auth(**kwargs)
1765 gsc_obj = _get_config(vnc_client)
1766 sas_objs = service_appliance_set_list(**kwargs)
1767 if name in sas_objs:
1768 ret['commnet'] = 'Service appliance set ' + name + ' already exists'
1769 else:
1770 service_appliance_set_obj = ServiceApplianceSet(
1771 name, gsc_obj)
1772 if properties:
1773 pairs = KeyValuePairs()
1774 for k, v in properties.items():
1775 pairs.add_key_value_pair(KeyValuePair(k, v))
1776 service_appliance_set_obj.set_service_appliance_set_properties(pairs)
1777 if driver:
1778 service_appliance_set_obj.set_service_appliance_driver(driver)
1779 if ha_mode:
1780 service_appliance_set_obj.set_service_appliance_ha_mode(ha_mode)
1781 if __opts__['test']:
1782 ret['result'] = None
1783 ret['comment'] = "ServiceApplianceSet " + name + " will be created"
1784 else:
1785 vnc_client.service_appliance_set_create(service_appliance_set_obj)
1786 ret['comment'] = "ServiceApplianceSet " + name + " has been created"
1787 ret['changes'] = {'ServiceApplianceSet': {'old': '', 'new': name}}
1788 return ret
1789
1790
1791def service_appliance_set_delete(name, **kwargs):
1792 '''
1793 Delete specific Contrail service appliance set
1794
1795 CLI Example:
1796
1797 .. code-block:: bash
1798
1799 salt '*' contrail.service_appliance_set_delete name
1800 '''
1801 ret = {'name': name,
1802 'changes': {},
1803 'result': True,
1804 'comment': ''}
1805 vnc_client = _auth(**kwargs)
1806 gsc_obj = _get_config(vnc_client)
1807 sas_obj = ServiceApplianceSet(name, gsc_obj)
1808 if __opts__['test']:
1809 ret['result'] = None
1810 ret['comment'] = "Service appliance set " + name + " will be deleted"
1811 else:
1812 vnc_client.service_appliance_set_delete(fq_name=sas_obj.get_fq_name())
1813 ret['comment'] = "ServiceApplianceSet " + name + " has been deleted"
1814 ret['changes'] = {'ServiceApplianceSet': {'old': name, 'new': ''}}
1815 return ret
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +01001816
1817def global_system_config_list(**kwargs):
1818 '''
1819 Return a list of all global system configs
1820
1821 CLI Example:
1822
1823 .. code-block:: bash
1824
1825 salt '*' contrail.global_system_config_list
1826 '''
1827
1828 ret = {}
1829 vnc_client = _auth(**kwargs)
1830 gsysconfs = vnc_client._objects_list('global-system-config', detail=True)
1831 for gsysconf in gsysconfs:
1832 ret[gsysconf.name] = gsysconf.__dict__
1833 return ret
1834
1835
1836def global_system_config_get(name, **kwargs):
1837 '''
1838 Return a specific Contrail global system config
1839
1840 CLI Example:
1841
1842 .. code-block:: bash
1843
1844 salt '*' contrail.global_system_config_get name
1845 '''
1846 ret = {}
1847 vnc_client = _auth(**kwargs)
1848 gsc_objs = vnc_client._objects_list('global-system-config', detail=True)
1849 for gsc_obj in gsc_objs:
1850 if name == gsc_obj.name:
1851 ret[name] = gsc_obj.__dict__
1852 if len(ret) == 0:
1853 return {'Error': 'Error in retrieving global system config.'}
1854 return ret
1855
1856
1857def global_system_config_create(name, ans=64512, grp=None, **kwargs):
1858 '''
1859 Create Contrail global system config
1860
1861 CLI Example:
1862
1863 .. code-block:: bash
1864
1865 salt '*' contrail.global_system_config_create name=default-global-system-config ans=64512
1866 '''
1867 ret = {'name': name,
1868 'changes': {},
1869 'result': True,
1870 'comment': ''}
1871 vnc_client = _auth(**kwargs)
1872
1873 gsc_objs = global_system_config_list(**kwargs)
1874 if name in gsc_objs:
1875 config_obj = vnc_client.global_system_config_read(fq_name=[name])
1876 if config_obj.graceful_restart_parameters and not HAS_OLD:
1877 curr_grp = str(config_obj.graceful_restart_parameters).replace(" ", "").split(",")
1878 curr_grpd = dict(item.split('=') for item in curr_grp)
psvimbersky3c84e272018-01-02 10:34:29 +01001879 else:
1880 curr_grpd = None
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +01001881
1882 if grp and 'enable' in grp and not HAS_OLD:
1883 grp_obj = GracefulRestartParametersType()
1884 if 'enable' in grp:
1885 grp_obj.enable = grp['enable']
1886 if curr_grpd and str(grp['enable']) != str(curr_grpd['enable']):
1887 ret['changes']['enable'] = {"from": str(curr_grpd['enable']), "to": str(grp['enable'])}
1888 elif not curr_grpd:
1889 ret['changes']['enable'] = {"from": None, "to": grp['enable']}
1890 if 'restart_time' in grp:
1891 grp_obj.restart_time = grp['restart_time']
1892 if curr_grpd and grp['restart_time'] != int(curr_grpd['restart_time']):
1893 ret['changes']['restart_time'] = {"from": int(curr_grpd['restart_time']), "to": grp['restart_time']}
1894 elif not curr_grpd:
1895 ret['changes']['restart_time'] = {"from": None, "to": grp['restart_time']}
1896 if 'end_of_rib_timeout' in grp:
1897 grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout']
1898 if curr_grpd and grp['end_of_rib_timeout'] != int(curr_grpd['end_of_rib_timeout']):
1899 ret['changes']['end_of_rib_timeout'] = {"from": int(curr_grpd['end_of_rib_timeout']), "to": grp['end_of_rib_timeout']}
1900 elif not curr_grpd:
1901 ret['changes']['end_of_rib_timeout'] = {"from": None, "to": grp['end_of_rib_timeout']}
1902 if 'bgp_helper_enable' in grp:
1903 grp_obj.bgp_helper_enable = grp['bgp_helper_enable']
1904 if curr_grpd and str(grp['bgp_helper_enable']) != str(curr_grpd['bgp_helper_enable']):
1905 ret['changes']['bgp_helper_enable'] = {"from": str(curr_grpd['bgp_helper_enable']), "to": grp['bgp_helper_enable']}
1906 elif not curr_grpd:
1907 ret['changes']['bgp_helper_enable'] = {"from": None, "to": grp['bgp_helper_enable']}
1908 if 'xmpp_helper_enable' in grp:
1909 grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable']
1910 if curr_grpd and str(grp['xmpp_helper_enable']) != str(curr_grpd['xmpp_helper_enable']):
1911 ret['changes']['xmpp_helper_enable'] = {"from": str(curr_grpd['xmpp_helper_enable']), "to": grp['xmpp_helper_enable']}
1912 elif not curr_grpd:
1913 ret['changes']['xmpp_helper_enable'] = {"from": None, "to": grp['xmpp_helper_enable']}
1914 if 'long_lived_restart_time' in grp:
1915 grp_obj.long_lived_restart_time = grp['long_lived_restart_time']
1916 if curr_grpd and grp['long_lived_restart_time'] != int(curr_grpd['long_lived_restart_time']):
1917 ret['changes']['long_lived_restart_time'] = {"from": int(curr_grpd['long_lived_restart_time']), "to": grp['long_lived_restart_time']}
1918 elif not curr_grpd:
1919 ret['changes']['long_lived_restart_time'] = {"from": None, "to": grp['long_lived_restart_time']}
1920 else:
1921 grp_obj = None
1922
1923 config_obj.graceful_restart_parameters = grp_obj
1924
1925 if ans:
1926 if config_obj.autonomous_system != ans:
1927 ret['changes']['autonomous_system'] = {"from": config_obj.autonomous_system, "to": ans}
1928 config_obj.autonomous_system = ans
1929
1930 vnc_client.global_system_config_update(config_obj)
1931 ret['comment'] = 'Global system config ' + name + ' has been updated'
1932 else:
1933 config_obj = GlobalSystemConfig(name=name)
1934 if grp and not HAS_OLD:
1935 grp_obj = GracefulRestartParametersType()
1936 if 'enable' in grp:
1937 grp_obj.enable = grp['enable']
1938 if 'restart_time' in grp:
1939 grp_obj.restart_time = grp['restart_time']
1940 if 'end_of_rib_timeout' in grp:
1941 grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout']
1942 if 'bgp_helper_enable' in grp:
1943 grp_obj.bgp_helper_enable = grp['bgp_helper_enable']
1944 if 'xmpp_helper_enable' in grp:
1945 grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable']
1946 if 'long_lived_restart_time' in grp:
1947 grp_obj.long_lived_restart_time = grp['long_lived_restart_time']
1948 config_obj.graceful_restart_parameters = grp_obj
1949 if ans:
1950 config_obj.autonomous_system = ans
1951
1952 vnc_client.global_system_config_create(config_obj)
1953 ret['changes'] = {"created": "new"}
1954 ret['comment'] = 'Global system config ' + name + ' has been created '
1955
1956 return ret
1957
1958
1959def global_system_config_delete(name, **kwargs):
1960 '''
1961 Delete specific Contrail global system config
1962
1963 CLI Example:
1964
1965 .. code-block:: bash
1966
1967 salt '*' contrail.global_system_config_delete name
1968 '''
1969 ret = {'name': name,
1970 'changes': {},
1971 'result': True,
1972 'comment': ''}
1973 vnc_client = _auth(**kwargs)
1974
1975 gsc_obj = GlobalSystemConfig(name)
1976 if __opts__['test']:
1977 ret['result'] = None
1978 ret['comment'] = "Global system config " + name + " will be deleted"
1979 else:
1980 vnc_client.global_system_config_delete(fq_name=gsc_obj.get_fq_name())
1981 ret['comment'] = "GlobalSystemConfig " + name + " has been deleted"
1982 ret['changes'] = {'GlobalSystemConfig': {'old': name, 'new': ''}}
1983 return ret
Jan Cachb3092722018-01-31 12:46:16 +01001984
1985
1986def list_floating_ip_pools(**kwargs):
1987 '''
1988 List all floating ip pools
1989
1990 CLI Example:
1991 .. code-block:: bash
1992 salt '*' contrail.list_floating_ip_pools
1993 '''
1994 vnc_client = _auth(**kwargs)
1995 pools = vnc_client.floating_ip_pools_list()
1996 # list of floating ip pools objects
1997 fp_list = []
1998
1999 for pool in vnc_client.floating_ip_pools_list()['floating-ip-pools']:
2000 fip_obj = vnc_client.floating_ip_pool_read(pool['fq_name'])
2001 fp_list.append(fip_obj)
2002 # print given pool
2003 fip_obj.dump()
2004
2005def update_floating_ip_pool(vn_name, vn_project, vn_domain=None,
2006 owner_access=None, global_access=None,
2007 projects=None, **kwargs):
2008 '''
2009 Update specific floating ip pool
2010
2011
2012 CLI Example
2013 .. code-block:: bash
2014 salt-call contrail.update_floating_ip_pool \
2015 'FLOATING-TEST' \
2016 'admin' \
2017 'default-domain' \
2018 7 7 \
2019 [['pepa',4],['karel',7]]
2020
2021
2022 params:
2023 vn_name - name of the virtual network, which to use
2024 vn-project - project which includes virtual network
2025 vn-domain - domain wchich includes vn_project and vn_name
2026 owner_access (int) - Permission rights for owner
2027 global_access (int) - Permission rights for others
2028 projects (list) - list of ShareType(tenant_name,tennat_permissions)
2029 '''
2030 ret = {'name': vn_name + "-default pool",
2031 'changes': {},
2032 'result': True,
2033 'comment': ''}
2034
2035 if vn_domain is None:
2036 vn_domain = 'default-domain'
2037 fip_obj = None
2038
2039 vnc_client = _auth(**kwargs)
2040 p_fq_name = [vn_domain, vn_project, vn_name, 'default']
2041 fip_obj = vnc_client.floating_ip_pool_read(fq_name=p_fq_name)
2042
2043 changes = {}
2044 # get perms from fip_obj (Floatin ip pool)
2045 perms2 = fip_obj.get_perms2()
2046 if owner_access is not None:
2047 if perms2.get_owner_access() != owner_access:
2048 changes['owner_access'] = {'old': str(perms2.get_owner_access()),
2049 'new': str(owner_access)}
2050 perms2.set_owner_access(owner_access)
2051
2052 if global_access is not None:
2053 if perms2.get_global_access() != global_access:
2054 changes['global_access'] = {'old': str(perms2.get_global_access()),
2055 'new': str(global_access)}
2056 perms2.set_global_access(global_access)
2057
2058 # list which represents the new state of perms
2059 final_list = []
2060 if projects:
2061 for item in perms2.get_share():
2062 for share in projects:
2063 if item.get_tenant() == share[0]:
2064 # project is in the new and old list
2065 # check is the permission number is same
2066 if item.get_tenant_access() == share[1]:
2067 # this project and permission is without change, keep it
2068 final_list.append(item)
2069 break
2070 else:
2071 # project exists but change the permission
2072 final_list.append(ShareType(tenant=share[0],
2073 tenant_access=share[1]))
2074 # show changes
2075 n = str('share-'+share[0])
2076 old_str = "permission for project {0} was {1}"
2077 new_str = "permission for project {0} will be {1}"
2078 old = old_str.format(share[0],
2079 str(item.get_tenant_access()))
2080
2081 new = new_str.format(share[0], str(share[1]))
2082 changes[n] = {'old': old, 'new': new}
2083 break
2084 else:
2085 rm_name = "share-" + item.get_tenant()
2086 changes[rm_name] = item.get_tenant() + " will be removed"
2087
2088 # check for the completly new projects
2089 for item in projects:
2090 for share in final_list:
2091 if item[0] == share.get_tenant():
2092 break
2093 else:
2094 final_list.append(ShareType(tenant=item[0],
2095 tenant_access=item[1]))
2096 name = 'share-' + str(item[0])
2097 c_str = '{0} will be added with permissions {1}'
2098 changes[name] = c_str.format(name, item[1])
2099 else:
2100 for item in perms2.get_share():
2101 rm_name = "share-" + item.get_tenant()
2102 changes[rm_name] = item.get_tenant() + " will be removed"
2103
2104 if __opts__['test']:
2105 ret['result'] = None
2106 ret['comment'] = changes
2107
2108 return ret
2109 else:
2110 ret['comment'] = changes
2111 perms2.set_share(final_list)
2112 fip_obj.set_perms2(perms2)
2113 vnc_client.floating_ip_pool_update(fip_obj)
2114
2115 return ret
Sergey Matov16896ac2018-02-15 15:46:31 +04002116
2117
2118def show_rbac_rules(api_access_list_entries):
2119 if api_access_list_entries is None:
2120 return 'Empty RBAC group!'
2121
2122 rule_list = api_access_list_entries.get_rbac_rule()
2123 response = 'Rules (%d):' % len(rule_list) + '----------\n'
2124 for idx, rule in enumerate(rule_list):
2125 o = rule.rule_object
2126 f = rule.rule_field
2127 ps = ', '.join([p.role_name+':'+p.role_crud for p in rule.rule_perms])
2128 o_f = "%s.%s" % (o, f) if f else o
2129 response += '%2d %-32s %s\n' % (idx, o_f, ps)
2130 return response
2131
2132
2133def vnc_read_obj(vnc, obj_type, fq_name):
2134 method_name = obj_type.replace('-', '_')
2135 method = getattr(vnc, "%s_read" % (method_name))
2136 try:
2137 return method(fq_name=fq_name)
2138 except NoIdError:
2139 print '%s %s not found!' % (obj_type, fq_name)
2140 return None
2141
2142
2143def rbac_show_group(name, uuid, **kwargs):
2144 '''
2145 Show specific RBAC group
2146
2147
2148 CLI Example
2149 .. code-block:: bash
2150 salt-call contrail.rbac_show_group name \
2151 'default-domain:default-project:default'
2152
2153 params:
2154 name - one of pair {name, uuid} addresing to access-list
2155 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2156 including domain and project
2157
2158 '''
2159 vnc = _auth(**kwargs)
2160 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2161 ret = {'name': fq_name,
2162 'changes': {},
2163 'result': True,
2164 'comment': ''}
2165 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2166 if not rg:
2167 ret['comment'] = 'No rules found'
2168 return ret
2169
2170 ret['comment'] = show_rbac_rules(rg.get_api_access_list_entries())
2171 return ret
2172
2173
2174def rbac_create_group(uuid, **kwargs):
2175 '''
2176 Create RBAC group
2177
2178 CLI Example
2179 .. code-block:: bash
2180 salt-call contrail.rbac_create_group name \
2181 'default-domain:default-project:default'
2182
2183 params:
2184 name - one of pair {name, uuid} addresing to access-list
2185 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2186 including domain and project
2187
2188 '''
2189 vnc = _auth(**kwargs)
2190 fq_name = uuid.split(':')
2191 ret = {'name': fq_name,
2192 'changes': {},
2193 'result': True,
2194 'comment': ''}
2195 if len(fq_name) != 2 and len(fq_name) != 3:
2196 ret['comment'] = 'Fully qualified name of rbac group expected'
2197 return ret
2198
2199 name = fq_name[-1]
2200
2201 if len(fq_name) == 2:
2202 if fq_name[0] == 'default-global-system-config':
2203 pobj = vnc.global_system_config_read(fq_name=fq_name[0:1])
2204 else:
2205 pobj = vnc.domain_read(fq_name=fq_name[0:1])
2206 else:
2207 pobj = vnc.project_read(fq_name=fq_name[0:2])
2208
2209 rentry = RbacRuleEntriesType([])
2210 rg = ApiAccessList(name, parent_obj=pobj, api_access_list_entries=rentry)
2211
2212 if __opts__['test']:
2213 ret['result'] = None
2214 ret['comment'] = "RBAC group " + uuid + " will be created"
2215
2216 return ret
2217 else:
2218 vnc.api_access_list_create(rg)
2219 rg2 = vnc.api_access_list_read(fq_name=fq_name)
2220 rge = rg.get_api_access_list_entries()
2221 show_rbac_rules(rge)
2222 ret['comment'] = "RBAC group " + uuid + " has been created"
2223
2224 return ret
2225
2226
2227def rbac_delete_group(name, uuid, **kwargs):
2228 '''
2229 Delete RBAC group
2230
2231 CLI Example
2232 .. code-block:: bash
2233 salt-call contrail.rbac_delete_group name \
2234 'default-domain:default-project:default'
2235
2236 params:
2237 name - one of pair {name, uuid} addresing to access-list
2238 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2239 including domain and project
2240
2241 '''
2242 vnc = _auth(**kwargs)
2243 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2244 ret = {'name': fq_name,
2245 'changes': {},
2246 'result': True,
2247 'comment': ''}
2248 if len(fq_name) != 2 and len(fq_name) != 3:
2249 ret['comment'] = 'Fully qualified name of rbac group expected'
2250 return ret
2251 name = fq_name[-1]
2252
2253 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2254 if not rg:
2255 ret['comment'] = 'No rules found'
2256 return ret
2257 rge = rg.get_api_access_list_entries()
2258 show_rbac_rules(rge)
2259
2260 if __opts__['test']:
2261 ret['result'] = None
2262 ret['comment'] = "RBAC group " + uuid + " will be deleted"
2263
2264 return ret
2265 else:
2266 vnc.api_access_list_delete(fq_name=fq_name)
2267 ret['comment'] = "RBAC group " + uuid + " has been deleted"
2268
2269 return ret
2270
2271
2272def rbac_add_rule(name, uuid, add_rule, **kwargs):
2273 '''
2274 Add rule to specific RBAC group
2275
2276 CLI Example
2277 .. code-block:: bash
2278 salt-call contrail.rbac_add_rule name \
2279 'default-domain:default-project:default' \
2280 '* admin:CRUD'
2281
2282 params:
2283 name - one of pair {name, uuid} addresing to access-list
2284 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2285 including domain and project
2286 rule(str) - Appropriate RBAC-based rule in format '<object, field> \
2287 list of <role:CRUD>' to be added
2288
2289 '''
2290 vnc = _auth(**kwargs)
2291 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2292 rule = build_rule(add_rule)
2293 ret = {'name': fq_name,
2294 'changes': {},
2295 'result': True,
2296 'comment': ''}
2297 if rule is None:
2298 ret['comment'] = 'A rule string must be specified for this operation'
2299 return ret
2300
2301 # rbac rule entry consists of one or more rules
2302 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2303 if not rg:
2304 ret['comment'] = 'No rules found'
2305 return ret
2306
2307 rge = rg.get_api_access_list_entries()
2308 if rge is None:
2309 rge = RbacRuleEntriesType([])
2310 show_rbac_rules(rge)
2311
2312 # avoid duplicates
2313 match = find_rule(rge, rule)
2314 if not match:
2315 rge.add_rbac_rule(rule)
2316 else:
2317 build_perms(rge.rbac_rule[match[0]-1], match[3])
2318
2319 show_rbac_rules(rge)
2320
2321 if __opts__['test']:
2322 ret['result'] = None
2323 ret['comment'] = "Rule " + add_rule
2324 ret['comment'] += " will be created for RBAC group " + uuid
2325
2326 return ret
2327 else:
2328 rg.set_api_access_list_entries(rge)
2329 vnc.api_access_list_update(rg)
2330 ret['comment'] = "Rule " + add_rule
2331 ret['comment'] += " has been added for RBAC group " + uuid
2332
2333 return ret
2334
2335
2336def rbac_delete_rule(name, uuid, del_rule, **kwargs):
2337 '''
2338 Delete rule to specific RBAC group
2339
2340 CLI Example
2341 .. code-block:: bash
2342 salt-call contrail.rbac_delete_rule name \
2343 'default-domain:default-project:default' \
2344 '* admin:CRUD'
2345
2346 params:
2347 name - one of pair {name, uuid} addresing to access-list
2348 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2349 including domain and project
2350 rule(str) - Appropriate RBAC-based rule in format '<object, field> \
2351 list of <role:CRUD>' to be deleted
2352
2353 '''
2354 vnc = _auth(**kwargs)
2355 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2356 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2357 ret = {'name': fq_name,
2358 'changes': {},
2359 'result': True,
2360 'comment': ''}
2361 if not rg:
2362 ret['comment'] = 'No rules found'
2363 return ret
2364 rge = rg.get_api_access_list_entries()
2365 show_rbac_rules(rge)
2366
2367 del_idx = re.match("^[0-9]+$", del_rule)
2368 if del_idx:
2369 del_idx = int(del_idx.group())
2370 rc = len(rge.rbac_rule)
2371 if del_idx > rc or del_idx < 1:
2372 ret['comment'] = 'Invalid rule index to delete.'
2373 ret['comment'] += 'Value must be 1-%d' % rc
2374 return ret
2375 match = (del_idx, True)
2376 else:
2377 rule = build_rule(del_rule)
2378 match = find_rule(rge, rule)
2379
2380 if not match:
2381 ret['comment'] = "Rule not found. Unchanged"
2382 return ret
2383 elif match[1]:
2384 rge.rbac_rule.pop(match[0]-1)
2385 else:
2386 build_perms(rge.rbac_rule[match[0]-1], match[2])
2387 show_rbac_rules(rge)
2388
2389 if __opts__['test']:
2390 ret['result'] = None
2391 ret['comment'] = "Rule " + del_rule
2392 ret['comment'] += " will be cleared from RBAC group " + uuid
2393
2394 return ret
2395 else:
2396 rg.set_api_access_list_entries(rge)
2397 vnc.api_access_list_update(rg)
2398 ret['comment'] = "Rule " + del_rule
2399 ret['comment'] += " has been cleared from RBAC group " + uuid
2400
2401 return ret