blob: 694f02423aa92d3c0ab9472d473f37bf5bf94950 [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')
Anton Samoylov72575c22019-06-07 20:26:44 +040073 use_ssl = kwargs.get('api_server_use_ssl')
Ales Komarekad46d2e2017-03-09 17:16:38 +010074 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
Ales Komarekad46d2e2017-03-09 17:16:38 +0100119def virtual_router_list(**kwargs):
120 '''
121 Return a list of all Contrail virtual routers
122
123 CLI Example:
124
125 .. code-block:: bash
126
127 salt '*' contrail.virtual_router_list
128 '''
129 ret = {}
130 vnc_client = _auth(**kwargs)
131 vrouter_objs = vnc_client._objects_list('virtual-router', detail=True)
132 for vrouter_obj in vrouter_objs:
133 ret[vrouter_obj.name] = {
134 'ip_address': vrouter_obj.virtual_router_ip_address,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200135 'dpdk_enabled': vrouter_obj.virtual_router_dpdk_enabled,
136 'uuid': vrouter_obj.uuid
137
Ales Komarekad46d2e2017-03-09 17:16:38 +0100138 }
139 return ret
140
141
142def virtual_router_get(name, **kwargs):
143 '''
144 Return a specific Contrail virtual router
145
146 CLI Example:
147
148 .. code-block:: bash
149
150 salt '*' contrail.virtual_router_get cmp01
151 '''
152 ret = {}
153 vrouter_objs = virtual_router_list(**kwargs)
154 if name in vrouter_objs:
155 ret[name] = vrouter_objs.get(name)
156 if len(ret) == 0:
157 return {'Error': 'Error in retrieving virtual router.'}
158 return ret
159
160
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200161def virtual_router_create(name, ip_address, router_type=None, dpdk_enabled=False, **kwargs):
Ales Komarekad46d2e2017-03-09 17:16:38 +0100162 '''
163 Create specific Contrail virtual router
164
165 CLI Example:
166
167 .. code-block:: bash
168
169 salt '*' contrail.virtual_router_create cmp02 10.10.10.102
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200170 router_types:
171 - tor-agent
172 - tor-service-node
173 - embedded
Ales Komarekad46d2e2017-03-09 17:16:38 +0100174 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200175 ret = {'name': name,
176 'changes': {},
177 'result': True,
178 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100179 vnc_client = _auth(**kwargs)
180 gsc_obj = _get_config(vnc_client)
181 vrouter_objs = virtual_router_list(**kwargs)
Pavel Svimberskya3140552017-08-28 16:55:44 +0200182 router_types = ['tor-agent', 'tor-service-node', 'embedded']
183 if router_type not in router_types:
184 router_type = None
Ales Komarekad46d2e2017-03-09 17:16:38 +0100185 if name in vrouter_objs:
Anton Samoylov72575c22019-06-07 20:26:44 +0400186 vrouter = virtual_router_get(name, **kwargs)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200187 vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[name]['uuid'])
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200188 changes = {}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200189 if vrouter_obj.get_virtual_router_ip_address() != ip_address:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200190 changes['ip_address'] = {'from': vrouter_obj.get_virtual_router_ip_address(), "to": ip_address}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200191 vrouter_obj.set_virtual_router_ip_address(ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200192 if vrouter_obj.get_virtual_router_type() != router_type:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200193 changes['router_type'] = {"from": vrouter_obj.get_virtual_router_type(), "to": router_type}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200194 vrouter_obj.set_virtual_router_type(router_type)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200195 if vrouter_obj.get_virtual_router_dpdk_enabled() != dpdk_enabled:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200196 changes['dpdk_enabled'] = {"from": vrouter_obj.get_virtual_router_dpdk_enabled(), "to": dpdk_enabled}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200197 vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200198 if len(changes) != 0:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200199 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200200 ret['result'] = None
201 ret['comment'] = "Virtual router " + name + " will be updated"
202 else:
203 ret['comment'] = "VirtualRouter " + name + " has been updated"
204 ret['changes'] = changes
205 vnc_client.virtual_router_update(vrouter_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200206 return ret
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200207 ret['comment'] = 'Virtual router ' + name + ' already exists and is updated'
208 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100209 else:
210 vrouter_obj = VirtualRouter(
211 name, gsc_obj,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200212 virtual_router_ip_address=ip_address,
213 virtual_router_type=router_type)
Ales Komarekad46d2e2017-03-09 17:16:38 +0100214 vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200215 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200216 ret['result'] = None
217 ret['comment'] = "VirtualRouter " + name + " will be created"
218 else:
219 vnc_client.virtual_router_create(vrouter_obj)
220 ret['comment'] = "VirtualRouter " + name + " has been created"
221 ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}}
222 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100223
224
225def virtual_router_delete(name, **kwargs):
226 '''
227 Delete specific Contrail virtual router
228
229 CLI Example:
230
231 .. code-block:: bash
232
233 salt '*' contrail.virtual_router_delete cmp01
234 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200235 ret = {'name': name,
236 'changes': {},
237 'result': True,
238 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100239 vnc_client = _auth(**kwargs)
240 gsc_obj = _get_config(vnc_client)
241 vrouter_obj = VirtualRouter(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200242 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200243 ret['result'] = None
244 ret['comment'] = "VirtualRouter " + name + " will be deleted"
245 else:
246 vnc_client.virtual_router_delete(fq_name=vrouter_obj.get_fq_name())
247 ret['comment'] = "VirtualRouter " + name + " has been deleted"
248 ret['changes'] = {'VirtualRouter': {'old': name, 'new': ''}}
249 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200250
251
252def physical_router_list(**kwargs):
253 '''
254 Return a list of all Contrail physical routers
255
256 CLI Example:
257
258 .. code-block:: bash
259
260 salt '*' contrail.physical_router_list
261 '''
262 ret = {}
263 vnc_client = _auth(**kwargs)
264 prouter_objs = vnc_client._objects_list('physical-router', detail=True)
265 for prouter_obj in prouter_objs:
266 ret[prouter_obj.name] = {
267 'uuid': prouter_obj._uuid,
268 'management_ip': prouter_obj._physical_router_management_ip,
269 'product_name': prouter_obj._physical_router_product_name,
270 }
271
272 return ret
273
274
275def physical_router_get(name, **kwargs):
276 '''
277 Return a specific Contrail physical router
278
279 CLI Example:
280
281 .. code-block:: bash
282
283 salt '*' contrail.physical_router_get router_name
284 '''
285 ret = {}
286 vnc_client = _auth(**kwargs)
287 prouter_objs = vnc_client._objects_list('physical-router', detail=True)
288 for prouter_obj in prouter_objs:
289 if name == prouter_obj.name:
290 ret[name] = prouter_obj.__dict__
291 if len(ret) == 0:
292 return {'Error': 'Error in retrieving physical router.'}
293 return ret
294
295
296def physical_router_create(name, parent_type=None,
297 management_ip=None,
298 dataplane_ip=None, # VTEP address in web GUI
299 vendor_name=None,
300 product_name=None,
301 vnc_managed=None,
302 junos_service_ports=None,
303 agents=None, **kwargs):
304 '''
305 Create specific Contrail physical router
306
307 CLI Example:
308
309 .. code-block:: bash
310
311 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']"
312 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200313 ret = {'name': name,
314 'changes': {},
315 'result': True,
316 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200317 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200318 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200319 prouter_objs = physical_router_list(**kwargs)
320 if name in prouter_objs:
321 prouter = physical_router_get(name)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200322 changes = {}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200323 prouter_obj = vnc_client._object_read('physical-router', id=prouter[name]['_uuid'])
324 if prouter_obj.physical_router_management_ip != management_ip:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200325 changes['management_ip'] = {'from': prouter_obj.physical_router_management_ip, "to": management_ip}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200326 prouter_obj.set_physical_router_management_ip(management_ip)
327 if prouter_obj.physical_router_dataplane_ip != dataplane_ip:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200328 changes['dataplane_ip'] = {'from': prouter_obj.physical_router_dataplane_ip, "to": dataplane_ip}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200329 prouter_obj.set_physical_router_dataplane_ip(dataplane_ip)
330 if prouter_obj.get_physical_router_vendor_name() != vendor_name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200331 changes['vendor_name'] = {'from': prouter_obj.get_physical_router_vendor_name(), "to": vendor_name}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200332 prouter_obj.set_physical_router_vendor_name(vendor_name)
333 if prouter_obj.get_physical_router_product_name() != product_name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200334 changes['product_name'] = {'from': prouter_obj.get_physical_router_product_name(), "to": product_name}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200335 prouter_obj.set_physical_router_product_name(product_name)
336 if prouter_obj.get_physical_router_vnc_managed() != vnc_managed:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200337 changes['vnc_managed'] = {'from': prouter_obj.get_physical_router_vnc_managed(), "to": vnc_managed}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200338 prouter_obj.set_physical_router_vnc_managed(vnc_managed)
339 if prouter_obj.get_physical_router_junos_service_ports() != junos_service_ports:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200340 changes['junos_service_ports'] = {'from': prouter_obj.get_physical_router_junos_service_ports(),
341 'to': junos_service_ports}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200342 prouter_obj.set_physical_router_junos_service_ports(junos_service_ports)
343
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200344 if len(changes) != 0:
345 if __opts__['test']:
346 ret['result'] = None
347 ret['comment'] = "Physical router " + name + " will be updated"
348 else:
349 ret['comment'] = 'Physical router ' + name + ' already exists and is updated'
350 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200351
352 vrouter_objs = vnc_client._objects_list('virtual-router', detail=True) # all vrouter objects
353 c_agents = [] # referenced vrouters
354 for c_agent in prouter_obj.get_virtual_router_refs():
355 c_agents.append(c_agent['uuid'])
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200356 # agent_objs = [] # required state of references
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200357 for vrouter_obj in vrouter_objs:
358 if vrouter_obj._display_name in agents and vrouter_obj._uuid not in c_agents:
359 prouter_obj.add_virtual_router(vrouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200360 changes['vrouter ' + vrouter_obj._display_name] = "Reference added"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200361 if vrouter_obj._display_name not in agents and vrouter_obj._uuid in c_agents:
362 prouter_obj.del_virtual_router(vrouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200363 changes['vrouter ' + vrouter_obj._display_name] = "Reference removed"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200364 vnc_client.physical_router_update(prouter_obj)
365
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200366 if __opts__['test']:
367 ret['result'] = None
368 ret['comment'] = "VirtualRouter " + name + " will be created"
369 else:
370 vnc_client.virtual_router_create(vrouter_obj)
371 ret['comment'] = "VirtualRouter " + name + " has been created"
372 ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}}
373
374 if len(changes) == 0:
375 ret['comment'] = "Physical router exists and is updated"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200376 return ret
377 else:
378 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200379 ret['result'] = None
380 ret['comment'] = "Physical router " + name + " will be created"
381 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200382 prouter_obj = PhysicalRouter(
383 name=name,
384 parent_obj=None,
385 physical_router_management_ip=management_ip,
386 physical_router_dataplane_ip=dataplane_ip,
387 physical_router_vendor_name=vendor_name,
388 physical_router_product_name=product_name,
389 physical_router_vnc_managed=vnc_managed,
390 physical_router_junos_service_ports=junos_service_ports,
391 )
392 for agent in agents:
393 vrouter = virtual_router_get(agent)
394 vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[agent]['uuid'])
395 prouter_obj.add_virtual_router(vrouter_obj)
396 vnc_client.physical_router_create(prouter_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200397 ret['comment'] = "Physical router " + name + " has been created"
398 ret['changes'] = {'PhysicalRouter': {'old': '', 'new': name}}
399 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200400
401
402def physical_router_delete(name, **kwargs):
403 '''
404 Delete specific Contrail physical router
405
406 CLI Example:
407
408 .. code-block:: bash
409
410 salt '*' contrail.physical_router_delete router_name
411 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200412 ret = {'name': name,
413 'changes': {},
414 'result': True,
415 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200416 vnc_client = _auth(**kwargs)
417 gsc_obj = _get_config(vnc_client)
418 prouter_obj = PhysicalRouter(name, gsc_obj)
419 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200420 ret['result'] = None
421 ret['comment'] = "Physical router " + name + " will be deleted"
422 else:
423 vnc_client.physical_router_delete(fq_name=prouter_obj.get_fq_name())
424 ret['comment'] = "Physical router " + name + " has been deleted"
425 ret['changes'] = {'Physical router': {'old': name, 'new': ''}}
426 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200427
428
429def physical_interface_list(**kwargs):
430 '''
431 Return a list of all Contrail physical interface
432
433 CLI Example:
434
435 .. code-block:: bash
436
437 salt '*' contrail.physical_interface_list
438 '''
439 ret = {}
440 vnc_client = _auth(**kwargs)
441 pinterface_objs = vnc_client._objects_list('physical-interface', detail=True)
442 for pinterface_obj in pinterface_objs:
443 ret[pinterface_obj.name] = {
444 'uuid': pinterface_obj._uuid,
445 'fq_name': pinterface_obj.fq_name,
446 'parent_type': pinterface_obj.parent_type,
447 }
448
449 return ret
450
451
452def physical_interface_get(name, physical_router, **kwargs):
453 '''
454 Return a specific Contrail physical interface
455
456 CLI Example:
457
458 .. code-block:: bash
459
460 salt '*' contrail.physical_interface_get interface_name physical_router_name
461 '''
462 ret = {}
463 vnc_client = _auth(**kwargs)
464 pinterf_objs = vnc_client._objects_list('physical-interface', detail=True)
465 for pinterf_obj in pinterf_objs:
466 if name == pinterf_obj.name and physical_router in pinterf_obj.fq_name:
467 ret[name] = pinterf_obj.__dict__
468 if len(ret) == 0:
469 return {'Error': 'Error in retrieving physical interface.'}
470 return ret
471
472
473def physical_interface_create(name, physical_router, **kwargs):
474 '''
475 Create specific Contrail physical interface
476
477 CLI Example:
478
479 .. code-block:: bash
480
481 salt '*' contrail.physical_interface_create ge-0/0/10 physical_router_name
482 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200483 ret = {'name': name,
484 'changes': {},
485 'result': True,
486 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200487 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200488 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200489 pinterf_obj = physical_interface_get(name, physical_router, **kwargs)
490 if 'Error' not in pinterf_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200491 ret['comment'] = 'Physical interface ' + name + ' on ' + physical_router + ' already exists'
492 return ret
493
494 if __opts__['test']:
495 ret['result'] = None
496 ret['comment'] = "Physical interface " + name + " will be created"
497 return ret
498
499 prouter = physical_router_get(physical_router)
500 prouter_obj = vnc_client._object_read('physical-router', id=prouter[physical_router]['_uuid'])
501 pinterf_obj = PhysicalInterface(name, prouter_obj)
502 vnc_client.physical_interface_create(pinterf_obj)
503 ret['comment'] = "Physical interface " + name + " has been created"
504 ret['changes'] = {'Physical interface': {'old': '', 'new': name}}
505 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200506
507
508def physical_interface_delete(name, physical_router, **kwargs):
509 '''
510 Delete specific Contrail physical interface
511
512 CLI Example:
513 .. code-block:: bash
514
515 salt '*' contrail.physical_interface_delete ge-0/0/0 phr01
516 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200517 ret = {'name': name,
518 'changes': {},
519 'result': True,
520 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200521 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200522 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200523 piface = physical_interface_get(name, physical_router)
524 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200525 ret['result'] = None
526 ret['comment'] = "Physical interface " + name + " will be deleted"
527 else:
528 vnc_client.physical_interface_delete(id=piface[name]['_uuid'])
529 ret['comment'] = "Physical router " + name + " has been deleted"
530 ret['changes'] = {'Physical router': {'old': name, 'new': ''}}
531 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200532
533
534def logical_interface_list(**kwargs):
535 '''
536 Return a list of all Contrail logical interfaces
537
538 CLI Example:
539
540 .. code-block:: bash
541
542 salt '*' contrail.logical_interface_list
543 '''
544 ret = []
545 vnc_client = _auth(**kwargs)
546 liface_objs = vnc_client._objects_list('logical-interface', detail=True)
547 for liface_obj in liface_objs:
548 ret.append({
549 'name': liface_obj.name,
550 'uuid': liface_obj._uuid,
551 'fq_name': liface_obj.fq_name,
552 'parent_type': liface_obj.parent_type,
553 })
554 return ret
555
556
557def logical_interface_get(name, parent_names, parent_type=None, **kwargs):
558 '''
559 Return a specific Contrail logical interface
560
561 CLI Example:
562
563 .. code-block:: bash
564
565 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01']
566 or
567 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['ge-0/0/0','phr01']
568 or
569 salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01'] parent_type=physcal-interface
570 '''
571 ret = {}
572 vnc_client = _auth(**kwargs)
573 liface_objs = vnc_client._objects_list('logical-interface', detail=True)
574 count = 0
575 for liface_obj in liface_objs:
576 if name == liface_obj.name and set(parent_names).issubset(liface_obj.fq_name):
577 if parent_type and parent_type == liface_obj.parent_type:
578 count += 1
579 ret[liface_obj.name] = liface_obj.__dict__
580 if not parent_type:
581 count += 1
582 ret[liface_obj.name] = liface_obj.__dict__
583 if len(ret) == 0:
584 return {'Error': 'Error in retrieving logical interface.'}
585 if count > 1:
586 return {
587 'Error': 'Error Was found more then one logical interface. Please put more parent_name or put parent_type to chose one of them.'}
588 return ret
589
590
591def logical_interface_create(name, parent_names, parent_type='physical-interface', vlan_tag=None, interface_type="l2",
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300592 vmis=None, **kwargs):
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200593 '''
594 Create specific Contrail logical interface
595
596 CLI Example:
597
598 .. code-block:: bash
599
600 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
601 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200602 ret = {'name': name,
603 'changes': {},
604 'result': True,
605 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200606 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200607 # gsc_obj = _get_config(vnc_client)
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300608
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200609 liface_obj = logical_interface_get(name, parent_names, parent_type, **kwargs)
610 if 'Error' not in liface_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200611 ret['comment'] = 'Logical interface ' + name + ' already exists'
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200612 else:
613 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200614 ret['result'] = None
615 ret['comment'] = "Logical interface " + name + " will be created"
616 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200617 parent_obj = None
618 for router in parent_names:
619 parent_router = physical_router_get(router)
620 if 'Error' not in parent_router:
621 parent_obj = vnc_client._object_read('physical-router', id=parent_router[router]['_uuid'])
622 break
623 if not parent_obj:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200624 ret['result'] = False
625 ret['comment'] = 'Physical router have to be defined'
626 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200627 if parent_type == 'physical-interface':
628 for interface in parent_names:
629 parent_interface = physical_interface_get(interface, parent_obj.name)
630 if 'Error' not in parent_interface:
631 parent_obj = vnc_client._object_read('physical-interface', id=parent_interface[interface]['_uuid'])
632 break
633 if interface_type.lower() == "l3":
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200634 ret['result'] = False
635 ret['comment'] = "Virtual Network have to be defined for L3 interface type"
636 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200637
638 liface_obj = LogicalInterface(name, parent_obj, vlan_tag, interface_type.lower())
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300639
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200640 if vmis:
641 for vmi_name, vmi in vmis.iteritems():
642 vmi = vnc_client.virtual_machine_interface_read(
643 fq_name=_get_fq_name(vnc_client, resource_name=vmi_name,
644 project_name=kwargs.get('tenant', 'admin')))
645 liface_obj.add_virtual_machine_interface(vmi)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200646 vnc_client.logical_interface_create(liface_obj)
Vasyl Saienkob10b7202017-09-05 14:19:03 +0300647
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200648 ret['comment'] = "Logical interface " + name + " has been created"
649 ret['changes'] = {'Logical interface': {'old': '', 'new': name}}
650 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200651
652
653def logical_interface_delete(name, parent_names, parent_type=None, **kwargs):
654 '''
655 Delete specific Contrail logical interface
656
657 CLI Example:
658
659 .. code-block:: bash
660
661 salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['ge-0/0/0','phr01']
662 or
663 salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['phr01'] parent_type=physical-router
664
665 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200666 ret = {'name': name,
667 'changes': {},
668 'result': True,
669 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200670 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200671 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200672 liface = logical_interface_get(name, parent_names, parent_type)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200673
674 if __opts__['test']:
675 ret['result'] = None
676 ret['comment'] = "Logical interface " + name + " will be deleted"
677 return ret
678 vnc_client.logical_interface_delete(id=liface[name]['_uuid'])
679 ret['comment'] = "Logical interface " + name + " has been deleted"
680 ret['changes'] = {'LogicalInterface ': {'old': name, 'new': ''}}
681 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200682
683
684def global_vrouter_config_list(**kwargs):
685 '''
686 Return a list of all Contrail global vrouter configs
687
688 CLI Example:
689
690 .. code-block:: bash"
691
692 salt '*' global_vrouter_config_list
693 '''
694 ret = {}
695 vnc_client = _auth(**kwargs)
696 vrouter_conf_objs = vnc_client._objects_list('global-vrouter-config', detail=True)
697 for vrouter_conf_obj in vrouter_conf_objs:
Anton Samoylovce3d7772018-11-23 00:00:02 +0400698 ret[vrouter_conf_obj.name] = vrouter_conf_obj.__dict__
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200699 return ret
700
701
702def global_vrouter_config_get(name, **kwargs):
703 '''
704 Return a specific Contrail global vrouter config
705
706 CLI Example:
707
708 .. code-block:: bash
709
710 salt '*' contrail.global_vrouter_get global-vrouter-config
711 '''
712 ret = {}
713 vrouter_conf_objs = global_vrouter_config_list(**kwargs)
714 if name in vrouter_conf_objs:
715 ret[name] = vrouter_conf_objs.get(name)
716 if len(ret) == 0:
717 return {'Error': 'Error in retrieving global vrouter config.'}
718 return ret
719
720
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +0100721def 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 +0200722 '''
723 Create specific Contrail global vrouter config
724
725 CLI Example:
726
727 .. code-block:: bash
728
Anton Samoylov02fb79b2019-04-15 12:42:54 +0400729 salt '*' contrail.global_vrouter_config_create \
730 name=global-vrouter-config parent_type=global-system-config \
731 encap_priority="MPLSoUDP,MPLSoGRE" vxlan_vn_id_mode="automatic" \
732 flow_export_rate=None \
733 fq_names="['default-global-system-config', 'default-global-vrouter-config']"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200734 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200735 ret = {'name': name,
736 'changes': {},
737 'result': True,
738 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200739 vnc_client = _auth(**kwargs)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200740 # gsc_obj = _get_config(vnc_client)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200741 vrouter_conf_objs = global_vrouter_config_list(**kwargs)
742 if name in vrouter_conf_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200743 ret['comment'] = 'Global vrouter config ' + name + ' already exists'
744 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200745 else:
746 vrouter_conf_obj = GlobalVrouterConfig(
747 name=name,
748 parent_obj=None,
749 encapsulation_priorities=EncapsulationPrioritiesType(encapsulation=encap_priority.split(",")),
750 fq_name=fq_names,
751 vxlan_network_identifier_mode=vxlan_vn_id_mode,
752 parent_type=parent_type,
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +0100753 flow_export_rate=flow_export_rate,
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200754 )
755 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200756 ret['result'] = None
757 ret['comment'] = "Global vRouter config " + name + " will be created"
758 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200759 vnc_client.global_vrouter_config_create(vrouter_conf_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200760 ret['comment'] = "Global vRouter config " + name + " has been created"
761 ret['changes'] = {'Global vRouter config': {'old': '', 'new': name}}
762 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200763
764
765def global_vrouter_config_delete(name, **kwargs):
766 '''
767 Delete specific Contrail global vrouter config
768
769 CLI Example:
770
771 .. code-block:: bash
772
773 salt '*' contrail.global_vrouter_config_delete global-vrouter-config
774 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200775 ret = {'name': name,
776 'changes': {},
777 'result': True,
778 'comment': ''}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200779 vnc_client = _auth(**kwargs)
780 gsc_obj = _get_config(vnc_client)
781 vrouter_conf_obj = GlobalVrouterConfig(name, gsc_obj)
782 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200783 ret['result'] = None
784 ret['comment'] = "Global vRouter config " + name + " will be deleted"
785 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200786 vnc_client.global_vrouter_config_delete(
787 fq_name=vrouter_conf_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200788 ret['comment'] = "Global vRouter config " + name + " has been deleted"
789 ret['changes'] = {'Global vRouter config': {'old': name, 'new': ''}}
790 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100791
792
793def analytics_node_list(**kwargs):
794 '''
795 Return a list of all Contrail analytics nodes
796
797 CLI Example:
798
799 .. code-block:: bash
800
801 salt '*' contrail.analytics_node_list
802 '''
803 ret = {}
804 vnc_client = _auth(**kwargs)
805 node_objs = vnc_client._objects_list('analytics-node', detail=True)
806 for node_obj in node_objs:
807 ret[node_obj.name] = node_obj.__dict__
808 return ret
809
810
811def analytics_node_get(name, **kwargs):
812 '''
813 Return a specific Contrail analytics node
814
815 CLI Example:
816
817 .. code-block:: bash
818
819 salt '*' contrail.analytics_node_get nal01
820 '''
821 ret = {}
822 vrouter_objs = analytics_node_list(**kwargs)
823 if name in vrouter_objs:
824 ret[name] = vrouter_objs.get(name)
825 if len(ret) == 0:
826 return {'Error': 'Error in retrieving analytics node.'}
827 return ret
828
829
830def analytics_node_create(name, ip_address, **kwargs):
831 '''
832 Create specific Contrail analytics node
833
834 CLI Example:
835
836 .. code-block:: bash
837
838 salt '*' contrail.analytics_node_create ntw03 10.10.10.103
839 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200840
841 ret = {'name': name,
842 'changes': {},
843 'result': True,
844 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100845 vnc_client = _auth(**kwargs)
846 gsc_obj = _get_config(vnc_client)
847 analytics_node_objs = analytics_node_list(**kwargs)
848 if name in analytics_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200849 ret['comment'] = 'Analytics node %s already exists'
850 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100851 else:
852 analytics_node_obj = AnalyticsNode(
853 name, gsc_obj,
854 analytics_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200855 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200856 ret['result'] = None
857 ret['comment'] = "AnalyticsNode " + name + " will be created"
858 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100859 vnc_client.analytics_node_create(analytics_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200860 ret['comment'] = "AnalyticsNode " + name + " has been created"
861 ret['changes'] = {'Analytics Node': {'old': '', 'new': name}}
862 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100863
864
865def analytics_node_delete(name, **kwargs):
866 '''
867 Delete specific Contrail analytics node
868
869 CLI Example:
870
871 .. code-block:: bash
872
873 salt '*' contrail.analytics_node_delete cmp01
874 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200875 ret = {'name': name,
876 'changes': {},
877 'result': True,
878 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100879 vnc_client = _auth(**kwargs)
880 gsc_obj = _get_config(vnc_client)
881 analytics_node_obj = AnalyticsNode(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200882 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200883 ret['result'] = None
884 ret['comment'] = "AnalyticsNode " + name + " will be deleted"
885 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100886 vnc_client.analytics_node_delete(
887 fq_name=analytics_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200888 ret['comment'] = "AnalyticsNode " + name + " has been deleted"
889 ret['changes'] = {'Analytics Node': {'old': name, 'new': ''}}
890 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100891
892
893def config_node_list(**kwargs):
894 '''
895 Return a list of all Contrail config nodes
896
897 CLI Example:
898
899 .. code-block:: bash
900
901 salt '*' contrail.config_node_list
902 '''
903 ret = {}
904 vnc_client = _auth(**kwargs)
905 node_objs = vnc_client._objects_list('config-node', detail=True)
906 for node_obj in node_objs:
907 ret[node_obj.name] = node_obj.__dict__
908 return ret
909
910
911def config_node_get(name, **kwargs):
912 '''
913 Return a specific Contrail config node
914
915 CLI Example:
916
917 .. code-block:: bash
918
919 salt '*' contrail.config_node_get nal01
920 '''
921 ret = {}
922 vrouter_objs = config_node_list(**kwargs)
923 if name in vrouter_objs:
924 ret[name] = vrouter_objs.get(name)
925 if len(ret) == 0:
926 return {'Error': 'Error in retrieving config node.'}
927 return ret
928
929
930def config_node_create(name, ip_address, **kwargs):
931 '''
932 Create specific Contrail config node
933
934 CLI Example:
935
936 .. code-block:: bash
937
938 salt '*' contrail.config_node_create ntw03 10.10.10.103
939 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200940 ret = {'name': name,
941 'changes': {},
942 'result': True,
943 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100944 vnc_client = _auth(**kwargs)
945 gsc_obj = _get_config(vnc_client)
946 config_node_objs = config_node_list(**kwargs)
947 if name in config_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200948 ret['comment'] = 'Config node ' + name + ' already exists'
949 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100950 else:
951 config_node_obj = ConfigNode(
952 name, gsc_obj,
953 config_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200954 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200955 ret['comment'] = "ConfigNode " + name + " will be created"
956 ret['result'] = None
957 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100958 vnc_client.config_node_create(config_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200959 ret['comment'] = "ConfigNode " + name + " has been created"
960 ret['changes'] = {'ConfigNode': {'old': '', 'new': name}}
961 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100962
963
964def config_node_delete(name, **kwargs):
965 '''
966 Delete specific Contrail config node
967
968 CLI Example:
969
970 .. code-block:: bash
971
972 salt '*' contrail.config_node_delete cmp01
973 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200974 ret = {'name': name,
975 'changes': {},
976 'result': True,
977 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +0100978 vnc_client = _auth(**kwargs)
979 gsc_obj = _get_config(vnc_client)
980 config_node_obj = ConfigNode(name, gsc_obj)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +0200981 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200982 ret['comment'] = "ConfigNode " + name + " will be deleted"
983 ret['result'] = None
984 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100985 vnc_client.config_node_delete(
986 fq_name=config_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +0200987 ret['comment'] = "ConfigNode " + name + " has been deleted"
988 ret['changes'] = {'ConfigNode': {'old': name, 'new': ''}}
989 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +0100990
991
992def bgp_router_list(**kwargs):
993 '''
994 Return a list of all Contrail BGP routers
995
996 CLI Example:
997
998 .. code-block:: bash
999
1000 salt '*' contrail.bgp_router_list
1001 '''
1002 ret = {}
1003 vnc_client = _auth(**kwargs)
1004 bgp_router_objs = vnc_client._objects_list('bgp-router', detail=True)
1005 for bgp_router_obj in bgp_router_objs:
1006 ret[bgp_router_obj.name] = bgp_router_obj.__dict__
1007 return ret
1008
1009
1010def bgp_router_get(name, **kwargs):
1011 '''
1012 Return a specific Contrail BGP router
1013
1014 CLI Example:
1015
1016 .. code-block:: bash
1017
1018 salt '*' contrail.bgp_router_get nal01
1019 '''
1020 ret = {}
1021 bgp_router_objs = bgp_router_list(**kwargs)
1022 if name in bgp_router_objs:
1023 ret[name] = bgp_router_objs.get(name)
1024 if len(ret) == 0:
1025 return {'Error': 'Error in retrieving BGP router.'}
1026 return ret
1027
1028
Marek Celoud3097e5b2018-01-09 13:52:14 +01001029def bgp_router_create(name, type, ip_address, asn=64512, key_type=None, key=None, **kwargs):
Ales Komarekad46d2e2017-03-09 17:16:38 +01001030 '''
1031 Create specific Contrail control node
1032
1033 CLI Example:
1034
1035 .. code-block:: bash
1036
1037 salt '*' contrail.bgp_router_create ntw03 control-node 10.10.10.103
1038 salt '*' contrail.bgp_router_create mx01 router 10.10.10.105
1039 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001040 ret = {'name': name,
1041 'changes': {},
1042 'result': True,
1043 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001044 vnc_client = _auth(**kwargs)
1045
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001046 address_families = ['route-target', 'inet-vpn', 'e-vpn', 'erm-vpn',
1047 'inet6-vpn']
1048 if type != 'control-node':
1049 address_families.remove('erm-vpn')
1050
Marek Celoud3097e5b2018-01-09 13:52:14 +01001051 key_type = None if key_type == 'None' else key_type
1052 key = None if key == 'None' else key
1053
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001054 bgp_addr_fams = AddressFamilies(address_families)
1055 bgp_sess_attrs = [
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001056 BgpSessionAttributes(address_families=bgp_addr_fams)]
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001057 bgp_sessions = [BgpSession(attributes=bgp_sess_attrs)]
1058 bgp_peering_attrs = BgpPeeringAttributes(session=bgp_sessions)
1059 rt_inst_obj = _get_rt_inst_obj(vnc_client)
1060
Marek Celoud3097e5b2018-01-09 13:52:14 +01001061 bgp_auth_data = None
1062
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001063 if type == 'control-node':
1064 vendor = 'contrail'
1065 elif type == 'router':
1066 vendor = 'mx'
1067 else:
1068 vendor = 'unknown'
1069
Sergey Kreyse78fa6c2019-09-19 16:01:57 -05001070 if key_type == 'md5':
1071 key_id = 0
1072 key_items = AuthenticationKeyItem(key_id, key)
1073 bgp_auth_data = AuthenticationData(key_type, [key_items])
1074
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001075 router_params = BgpRouterParams(router_type=type,
1076 vendor=vendor, autonomous_system=int(asn),
1077 identifier=_get_ip(ip_address),
1078 address=_get_ip(ip_address),
Marek Celoud3097e5b2018-01-09 13:52:14 +01001079 port=179, address_families=bgp_addr_fams,
1080 auth_data=bgp_auth_data)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001081
Ales Komarekad46d2e2017-03-09 17:16:38 +01001082 bgp_router_objs = bgp_router_list(**kwargs)
1083 if name in bgp_router_objs:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001084 bgp_router_obj = vnc_client._object_read('bgp-router', id=bgp_router_objs[name]['_uuid'])
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001085
1086 if bgp_router_obj.bgp_router_parameters.autonomous_system != asn:
1087 ret['changes'].update({"autonomous_system": {'old': bgp_router_obj.bgp_router_parameters.autonomous_system, 'new': asn}})
1088 if bgp_router_obj.bgp_router_parameters.vendor != vendor:
1089 ret['changes'].update({"vendor": {'old': bgp_router_obj.bgp_router_parameters.vendor, 'new': vendor}})
1090 if bgp_router_obj.bgp_router_parameters.address != ip_address:
1091 ret['changes'].update({"ip_address": {'old': bgp_router_obj.bgp_router_parameters.address, 'new': ip_address}})
Marek Celoud3097e5b2018-01-09 13:52:14 +01001092 try:
1093 if bgp_router_obj.bgp_router_parameters.auth_data.key_type != key_type:
1094 ret['changes'].update({"key_type": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_type, 'new': key_type}})
1095 except:
1096 if key_type != None:
1097 ret['changes'].update({"key_type": {'old': None, 'new': key_type}})
1098 if key_type == 'md5':
1099 try:
1100 if bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key != key:
Sergey Kreyse78fa6c2019-09-19 16:01:57 -05001101 ret['changes'].update({"key": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key, 'new': key}})
Marek Celoud3097e5b2018-01-09 13:52:14 +01001102 except:
Sergey Kreyse78fa6c2019-09-19 16:01:57 -05001103 ret['changes'].update({"key": {'old': None, 'new': key}})
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001104
1105 if len(ret['changes']) == 0:
1106 return ret
1107
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001108 bgp_router_obj.set_bgp_router_parameters(router_params)
1109 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001110 ret['result'] = None
1111 ret['comment'] = "BGP router " + name + " will be updated"
1112 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001113 vnc_client.bgp_router_update(bgp_router_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001114 ret['comment'] = "BGP router " + name + " has been updated"
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001115 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001116 else:
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001117 bgp_router_obj = BgpRouter(name, rt_inst_obj, bgp_router_parameters=router_params)
1118 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001119 ret['result'] = None
1120 ret['comment'] = "BGP router " + name + " will be created"
1121 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001122 vnc_client.bgp_router_create(bgp_router_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001123 ret['comment'] = "BGP router " + name + " has been created"
1124 ret['changes'] = {'BGP router': {'old': name, 'new': ''}}
1125 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001126
1127
1128def bgp_router_delete(name, **kwargs):
1129 '''
1130 Delete specific Contrail control node
1131
1132 CLI Example:
1133
1134 .. code-block:: bash
1135
1136 salt '*' contrail.bgp_router_delete mx01
1137 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001138 ret = {'name': name,
1139 'changes': {},
1140 'result': True,
1141 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001142 vnc_client = _auth(**kwargs)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001143
1144 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001145 ret['result'] = None
1146 ret['comment'] = "BGP router " + name + " will be deleted"
1147 return ret
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001148
1149 bgp_router = bgp_router_get(name)
1150 if name in bgp_router:
1151 vnc_client.bgp_router_delete(fq_name=bgp_router[name]['fq_name'])
1152 ret['comment'] = "BGP router " + name + " has been deleted"
1153 ret['changes'] = {'BGP router': {'old': '', 'new': name}}
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001154 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001155
Ales Komarekad46d2e2017-03-09 17:16:38 +01001156
1157def database_node_list(**kwargs):
1158 '''
1159 Return a list of all Contrail database nodes
1160
1161 CLI Example:
1162
1163 .. code-block:: bash
1164
1165 salt '*' contrail.database_node_list
1166 '''
1167 ret = {}
1168 vnc_client = _auth(**kwargs)
1169 node_objs = vnc_client._objects_list('database-node', detail=True)
1170 for node_obj in node_objs:
1171 ret[node_obj.name] = node_obj.__dict__
1172 return ret
1173
1174
1175def database_node_get(name, **kwargs):
1176 '''
1177 Return a specific Contrail database node
1178
1179 CLI Example:
1180
1181 .. code-block:: bash
1182
1183 salt '*' contrail.database_node_get nal01
1184 '''
1185 ret = {}
1186 vrouter_objs = database_node_list(**kwargs)
1187 if name in vrouter_objs:
1188 ret[name] = vrouter_objs.get(name)
1189 if len(ret) == 0:
1190 return {'Error': 'Error in retrieving database node.'}
1191 return ret
1192
1193
1194def database_node_create(name, ip_address, **kwargs):
1195 '''
1196 Create specific Contrail database node
1197
1198 CLI Example:
1199
1200 .. code-block:: bash
1201
1202 salt '*' contrail.database_node_create ntw03 10.10.10.103
1203 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001204 ret = {'name': name,
1205 'changes': {},
1206 'result': True,
1207 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001208 vnc_client = _auth(**kwargs)
1209 gsc_obj = _get_config(vnc_client)
1210 database_node_objs = database_node_list(**kwargs)
1211 if name in database_node_objs:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001212 ret['comment'] = 'Database node ' + name + ' already exists'
1213 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001214 else:
1215 database_node_obj = DatabaseNode(
1216 name, gsc_obj,
1217 database_node_ip_address=ip_address)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001218 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001219 ret['result'] = None
1220 ret['comment'] = "DatabaseNode " + name + " will be created"
1221 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001222 vnc_client.database_node_create(database_node_obj)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001223 ret['comment'] = "DatabaseNode " + name + " has been created"
1224 ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}}
1225 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001226
1227
1228def database_node_delete(name, **kwargs):
1229 '''
1230 Delete specific Contrail database node
1231
1232 CLI Example:
1233
1234 .. code-block:: bash
1235
1236 salt '*' contrail.database_node_delete cmp01
1237 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001238 ret = {'name': name,
1239 'changes': {},
1240 'result': True,
1241 'comment': ''}
Ales Komarekad46d2e2017-03-09 17:16:38 +01001242 vnc_client = _auth(**kwargs)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001243 gsc_obj = _get_config(vnc_client)
1244 database_node_obj = DatabaseNode(name, gsc_obj)
1245 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001246 ret['result'] = None
1247 ret['comment'] = "DatabaseNode " + name + " will be deleted"
1248 return ret
Ales Komarekad46d2e2017-03-09 17:16:38 +01001249 vnc_client.database_node_delete(
1250 fq_name=database_node_obj.get_fq_name())
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001251 ret['comment'] = "DatabaseNode " + name + " has been deleted"
1252 ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}}
1253 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001254
1255
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001256def _get_vrouter_config(vnc_client, gvc_name=None):
Petr Jediný5f3efe32017-05-26 17:55:09 +02001257 try:
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001258 if not gvc_name:
1259 gvc_list = global_vrouter_config_list()
1260 gvc_name = gvc_list.values()[0]['name']
1261
Petr Jediný5f3efe32017-05-26 17:55:09 +02001262 config = vnc_client.global_vrouter_config_read(
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001263 fq_name=['default-global-system-config', gvc_name])
Petr Jediný5f3efe32017-05-26 17:55:09 +02001264 except Exception:
1265 config = None
1266
1267 return config
1268
1269
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001270def linklocal_service_list(global_vrouter_config_name=None, **kwargs):
Petr Jediný5f3efe32017-05-26 17:55:09 +02001271 '''
1272 Return a list of all Contrail link local services
1273
1274 CLI Example:
1275
1276 .. code-block:: bash
1277
1278 salt '*' contrail.linklocal_service_list
1279 '''
1280 ret = {}
1281 vnc_client = _auth(**kwargs)
1282
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001283 current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001284 if current_config is None:
1285 return ret
1286
1287 service_list_res = current_config.get_linklocal_services()
1288 if service_list_res is None:
1289 service_list_obj = {'linklocal_service_entry': []}
1290 else:
1291 service_list_obj = service_list_res.__dict__
1292 for _, value in service_list_obj.iteritems():
1293 for entry in value:
1294 service = entry.__dict__
1295 if 'linklocal_service_name' in service:
1296 ret[service['linklocal_service_name']] = service
1297 return ret
1298
1299
1300def linklocal_service_get(name, **kwargs):
1301 '''
1302 Return a specific Contrail link local service
1303
1304 CLI Example:
1305
1306 .. code-block:: bash
1307
1308 salt '*' contrail.linklocal_service_get llservice
1309 '''
1310 ret = {}
1311 services = linklocal_service_list(**kwargs)
1312 if name in services:
1313 ret[name] = services.get(name)
1314 if len(ret) == 0:
1315 return {'Error': 'Error in retrieving link local service "{0}"'.format(name)}
1316 return ret
1317
1318
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001319def 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 +02001320 '''
1321 Create specific Contrail link local service
1322
1323 CLI Example:
1324
1325 .. code-block:: bash
1326
1327 salt '*' contrail.linklocal_service_create \
1328 llservice 10.10.10.103 22 '["20.20.20.20", "30.30.30.30"]' 22
1329 salt '*' contrail.linklocal_service_create \
1330 llservice 10.10.10.103 22 link-local.service.dns-name 22
1331 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001332 ret = {'name': name,
1333 'changes': {},
1334 'result': True,
1335 'comment': ''}
Petr Jediný5f3efe32017-05-26 17:55:09 +02001336 vnc_client = _auth(**kwargs)
Pavel Svimbersky2fe0c272017-11-30 14:58:16 +01001337 current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001338 service_entry = LinklocalServiceEntryType(
1339 linklocal_service_name=name,
1340 linklocal_service_ip=lls_ip,
1341 linklocal_service_port=lls_port,
1342 ip_fabric_service_port=ipf_port)
1343 if isinstance(ipf_dns_or_ip, basestring):
1344 service_entry.ip_fabric_DNS_service_name = ipf_dns_or_ip
1345 elif isinstance(ipf_dns_or_ip, list):
1346 service_entry.ip_fabric_service_ip = ipf_dns_or_ip
1347 service_entry.ip_fabric_DNS_service_name = ''
1348
1349 if current_config is None:
1350 new_services = LinklocalServicesTypes([service_entry])
1351 new_config = GlobalVrouterConfig(linklocal_services=new_services)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001352 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001353 ret['result'] = None
1354 ret['comment'] = "Link local service " + name + " will be created"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001355 else:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001356 ret['comment'] = "Link local service " + name + " has been created"
1357 ret['changes'] = {'LinkLocalSevice': {'old': '', 'new': name}}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001358 vnc_client.global_vrouter_config_create(new_config)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001359 else:
1360 _current_service_list = current_config.get_linklocal_services()
1361 if _current_service_list is None:
1362 service_list = {'linklocal_service_entry': []}
1363 else:
1364 service_list = _current_service_list.__dict__
1365 new_services = [service_entry]
1366 for key, value in service_list.iteritems():
1367 if key != 'linklocal_service_entry':
1368 continue
1369 for _entry in value:
1370 entry = _entry.__dict__
1371 if 'linklocal_service_name' in entry:
1372 if entry['linklocal_service_name'] == name:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001373 ret['comment'] = 'Link local service ' + name + ' already exists'
1374 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001375 new_services.append(_entry)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001376 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001377 ret['result'] = None
1378 ret['comment'] = "LinkLocalSevices " + name + " will be created"
Petr Jediný5f3efe32017-05-26 17:55:09 +02001379 service_list[key] = new_services
1380 new_config = GlobalVrouterConfig(linklocal_services=service_list)
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001381 if __opts__['test']:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001382 ret['result'] = None
1383 ret['comment'] = "LinkLocalSevices " + name + " will be updated"
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001384 else:
1385 vnc_client.global_vrouter_config_update(new_config)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001386 ret['comment'] = "LinkLocalSevices " + name + " has been created"
1387 ret['changes'] = {'LinkLocalSevices': {'old': '', 'new': name}}
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001388 return ret
Petr Jediný5f3efe32017-05-26 17:55:09 +02001389
1390
1391def linklocal_service_delete(name, **kwargs):
1392 '''
1393 Delete specific link local service entry
1394
1395 CLI Example:
1396
1397 .. code-block:: bash
1398
1399 salt '*' contrail.linklocal_service_delete llservice
1400 '''
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001401 ret = {'name': name,
1402 'changes': {},
1403 'result': True,
1404 'comment': ''}
1405 lls = linklocal_service_get(name)
1406 print (lls)
1407 if name in lls:
1408 if __opts__['test']:
1409 print " ------------ Test only ------------"
1410 ret['result'] = None
1411 ret['comment'] = "Link local service " + name + " will be deleted"
1412 return ret
1413 else:
1414 return ret
1415
Petr Jediný5f3efe32017-05-26 17:55:09 +02001416 vnc_client = _auth(**kwargs)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001417 current_config = _get_vrouter_config(vnc_client)
Petr Jediný5f3efe32017-05-26 17:55:09 +02001418 if current_config is not None:
1419 _current_service_list = current_config.get_linklocal_services()
1420 if _current_service_list is None:
1421 service_list = {'linklocal_service_entry': []}
1422 else:
1423 service_list = _current_service_list.__dict__
1424 new_services = []
1425 for key, value in service_list.iteritems():
1426 if key != 'linklocal_service_entry':
1427 continue
1428 for _entry in value:
1429 entry = _entry.__dict__
1430 if 'linklocal_service_name' in entry:
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001431 if entry['linklocal_service_name'] != name:
Petr Jediný5f3efe32017-05-26 17:55:09 +02001432 new_services.append(_entry)
1433 service_list[key] = new_services
1434 new_config = GlobalVrouterConfig(linklocal_services=service_list)
1435 vnc_client.global_vrouter_config_update(new_config)
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001436 ret['comment'] = "Link local service " + name + " will be deleted"
1437 ret['changes'] = {'LinkLocalService': {'old': '', 'new': name}}
1438 return ret
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001439
1440
1441def virtual_machine_interface_list(**kwargs):
1442 '''
1443 Return a list of all Contrail virtual machine interfaces
1444
1445 CLI Example:
1446
1447 .. code-block:: bash
1448
1449 salt '*' contrail.virtual_machine_interfaces
1450 '''
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001451 ret = []
1452 vnc_client = _auth(**kwargs)
1453 project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin'))
1454 project_uuid = project.get_uuid()
1455
1456 vm_ifaces = vnc_client.virtual_machine_interfaces_list(
1457 detail=True, parent_id=project_uuid)
1458
1459 for vm_iface in vm_ifaces:
1460 ret.append(vm_iface.__dict__)
1461
1462 return ret
1463
1464
1465def virtual_machine_interface_create(name,
1466 virtual_network,
1467 mac_address=None,
1468 ip_address=None,
1469 security_group=None,
1470 **kwargs):
1471 '''
1472 Create specific Contrail virtual machine interface (Port)
1473
1474 CLI Example:
1475
1476 .. code-block:: bash
1477
1478 salt '*' contrail.virtual_machine_interface_create port01 net01 mac_address='01:02:03:04:05:06'
1479 router_types:
1480 - tor-agent
1481 - tor-service-node
1482 - embedded
1483 '''
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001484 ret = {}
1485 vnc_client = _auth(**kwargs)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001486 project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin'))
1487
1488 vm_int = VirtualMachineInterface(name, parent_obj=project)
1489
1490 if mac_address:
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001491 mac_address_obj = MacAddressesType([mac_address])
1492 vm_int.set_virtual_machine_interface_mac_addresses(mac_address_obj)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001493
1494 if security_group:
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001495 sgo = vnc_client.security_group_read(fq_name=_get_fq_name(
Pavel Svimbersky4358c352017-09-27 13:23:46 +02001496 vnc_client, security_group, kwargs.get('tenant', 'admin')))
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001497 vm_int.set_security_group(sgo)
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001498
1499 vnet_uuid = virtual_network_get(virtual_network, **kwargs)[virtual_network]['_uuid']
1500 vnet_obj = vnc_client.virtual_network_read(id=vnet_uuid)
1501 vm_int.set_virtual_network(vnet_obj)
1502
1503 vmi_uuid = vnc_client.virtual_machine_interface_create(vm_int)
1504 vmi = vnc_client.virtual_machine_interface_read(id=vmi_uuid)
1505
1506 vm_int.set_port_security_enabled(False)
1507 vnc_client.virtual_machine_interface_update(vm_int)
1508
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001509 # Allocate IP to VMI
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001510 ip = vnc_api.InstanceIp(name + '.ip')
1511 ip.set_virtual_machine_interface(vmi)
1512 ip.set_virtual_network(vnet_obj)
1513
1514 ip_uuid = vnc_client.instance_ip_create(ip)
1515
1516 if ip_address:
1517 ip.set_instance_ip_address(ip_address)
1518 vnc_client.instance_ip_update(ip)
1519
1520 return vmi.__dict__
Pavel Svimbersky483a19e2017-08-22 09:50:29 +02001521
1522
1523def virtual_network_list(**kwargs):
1524 '''
1525 Return a list of all Contrail virtual network
1526
1527 CLI Example:
1528
1529 .. code-block:: bash
1530
1531 salt '*' contrail.virtual_network
1532 '''
1533
1534 ret = {}
1535 vnc_client = _auth(**kwargs)
1536 virtual_networks = vnc_client._objects_list('virtual-network', detail=True)
1537 for virtual_network in virtual_networks:
1538 ret[virtual_network.name] = virtual_network.__dict__
1539 return ret
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001540
1541
1542def virtual_network_get(name, **kwargs):
1543 '''
1544 Return a specific Contrail virtual network
1545
1546 CLI Example:
1547
1548 .. code-block:: bash
1549
1550 salt '*' contrail.virtual_network_get net01
1551 '''
1552 ret = {}
1553 vnet_objs = virtual_network_list(**kwargs)
1554 if name in vnet_objs:
1555 ret[name] = vnet_objs.get(name)
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001556 if len(ret) != 1:
Vasyl Saienkob10b7202017-09-05 14:19:03 +03001557 return {'result': False,
1558 'Error': 'Error in retrieving virtual networks.'}
1559 return ret
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001560
1561
ibumarskov66f46102019-02-20 11:44:22 +04001562def virtual_network_create(name, domain='default-domain', project='admin',
1563 ipam_domain='default-domain',
1564 ipam_project='default-project',
1565 ipam_name='default-network-ipam',
1566 router_external=None, route_target_list=None,
1567 subnet_conf=None, vntype_conf=None, **kwargs):
Jan Cacha859e6b2018-01-09 17:34:18 +01001568 '''
1569 Create Contrail virtual network
1570 CLI Example:
1571 .. code-block:: bash
Jan Cacha859e6b2018-01-09 17:34:18 +01001572
ibumarskov66f46102019-02-20 11:44:22 +04001573 salt -C 'I@opencontrail:control:role:primary'
1574 contrail.virtual_network_create public router_external=True
1575 route_target_list=["target:64512:10000"]
1576 subnet_conf=["ip_prefix":"172.16.111.0","ip_prefix_len":24]
Jan Cacha859e6b2018-01-09 17:34:18 +01001577
1578 Parameters:
ibumarskov66f46102019-02-20 11:44:22 +04001579 name (str): name of the network (required)
1580 domain (str): name of domain (optional)
1581 project (str): name of project (optional)
1582 ipam_domain (str): domain for ipam (optional)
1583 ipam_project (str): project for ipam (optional)
1584 ipam_name (str): name of IP Address Management (optional)
1585 router_external (bool): When true, this virtual network is openstack router
1586 external network. (optional)
1587 route_target_list (list): route target list - format is
1588 ['target:<asn>:<target>']
1589 subnet_conf (dict):
Jan Cacha859e6b2018-01-09 17:34:18 +01001590 ip_prefix (string) optional - format is xxx.xxx.xxx.xxx
1591 ip_prefix_len (int) optional - format is xx
ibumarskov66f46102019-02-20 11:44:22 +04001592 vntype_conf (dict):
Jan Cacha859e6b2018-01-09 17:34:18 +01001593 allow_transit (boolean) optional - enable allow transit
ibumarskov66f46102019-02-20 11:44:22 +04001594 vxlan_network_identifier (int) - VxLAN VNI value for network
Jan Cacha859e6b2018-01-09 17:34:18 +01001595 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 '''
Jan Cacha859e6b2018-01-09 17:34:18 +01001603 ret = {'name': name,
1604 'changes': {},
1605 'result': True,
1606 'comment': ''}
1607
Jan Cacha859e6b2018-01-09 17:34:18 +01001608 vnc_client = _auth(**kwargs)
ibumarskov66f46102019-02-20 11:44:22 +04001609 fq_name = [domain, project, name]
1610 prj_obj = vnc_client.project_read(fq_name=[domain,
1611 project])
1612 ipam_obj = vnc_client.network_ipam_read(fq_name=[ipam_domain,
1613 ipam_project,
1614 ipam_name])
1615 if route_target_list:
1616 route_target_list = RouteTargetList(route_target_list)
1617 if subnet_conf:
1618 if 'ip_prefix' in subnet_conf and 'ip_prefix_len' in subnet_conf:
1619 ipam_sn = IpamSubnetType(subnet=SubnetType(
1620 ip_prefix=subnet_conf['ip_prefix'],
1621 ip_prefix_len=subnet_conf['ip_prefix_len']))
Jan Cacha859e6b2018-01-09 17:34:18 +01001622
ibumarskov66f46102019-02-20 11:44:22 +04001623 # Check if the network exists
1624 vn_obj_list = vnc_client.virtual_networks_list(parent_id=prj_obj.uuid)
1625 if name in list(map(lambda x: x['fq_name'][2],
1626 vn_obj_list['virtual-networks'])):
1627 changes = {}
1628 vn_obj = vnc_client.virtual_network_read(fq_name=fq_name)
Jan Cacha859e6b2018-01-09 17:34:18 +01001629
ibumarskov66f46102019-02-20 11:44:22 +04001630 # Update IPAM properties
1631 ipam_refs = vn_obj.get_network_ipam_refs()
1632 subnet_detected = False
1633 if subnet_conf and ipam_refs:
1634 for ipam in ipam_refs:
1635 if ipam_obj.get_uuid() == ipam['uuid']:
1636 ipam_subnet_list = ipam['attr'].get_ipam_subnets()
1637 for ipam_subnet_type in ipam_subnet_list:
1638 subnet_obj = ipam_subnet_type.get_subnet()
1639 ip_prefix = subnet_obj.get_ip_prefix()
1640 ip_prefix_len = subnet_obj.get_ip_prefix_len()
1641 if subnet_conf['ip_prefix'] == ip_prefix and \
1642 subnet_conf['ip_prefix_len'] == ip_prefix_len:
1643 subnet_detected = True
1644 if subnet_conf and not subnet_detected:
1645 changes['ipam_subnet'] = \
1646 {'added': '{0}/{1}'.format(subnet_conf['ip_prefix'],
1647 subnet_conf['ip_prefix_len'])}
1648 vn_obj.add_network_ipam(ipam_obj,
1649 VnSubnetsType(ipam_subnets=[ipam_sn]))
Jan Cacha859e6b2018-01-09 17:34:18 +01001650
ibumarskov66f46102019-02-20 11:44:22 +04001651 # Update VirtualNetwork properties
1652 external = vn_obj.get_router_external()
1653 if router_external is not None and router_external != external:
1654 changes['router_external'] = {'from': external,
1655 'to': router_external}
1656 vn_obj.set_router_external(router_external)
1657 if route_target_list:
1658 changes['router_list'] = \
1659 {'from': str(vn_obj.get_route_target_list()),
1660 'to': str(route_target_list)}
1661 vn_obj.set_route_target_list(route_target_list)
Jan Cacha859e6b2018-01-09 17:34:18 +01001662
ibumarskov66f46102019-02-20 11:44:22 +04001663 # Update VirtualNetworkType properties
1664 if vntype_conf:
1665 vn_type_obj = vn_obj.get_virtual_network_properties()
1666 if vn_type_obj is None:
1667 vn_type_obj = VirtualNetworkType()
Jan Cacha859e6b2018-01-09 17:34:18 +01001668
ibumarskov66f46102019-02-20 11:44:22 +04001669 if 'allow_transit' in vntype_conf:
1670 allow_transit_attr = vn_type_obj.get_allow_transit()
1671 if vntype_conf['allow_transit'] != allow_transit_attr:
1672 changes['allow_transit'] = \
1673 {'from': allow_transit_attr,
1674 'to': vntype_conf['allow_transit']}
1675 vn_type_obj.set_allow_transit(vntype_conf['allow_transit'])
1676 if 'vxlan_network_identifier' in vntype_conf:
1677 vxlan_net_id = vn_type_obj.get_vxlan_network_identifier()
1678 if vntype_conf['vxlan_network_identifier'] != vxlan_net_id:
1679 vn_type_obj.set_vxlan_network_identifier(
1680 vntype_conf['vxlan_network_identifier'])
1681 changes['vxlan_network_identifier'] = \
1682 {'from': vxlan_net_id,
1683 'to': vntype_conf['vxlan_network_identifier']}
1684 if 'forwarding_mode' in vntype_conf:
1685 forwarding_mode_attr = vn_type_obj.get_forwarding_mode()
1686 if vntype_conf['forwarding_mode'] in ['l2_l3', 'l2', 'l3'] and \
1687 vntype_conf['forwarding_mode'] != forwarding_mode_attr:
1688 changes['forwarding_mode'] = \
1689 {'from': forwarding_mode_attr,
1690 'to': vntype_conf['forwarding_mode']}
1691 vn_type_obj.set_forwarding_mode(
1692 vntype_conf['forwarding_mode'])
1693 if 'mirror_destination' in vntype_conf:
1694 mirror_dst_attr = vn_type_obj.get_mirror_destination()
1695 if vntype_conf['mirror_destination'] != mirror_dst_attr:
1696 changes['mirror_destination'] = \
1697 {'from': mirror_dst_attr,
1698 'to': vntype_conf['mirror_destination']}
1699 vn_type_obj.set_mirror_destination(
1700 vntype_conf['mirror_destination'])
1701 if 'rpf' in vntype_conf:
1702 rpf_attr = vn_type_obj.get_rpf()
1703 if vntype_conf['rpf'] != rpf_attr:
1704 changes['rpf'] = \
1705 {'from': rpf_attr,
1706 'to': vntype_conf['rpf']}
1707 vn_type_obj.set_rpf(vntype_conf['rpf'])
1708 vn_obj.set_virtual_network_properties(vn_type_obj)
Jan Cacha859e6b2018-01-09 17:34:18 +01001709
ibumarskov66f46102019-02-20 11:44:22 +04001710 if changes:
1711 ret['changes'] = changes
1712 if __opts__['test']:
1713 ret['result'] = None
1714 ret['comment'] = "Virtual network " + name + " will be updated"
1715 else:
1716 ret['comment'] = "VirtualNetwork " + name + " has been updated"
1717 vnc_client.virtual_network_update(vn_obj)
1718 else:
1719 ret['comment'] = 'Virtual network ' + name + \
1720 ' already exists and is updated'
Jan Cacha859e6b2018-01-09 17:34:18 +01001721 else:
ibumarskov66f46102019-02-20 11:44:22 +04001722 vn_obj = VirtualNetwork(name, prj_obj)
Jan Cachb3092722018-01-31 12:46:16 +01001723
ibumarskov66f46102019-02-20 11:44:22 +04001724 # Configure IPAM properties
1725 if subnet_conf:
1726 if 'ip_prefix' in subnet_conf and 'ip_prefix_len' in subnet_conf:
1727 vn_obj.add_network_ipam(ipam_obj,
1728 VnSubnetsType(ipam_subnets=[ipam_sn]))
1729
1730 # Configure VirtualNetwork properties
1731 if router_external is not None:
1732 vn_obj.set_router_external(router_external)
1733 if route_target_list is not None:
1734 vn_obj.set_route_target_list(route_target_list)
1735
1736 # Configure VirtualNetworkType properties
1737 if vntype_conf:
1738 vn_type_obj = VirtualNetworkType()
1739 if 'allow_transit' in vntype_conf:
1740 vn_type_obj.set_allow_transit(vntype_conf['allow_transit'])
1741 if 'vxlan_network_identifier' in vntype_conf:
1742 vn_type_obj.set_vxlan_network_identifier(
1743 vntype_conf['vxlan_network_identifier'])
1744 if 'forwarding_mode' in vntype_conf:
1745 if vntype_conf['forwarding_mode'] in ['l2_l3', 'l2', 'l3']:
1746 vn_type_obj.set_forwarding_mode(
1747 vntype_conf['forwarding_mode'])
1748 if 'mirror_destination' in vntype_conf:
1749 vn_type_obj.set_mirror_destination(vntype_conf['mirror_destination'])
1750 if 'rpf' in vntype_conf:
1751 vn_type_obj.set_rpf(vntype_conf['rpf'])
1752 vn_obj.set_virtual_network_properties(vn_type_obj)
1753
1754 if __opts__['test']:
1755 ret['result'] = None
1756 ret['comment'] = "VirtualNetwork " + name + " will be created"
1757 else:
1758 vnc_client.virtual_network_create(vn_obj)
1759 ret['comment'] = "VirtualNetwork " + name + " has been created"
1760 ret['changes'] = {'VirtualNetwork': {'created': name}}
Jan Cacha859e6b2018-01-09 17:34:18 +01001761 return ret
1762
1763
Pavel Svimbersky5ba8a7b2017-09-21 11:07:48 +02001764def service_appliance_set_list(**kwargs):
1765 '''
1766 Return a list of Contrail service appliance set
1767
1768 CLI Example:
1769
1770 .. code-block:: bash
1771
1772 salt '*' contrail.service_appliance_set_list
1773 '''
1774 ret = {}
1775 vnc_client = _auth(**kwargs)
1776 service_appliance_sets = vnc_client._objects_list('service-appliance-set', detail=True)
1777 for service_appliance_set in service_appliance_sets:
1778 ret[service_appliance_set.name] = service_appliance_set.__dict__
1779 return ret
1780
1781
1782def service_appliance_set_get(name, **kwargs):
1783 '''
1784 Return a specific Contrail service appliance set
1785
1786 CLI Example:
1787
1788 .. code-block:: bash
1789
1790 salt '*' contrail.service_appliance_set_get name
1791 '''
1792 ret = {}
1793 sas_objs = service_appliance_set_list(**kwargs)
1794 if name in sas_objs:
1795 ret[name] = sas_objs.get(name)
1796 if len(ret) != 1:
1797 return {'result': False,
1798 'Error': "Error in the retrieving service apliance set."}
1799 return ret
1800
1801
1802def service_appliance_set_create(name, properties=None, driver=None, ha_mode=None, **kwargs):
1803 '''
1804 Create Contrail service appliance set
1805
1806 CLI Example:
1807
1808 .. code-block:: bash
1809
1810 salt '*' contrail.service_appliance_set_create name
1811 '''
1812 ret = {'name': name,
1813 'changes': {},
1814 'result': True,
1815 'comment': ''}
1816 vnc_client = _auth(**kwargs)
1817 gsc_obj = _get_config(vnc_client)
1818 sas_objs = service_appliance_set_list(**kwargs)
1819 if name in sas_objs:
1820 ret['commnet'] = 'Service appliance set ' + name + ' already exists'
1821 else:
1822 service_appliance_set_obj = ServiceApplianceSet(
1823 name, gsc_obj)
1824 if properties:
1825 pairs = KeyValuePairs()
1826 for k, v in properties.items():
1827 pairs.add_key_value_pair(KeyValuePair(k, v))
1828 service_appliance_set_obj.set_service_appliance_set_properties(pairs)
1829 if driver:
1830 service_appliance_set_obj.set_service_appliance_driver(driver)
1831 if ha_mode:
1832 service_appliance_set_obj.set_service_appliance_ha_mode(ha_mode)
1833 if __opts__['test']:
1834 ret['result'] = None
1835 ret['comment'] = "ServiceApplianceSet " + name + " will be created"
1836 else:
1837 vnc_client.service_appliance_set_create(service_appliance_set_obj)
1838 ret['comment'] = "ServiceApplianceSet " + name + " has been created"
1839 ret['changes'] = {'ServiceApplianceSet': {'old': '', 'new': name}}
1840 return ret
1841
1842
1843def service_appliance_set_delete(name, **kwargs):
1844 '''
1845 Delete specific Contrail service appliance set
1846
1847 CLI Example:
1848
1849 .. code-block:: bash
1850
1851 salt '*' contrail.service_appliance_set_delete name
1852 '''
1853 ret = {'name': name,
1854 'changes': {},
1855 'result': True,
1856 'comment': ''}
1857 vnc_client = _auth(**kwargs)
1858 gsc_obj = _get_config(vnc_client)
1859 sas_obj = ServiceApplianceSet(name, gsc_obj)
1860 if __opts__['test']:
1861 ret['result'] = None
1862 ret['comment'] = "Service appliance set " + name + " will be deleted"
1863 else:
1864 vnc_client.service_appliance_set_delete(fq_name=sas_obj.get_fq_name())
1865 ret['comment'] = "ServiceApplianceSet " + name + " has been deleted"
1866 ret['changes'] = {'ServiceApplianceSet': {'old': name, 'new': ''}}
1867 return ret
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +01001868
1869def global_system_config_list(**kwargs):
1870 '''
1871 Return a list of all global system configs
1872
1873 CLI Example:
1874
1875 .. code-block:: bash
1876
1877 salt '*' contrail.global_system_config_list
1878 '''
1879
1880 ret = {}
1881 vnc_client = _auth(**kwargs)
1882 gsysconfs = vnc_client._objects_list('global-system-config', detail=True)
1883 for gsysconf in gsysconfs:
1884 ret[gsysconf.name] = gsysconf.__dict__
1885 return ret
1886
1887
1888def global_system_config_get(name, **kwargs):
1889 '''
1890 Return a specific Contrail global system config
1891
1892 CLI Example:
1893
1894 .. code-block:: bash
1895
1896 salt '*' contrail.global_system_config_get name
1897 '''
1898 ret = {}
1899 vnc_client = _auth(**kwargs)
1900 gsc_objs = vnc_client._objects_list('global-system-config', detail=True)
1901 for gsc_obj in gsc_objs:
1902 if name == gsc_obj.name:
1903 ret[name] = gsc_obj.__dict__
1904 if len(ret) == 0:
1905 return {'Error': 'Error in retrieving global system config.'}
1906 return ret
1907
1908
1909def global_system_config_create(name, ans=64512, grp=None, **kwargs):
1910 '''
1911 Create Contrail global system config
1912
1913 CLI Example:
1914
1915 .. code-block:: bash
1916
1917 salt '*' contrail.global_system_config_create name=default-global-system-config ans=64512
1918 '''
1919 ret = {'name': name,
1920 'changes': {},
1921 'result': True,
1922 'comment': ''}
1923 vnc_client = _auth(**kwargs)
1924
1925 gsc_objs = global_system_config_list(**kwargs)
1926 if name in gsc_objs:
1927 config_obj = vnc_client.global_system_config_read(fq_name=[name])
1928 if config_obj.graceful_restart_parameters and not HAS_OLD:
1929 curr_grp = str(config_obj.graceful_restart_parameters).replace(" ", "").split(",")
1930 curr_grpd = dict(item.split('=') for item in curr_grp)
psvimbersky3c84e272018-01-02 10:34:29 +01001931 else:
1932 curr_grpd = None
Pavel Svimberskydbd52ea2017-12-05 18:05:25 +01001933
1934 if grp and 'enable' in grp and not HAS_OLD:
1935 grp_obj = GracefulRestartParametersType()
1936 if 'enable' in grp:
1937 grp_obj.enable = grp['enable']
1938 if curr_grpd and str(grp['enable']) != str(curr_grpd['enable']):
1939 ret['changes']['enable'] = {"from": str(curr_grpd['enable']), "to": str(grp['enable'])}
1940 elif not curr_grpd:
1941 ret['changes']['enable'] = {"from": None, "to": grp['enable']}
1942 if 'restart_time' in grp:
1943 grp_obj.restart_time = grp['restart_time']
1944 if curr_grpd and grp['restart_time'] != int(curr_grpd['restart_time']):
1945 ret['changes']['restart_time'] = {"from": int(curr_grpd['restart_time']), "to": grp['restart_time']}
1946 elif not curr_grpd:
1947 ret['changes']['restart_time'] = {"from": None, "to": grp['restart_time']}
1948 if 'end_of_rib_timeout' in grp:
1949 grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout']
1950 if curr_grpd and grp['end_of_rib_timeout'] != int(curr_grpd['end_of_rib_timeout']):
1951 ret['changes']['end_of_rib_timeout'] = {"from": int(curr_grpd['end_of_rib_timeout']), "to": grp['end_of_rib_timeout']}
1952 elif not curr_grpd:
1953 ret['changes']['end_of_rib_timeout'] = {"from": None, "to": grp['end_of_rib_timeout']}
1954 if 'bgp_helper_enable' in grp:
1955 grp_obj.bgp_helper_enable = grp['bgp_helper_enable']
1956 if curr_grpd and str(grp['bgp_helper_enable']) != str(curr_grpd['bgp_helper_enable']):
1957 ret['changes']['bgp_helper_enable'] = {"from": str(curr_grpd['bgp_helper_enable']), "to": grp['bgp_helper_enable']}
1958 elif not curr_grpd:
1959 ret['changes']['bgp_helper_enable'] = {"from": None, "to": grp['bgp_helper_enable']}
1960 if 'xmpp_helper_enable' in grp:
1961 grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable']
1962 if curr_grpd and str(grp['xmpp_helper_enable']) != str(curr_grpd['xmpp_helper_enable']):
1963 ret['changes']['xmpp_helper_enable'] = {"from": str(curr_grpd['xmpp_helper_enable']), "to": grp['xmpp_helper_enable']}
1964 elif not curr_grpd:
1965 ret['changes']['xmpp_helper_enable'] = {"from": None, "to": grp['xmpp_helper_enable']}
1966 if 'long_lived_restart_time' in grp:
1967 grp_obj.long_lived_restart_time = grp['long_lived_restart_time']
1968 if curr_grpd and grp['long_lived_restart_time'] != int(curr_grpd['long_lived_restart_time']):
1969 ret['changes']['long_lived_restart_time'] = {"from": int(curr_grpd['long_lived_restart_time']), "to": grp['long_lived_restart_time']}
1970 elif not curr_grpd:
1971 ret['changes']['long_lived_restart_time'] = {"from": None, "to": grp['long_lived_restart_time']}
1972 else:
1973 grp_obj = None
1974
1975 config_obj.graceful_restart_parameters = grp_obj
1976
1977 if ans:
1978 if config_obj.autonomous_system != ans:
1979 ret['changes']['autonomous_system'] = {"from": config_obj.autonomous_system, "to": ans}
1980 config_obj.autonomous_system = ans
1981
1982 vnc_client.global_system_config_update(config_obj)
1983 ret['comment'] = 'Global system config ' + name + ' has been updated'
1984 else:
1985 config_obj = GlobalSystemConfig(name=name)
1986 if grp and not HAS_OLD:
1987 grp_obj = GracefulRestartParametersType()
1988 if 'enable' in grp:
1989 grp_obj.enable = grp['enable']
1990 if 'restart_time' in grp:
1991 grp_obj.restart_time = grp['restart_time']
1992 if 'end_of_rib_timeout' in grp:
1993 grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout']
1994 if 'bgp_helper_enable' in grp:
1995 grp_obj.bgp_helper_enable = grp['bgp_helper_enable']
1996 if 'xmpp_helper_enable' in grp:
1997 grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable']
1998 if 'long_lived_restart_time' in grp:
1999 grp_obj.long_lived_restart_time = grp['long_lived_restart_time']
2000 config_obj.graceful_restart_parameters = grp_obj
2001 if ans:
2002 config_obj.autonomous_system = ans
2003
2004 vnc_client.global_system_config_create(config_obj)
2005 ret['changes'] = {"created": "new"}
2006 ret['comment'] = 'Global system config ' + name + ' has been created '
2007
2008 return ret
2009
2010
2011def global_system_config_delete(name, **kwargs):
2012 '''
2013 Delete specific Contrail global system config
2014
2015 CLI Example:
2016
2017 .. code-block:: bash
2018
2019 salt '*' contrail.global_system_config_delete name
2020 '''
2021 ret = {'name': name,
2022 'changes': {},
2023 'result': True,
2024 'comment': ''}
2025 vnc_client = _auth(**kwargs)
2026
2027 gsc_obj = GlobalSystemConfig(name)
2028 if __opts__['test']:
2029 ret['result'] = None
2030 ret['comment'] = "Global system config " + name + " will be deleted"
2031 else:
2032 vnc_client.global_system_config_delete(fq_name=gsc_obj.get_fq_name())
2033 ret['comment'] = "GlobalSystemConfig " + name + " has been deleted"
2034 ret['changes'] = {'GlobalSystemConfig': {'old': name, 'new': ''}}
2035 return ret
Jan Cachb3092722018-01-31 12:46:16 +01002036
2037
2038def list_floating_ip_pools(**kwargs):
2039 '''
2040 List all floating ip pools
2041
2042 CLI Example:
2043 .. code-block:: bash
2044 salt '*' contrail.list_floating_ip_pools
2045 '''
2046 vnc_client = _auth(**kwargs)
2047 pools = vnc_client.floating_ip_pools_list()
2048 # list of floating ip pools objects
2049 fp_list = []
2050
2051 for pool in vnc_client.floating_ip_pools_list()['floating-ip-pools']:
2052 fip_obj = vnc_client.floating_ip_pool_read(pool['fq_name'])
2053 fp_list.append(fip_obj)
2054 # print given pool
2055 fip_obj.dump()
2056
2057def update_floating_ip_pool(vn_name, vn_project, vn_domain=None,
2058 owner_access=None, global_access=None,
2059 projects=None, **kwargs):
2060 '''
2061 Update specific floating ip pool
2062
2063
2064 CLI Example
2065 .. code-block:: bash
2066 salt-call contrail.update_floating_ip_pool \
2067 'FLOATING-TEST' \
2068 'admin' \
2069 'default-domain' \
2070 7 7 \
2071 [['pepa',4],['karel',7]]
2072
2073
2074 params:
2075 vn_name - name of the virtual network, which to use
2076 vn-project - project which includes virtual network
2077 vn-domain - domain wchich includes vn_project and vn_name
2078 owner_access (int) - Permission rights for owner
2079 global_access (int) - Permission rights for others
2080 projects (list) - list of ShareType(tenant_name,tennat_permissions)
2081 '''
2082 ret = {'name': vn_name + "-default pool",
2083 'changes': {},
2084 'result': True,
2085 'comment': ''}
2086
2087 if vn_domain is None:
2088 vn_domain = 'default-domain'
2089 fip_obj = None
2090
2091 vnc_client = _auth(**kwargs)
2092 p_fq_name = [vn_domain, vn_project, vn_name, 'default']
2093 fip_obj = vnc_client.floating_ip_pool_read(fq_name=p_fq_name)
2094
2095 changes = {}
2096 # get perms from fip_obj (Floatin ip pool)
2097 perms2 = fip_obj.get_perms2()
2098 if owner_access is not None:
2099 if perms2.get_owner_access() != owner_access:
2100 changes['owner_access'] = {'old': str(perms2.get_owner_access()),
2101 'new': str(owner_access)}
2102 perms2.set_owner_access(owner_access)
2103
2104 if global_access is not None:
2105 if perms2.get_global_access() != global_access:
2106 changes['global_access'] = {'old': str(perms2.get_global_access()),
2107 'new': str(global_access)}
2108 perms2.set_global_access(global_access)
2109
2110 # list which represents the new state of perms
2111 final_list = []
2112 if projects:
2113 for item in perms2.get_share():
2114 for share in projects:
2115 if item.get_tenant() == share[0]:
2116 # project is in the new and old list
2117 # check is the permission number is same
2118 if item.get_tenant_access() == share[1]:
2119 # this project and permission is without change, keep it
2120 final_list.append(item)
2121 break
2122 else:
2123 # project exists but change the permission
2124 final_list.append(ShareType(tenant=share[0],
2125 tenant_access=share[1]))
2126 # show changes
2127 n = str('share-'+share[0])
2128 old_str = "permission for project {0} was {1}"
2129 new_str = "permission for project {0} will be {1}"
2130 old = old_str.format(share[0],
2131 str(item.get_tenant_access()))
2132
2133 new = new_str.format(share[0], str(share[1]))
2134 changes[n] = {'old': old, 'new': new}
2135 break
2136 else:
2137 rm_name = "share-" + item.get_tenant()
2138 changes[rm_name] = item.get_tenant() + " will be removed"
2139
2140 # check for the completly new projects
2141 for item in projects:
2142 for share in final_list:
2143 if item[0] == share.get_tenant():
2144 break
2145 else:
2146 final_list.append(ShareType(tenant=item[0],
2147 tenant_access=item[1]))
2148 name = 'share-' + str(item[0])
2149 c_str = '{0} will be added with permissions {1}'
2150 changes[name] = c_str.format(name, item[1])
2151 else:
2152 for item in perms2.get_share():
2153 rm_name = "share-" + item.get_tenant()
2154 changes[rm_name] = item.get_tenant() + " will be removed"
2155
2156 if __opts__['test']:
2157 ret['result'] = None
2158 ret['comment'] = changes
2159
2160 return ret
2161 else:
2162 ret['comment'] = changes
2163 perms2.set_share(final_list)
2164 fip_obj.set_perms2(perms2)
2165 vnc_client.floating_ip_pool_update(fip_obj)
2166
2167 return ret
Sergey Matov16896ac2018-02-15 15:46:31 +04002168
2169
2170def show_rbac_rules(api_access_list_entries):
2171 if api_access_list_entries is None:
2172 return 'Empty RBAC group!'
2173
2174 rule_list = api_access_list_entries.get_rbac_rule()
2175 response = 'Rules (%d):' % len(rule_list) + '----------\n'
2176 for idx, rule in enumerate(rule_list):
2177 o = rule.rule_object
2178 f = rule.rule_field
2179 ps = ', '.join([p.role_name+':'+p.role_crud for p in rule.rule_perms])
2180 o_f = "%s.%s" % (o, f) if f else o
2181 response += '%2d %-32s %s\n' % (idx, o_f, ps)
2182 return response
2183
2184
2185def vnc_read_obj(vnc, obj_type, fq_name):
2186 method_name = obj_type.replace('-', '_')
2187 method = getattr(vnc, "%s_read" % (method_name))
2188 try:
2189 return method(fq_name=fq_name)
2190 except NoIdError:
2191 print '%s %s not found!' % (obj_type, fq_name)
2192 return None
2193
2194
2195def rbac_show_group(name, uuid, **kwargs):
2196 '''
2197 Show specific RBAC group
2198
2199
2200 CLI Example
2201 .. code-block:: bash
2202 salt-call contrail.rbac_show_group name \
2203 'default-domain:default-project:default'
2204
2205 params:
2206 name - one of pair {name, uuid} addresing to access-list
2207 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2208 including domain and project
2209
2210 '''
2211 vnc = _auth(**kwargs)
2212 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2213 ret = {'name': fq_name,
2214 'changes': {},
2215 'result': True,
2216 'comment': ''}
2217 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2218 if not rg:
2219 ret['comment'] = 'No rules found'
2220 return ret
2221
2222 ret['comment'] = show_rbac_rules(rg.get_api_access_list_entries())
2223 return ret
2224
2225
2226def rbac_create_group(uuid, **kwargs):
2227 '''
2228 Create RBAC group
2229
2230 CLI Example
2231 .. code-block:: bash
2232 salt-call contrail.rbac_create_group name \
2233 'default-domain:default-project:default'
2234
2235 params:
2236 name - one of pair {name, uuid} addresing to access-list
2237 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2238 including domain and project
2239
2240 '''
2241 vnc = _auth(**kwargs)
2242 fq_name = uuid.split(':')
2243 ret = {'name': fq_name,
2244 'changes': {},
2245 'result': True,
2246 'comment': ''}
2247 if len(fq_name) != 2 and len(fq_name) != 3:
2248 ret['comment'] = 'Fully qualified name of rbac group expected'
2249 return ret
2250
2251 name = fq_name[-1]
2252
2253 if len(fq_name) == 2:
2254 if fq_name[0] == 'default-global-system-config':
2255 pobj = vnc.global_system_config_read(fq_name=fq_name[0:1])
2256 else:
2257 pobj = vnc.domain_read(fq_name=fq_name[0:1])
2258 else:
2259 pobj = vnc.project_read(fq_name=fq_name[0:2])
2260
2261 rentry = RbacRuleEntriesType([])
2262 rg = ApiAccessList(name, parent_obj=pobj, api_access_list_entries=rentry)
2263
2264 if __opts__['test']:
2265 ret['result'] = None
2266 ret['comment'] = "RBAC group " + uuid + " will be created"
2267
2268 return ret
2269 else:
2270 vnc.api_access_list_create(rg)
2271 rg2 = vnc.api_access_list_read(fq_name=fq_name)
2272 rge = rg.get_api_access_list_entries()
2273 show_rbac_rules(rge)
2274 ret['comment'] = "RBAC group " + uuid + " has been created"
2275
2276 return ret
2277
2278
2279def rbac_delete_group(name, uuid, **kwargs):
2280 '''
2281 Delete RBAC group
2282
2283 CLI Example
2284 .. code-block:: bash
2285 salt-call contrail.rbac_delete_group name \
2286 'default-domain:default-project:default'
2287
2288 params:
2289 name - one of pair {name, uuid} addresing to access-list
2290 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2291 including domain and project
2292
2293 '''
2294 vnc = _auth(**kwargs)
2295 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2296 ret = {'name': fq_name,
2297 'changes': {},
2298 'result': True,
2299 'comment': ''}
2300 if len(fq_name) != 2 and len(fq_name) != 3:
2301 ret['comment'] = 'Fully qualified name of rbac group expected'
2302 return ret
2303 name = fq_name[-1]
2304
2305 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2306 if not rg:
2307 ret['comment'] = 'No rules found'
2308 return ret
2309 rge = rg.get_api_access_list_entries()
2310 show_rbac_rules(rge)
2311
2312 if __opts__['test']:
2313 ret['result'] = None
2314 ret['comment'] = "RBAC group " + uuid + " will be deleted"
2315
2316 return ret
2317 else:
2318 vnc.api_access_list_delete(fq_name=fq_name)
2319 ret['comment'] = "RBAC group " + uuid + " has been deleted"
2320
2321 return ret
2322
2323
2324def rbac_add_rule(name, uuid, add_rule, **kwargs):
2325 '''
2326 Add rule to specific RBAC group
2327
2328 CLI Example
2329 .. code-block:: bash
2330 salt-call contrail.rbac_add_rule name \
2331 'default-domain:default-project:default' \
2332 '* admin:CRUD'
2333
2334 params:
2335 name - one of pair {name, uuid} addresing to access-list
2336 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2337 including domain and project
2338 rule(str) - Appropriate RBAC-based rule in format '<object, field> \
2339 list of <role:CRUD>' to be added
2340
2341 '''
2342 vnc = _auth(**kwargs)
2343 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2344 rule = build_rule(add_rule)
2345 ret = {'name': fq_name,
2346 'changes': {},
2347 'result': True,
2348 'comment': ''}
2349 if rule is None:
2350 ret['comment'] = 'A rule string must be specified for this operation'
2351 return ret
2352
2353 # rbac rule entry consists of one or more rules
2354 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2355 if not rg:
2356 ret['comment'] = 'No rules found'
2357 return ret
2358
2359 rge = rg.get_api_access_list_entries()
2360 if rge is None:
2361 rge = RbacRuleEntriesType([])
2362 show_rbac_rules(rge)
2363
2364 # avoid duplicates
2365 match = find_rule(rge, rule)
2366 if not match:
2367 rge.add_rbac_rule(rule)
2368 else:
2369 build_perms(rge.rbac_rule[match[0]-1], match[3])
2370
2371 show_rbac_rules(rge)
2372
2373 if __opts__['test']:
2374 ret['result'] = None
2375 ret['comment'] = "Rule " + add_rule
2376 ret['comment'] += " will be created for RBAC group " + uuid
2377
2378 return ret
2379 else:
2380 rg.set_api_access_list_entries(rge)
2381 vnc.api_access_list_update(rg)
2382 ret['comment'] = "Rule " + add_rule
2383 ret['comment'] += " has been added for RBAC group " + uuid
2384
2385 return ret
2386
2387
2388def rbac_delete_rule(name, uuid, del_rule, **kwargs):
2389 '''
2390 Delete rule to specific RBAC group
2391
2392 CLI Example
2393 .. code-block:: bash
2394 salt-call contrail.rbac_delete_rule name \
2395 'default-domain:default-project:default' \
2396 '* admin:CRUD'
2397
2398 params:
2399 name - one of pair {name, uuid} addresing to access-list
2400 uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \
2401 including domain and project
2402 rule(str) - Appropriate RBAC-based rule in format '<object, field> \
2403 list of <role:CRUD>' to be deleted
2404
2405 '''
2406 vnc = _auth(**kwargs)
2407 fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':')
2408 rg = vnc_read_obj(vnc, 'api-access-list', fq_name)
2409 ret = {'name': fq_name,
2410 'changes': {},
2411 'result': True,
2412 'comment': ''}
2413 if not rg:
2414 ret['comment'] = 'No rules found'
2415 return ret
2416 rge = rg.get_api_access_list_entries()
2417 show_rbac_rules(rge)
2418
2419 del_idx = re.match("^[0-9]+$", del_rule)
2420 if del_idx:
2421 del_idx = int(del_idx.group())
2422 rc = len(rge.rbac_rule)
2423 if del_idx > rc or del_idx < 1:
2424 ret['comment'] = 'Invalid rule index to delete.'
2425 ret['comment'] += 'Value must be 1-%d' % rc
2426 return ret
2427 match = (del_idx, True)
2428 else:
2429 rule = build_rule(del_rule)
2430 match = find_rule(rge, rule)
2431
2432 if not match:
2433 ret['comment'] = "Rule not found. Unchanged"
2434 return ret
2435 elif match[1]:
2436 rge.rbac_rule.pop(match[0]-1)
2437 else:
2438 build_perms(rge.rbac_rule[match[0]-1], match[2])
2439 show_rbac_rules(rge)
2440
2441 if __opts__['test']:
2442 ret['result'] = None
2443 ret['comment'] = "Rule " + del_rule
2444 ret['comment'] += " will be cleared from RBAC group " + uuid
2445
2446 return ret
2447 else:
2448 rg.set_api_access_list_entries(rge)
2449 vnc.api_access_list_update(rg)
2450 ret['comment'] = "Rule " + del_rule
2451 ret['comment'] += " has been cleared from RBAC group " + uuid
2452
2453 return ret