| #!/usr/bin/python |
| # Copyright 2017 Mirantis, Inc. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| from vnc_api.vnc_api import * |
| from vnc_api.gen.resource_xsd import * |
| from cfgm_common.exceptions import * |
| from cfgm_common.rbaclib import * |
| import cfgm_common |
| |
| from netaddr import IPNetwork |
| from vnc_api.vnc_api import PhysicalRouter, PhysicalInterface, LogicalInterface |
| from vnc_api.vnc_api import EncapsulationPrioritiesType |
| from vnc_api.vnc_api import VirtualMachineInterface, MacAddressesType |
| from vnc_api.vnc_api import ServiceApplianceSet, KeyValuePairs, KeyValuePair |
| |
| try: |
| from vnc_api import vnc_api |
| from vnc_api.vnc_api import LinklocalServiceEntryType, \ |
| LinklocalServicesTypes, GlobalVrouterConfig, GlobalSystemConfig |
| from vnc_api.gen.resource_client import VirtualRouter, AnalyticsNode, \ |
| ConfigNode, DatabaseNode, BgpRouter, VirtualNetwork, FloatingIpPool |
| from vnc_api.gen.resource_xsd import AddressFamilies, BgpSessionAttributes, \ |
| BgpSession, BgpPeeringAttributes, BgpRouterParams, AuthenticationData, \ |
| AuthenticationKeyItem, VirtualNetworkType, IpamSubnetType, SubnetType, \ |
| VnSubnetsType, RouteTargetList, ShareType |
| |
| HAS_CONTRAIL = True |
| except ImportError: |
| HAS_CONTRAIL = False |
| |
| |
| try: |
| from vnc_api.gen.resource_xsd import GracefulRestartParametersType |
| HAS_OLD = False |
| except ImportError: |
| HAS_OLD = True |
| |
| __opts__ = {} |
| |
| |
| def __virtual__(): |
| ''' |
| Only load this module if vnc_api library is installed. |
| ''' |
| if HAS_CONTRAIL: |
| return 'contrail' |
| |
| return False |
| |
| |
| def _auth(**kwargs): |
| ''' |
| Set up Contrail API credentials. |
| ''' |
| user = kwargs.get('user') |
| password = kwargs.get('password') |
| tenant_name = kwargs.get('project') |
| api_host = kwargs.get('api_server_ip') |
| api_port = kwargs.get('api_server_port') |
| api_base_url = kwargs.get('api_base_url') |
| use_ssl = False |
| auth_host = kwargs.get('auth_host_ip') |
| vnc_lib = vnc_api.VncApi(user, password, tenant_name, |
| api_host, api_port, api_base_url, wait_for_connect=True, |
| api_server_use_ssl=use_ssl, auth_host=auth_host) |
| |
| return vnc_lib |
| |
| |
| def _get_config(vnc_client, global_system_config='default-global-system-config'): |
| try: |
| gsc_obj = vnc_client.global_system_config_read(id=global_system_config) |
| except vnc_api.NoIdError: |
| gsc_obj = vnc_client.global_system_config_read(fq_name_str=global_system_config) |
| except: |
| gsc_obj = None |
| |
| return gsc_obj |
| |
| |
| def _get_rt_inst_obj(vnc_client): |
| # TODO pick fqname hardcode from common |
| rt_inst_obj = vnc_client.routing_instance_read( |
| fq_name=['default-domain', 'default-project', |
| 'ip-fabric', '__default__']) |
| |
| return rt_inst_obj |
| |
| |
| def _get_fq_name(vnc_client, resource_name, project_name, domain='default-domain'): |
| res = [domain] |
| if project_name: |
| res.append(project_name) |
| if resource_name: |
| res.append(resource_name) |
| return res |
| |
| |
| def _get_project_obj(vnc_client, name, domain='default-domain'): |
| return vnc_client.project_read(fq_name=[domain, name]) |
| |
| |
| def _get_ip(ip_w_pfx): |
| return str(IPNetwork(ip_w_pfx).ip) |
| |
| |
| def _create_floating_ip_pool(name, vn_obj, **kwargs): |
| vnc_client = _auth(**kwargs) |
| # create floating ip pool |
| fip_obj = FloatingIpPool(name=name, parent_obj=vn_obj) |
| vnc_client.floating_ip_pool_create(fip_obj) |
| |
| |
| def virtual_router_list(**kwargs): |
| ''' |
| Return a list of all Contrail virtual routers |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_router_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| vrouter_objs = vnc_client._objects_list('virtual-router', detail=True) |
| for vrouter_obj in vrouter_objs: |
| ret[vrouter_obj.name] = { |
| 'ip_address': vrouter_obj.virtual_router_ip_address, |
| 'dpdk_enabled': vrouter_obj.virtual_router_dpdk_enabled, |
| 'uuid': vrouter_obj.uuid |
| |
| } |
| return ret |
| |
| |
| def virtual_router_get(name, **kwargs): |
| ''' |
| Return a specific Contrail virtual router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_router_get cmp01 |
| ''' |
| ret = {} |
| vrouter_objs = virtual_router_list(**kwargs) |
| if name in vrouter_objs: |
| ret[name] = vrouter_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving virtual router.'} |
| return ret |
| |
| |
| def virtual_router_create(name, ip_address, router_type=None, dpdk_enabled=False, **kwargs): |
| ''' |
| Create specific Contrail virtual router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_router_create cmp02 10.10.10.102 |
| router_types: |
| - tor-agent |
| - tor-service-node |
| - embedded |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| vrouter_objs = virtual_router_list(**kwargs) |
| router_types = ['tor-agent', 'tor-service-node', 'embedded'] |
| if router_type not in router_types: |
| router_type = None |
| if name in vrouter_objs: |
| vrouter = virtual_router_get(name) |
| vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[name]['uuid']) |
| changes = {} |
| if vrouter_obj.get_virtual_router_ip_address() != ip_address: |
| changes['ip_address'] = {'from': vrouter_obj.get_virtual_router_ip_address(), "to": ip_address} |
| vrouter_obj.set_virtual_router_ip_address(ip_address) |
| if vrouter_obj.get_virtual_router_type() != router_type: |
| changes['router_type'] = {"from": vrouter_obj.get_virtual_router_type(), "to": router_type} |
| vrouter_obj.set_virtual_router_type(router_type) |
| if vrouter_obj.get_virtual_router_dpdk_enabled() != dpdk_enabled: |
| changes['dpdk_enabled'] = {"from": vrouter_obj.get_virtual_router_dpdk_enabled(), "to": dpdk_enabled} |
| vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled) |
| if len(changes) != 0: |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Virtual router " + name + " will be updated" |
| else: |
| ret['comment'] = "VirtualRouter " + name + " has been updated" |
| ret['changes'] = changes |
| vnc_client.virtual_router_update(vrouter_obj) |
| return ret |
| ret['comment'] = 'Virtual router ' + name + ' already exists and is updated' |
| return ret |
| else: |
| vrouter_obj = VirtualRouter( |
| name, gsc_obj, |
| virtual_router_ip_address=ip_address, |
| virtual_router_type=router_type) |
| vrouter_obj.set_virtual_router_dpdk_enabled(dpdk_enabled) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "VirtualRouter " + name + " will be created" |
| else: |
| vnc_client.virtual_router_create(vrouter_obj) |
| ret['comment'] = "VirtualRouter " + name + " has been created" |
| ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def virtual_router_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail virtual router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_router_delete cmp01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| vrouter_obj = VirtualRouter(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "VirtualRouter " + name + " will be deleted" |
| else: |
| vnc_client.virtual_router_delete(fq_name=vrouter_obj.get_fq_name()) |
| ret['comment'] = "VirtualRouter " + name + " has been deleted" |
| ret['changes'] = {'VirtualRouter': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def physical_router_list(**kwargs): |
| ''' |
| Return a list of all Contrail physical routers |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_router_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| prouter_objs = vnc_client._objects_list('physical-router', detail=True) |
| for prouter_obj in prouter_objs: |
| ret[prouter_obj.name] = { |
| 'uuid': prouter_obj._uuid, |
| 'management_ip': prouter_obj._physical_router_management_ip, |
| 'product_name': prouter_obj._physical_router_product_name, |
| } |
| |
| return ret |
| |
| |
| def physical_router_get(name, **kwargs): |
| ''' |
| Return a specific Contrail physical router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_router_get router_name |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| prouter_objs = vnc_client._objects_list('physical-router', detail=True) |
| for prouter_obj in prouter_objs: |
| if name == prouter_obj.name: |
| ret[name] = prouter_obj.__dict__ |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving physical router.'} |
| return ret |
| |
| |
| def physical_router_create(name, parent_type=None, |
| management_ip=None, |
| dataplane_ip=None, # VTEP address in web GUI |
| vendor_name=None, |
| product_name=None, |
| vnc_managed=None, |
| junos_service_ports=None, |
| agents=None, **kwargs): |
| ''' |
| Create specific Contrail physical router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| 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']" |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| prouter_objs = physical_router_list(**kwargs) |
| if name in prouter_objs: |
| prouter = physical_router_get(name) |
| changes = {} |
| prouter_obj = vnc_client._object_read('physical-router', id=prouter[name]['_uuid']) |
| if prouter_obj.physical_router_management_ip != management_ip: |
| changes['management_ip'] = {'from': prouter_obj.physical_router_management_ip, "to": management_ip} |
| prouter_obj.set_physical_router_management_ip(management_ip) |
| if prouter_obj.physical_router_dataplane_ip != dataplane_ip: |
| changes['dataplane_ip'] = {'from': prouter_obj.physical_router_dataplane_ip, "to": dataplane_ip} |
| prouter_obj.set_physical_router_dataplane_ip(dataplane_ip) |
| if prouter_obj.get_physical_router_vendor_name() != vendor_name: |
| changes['vendor_name'] = {'from': prouter_obj.get_physical_router_vendor_name(), "to": vendor_name} |
| prouter_obj.set_physical_router_vendor_name(vendor_name) |
| if prouter_obj.get_physical_router_product_name() != product_name: |
| changes['product_name'] = {'from': prouter_obj.get_physical_router_product_name(), "to": product_name} |
| prouter_obj.set_physical_router_product_name(product_name) |
| if prouter_obj.get_physical_router_vnc_managed() != vnc_managed: |
| changes['vnc_managed'] = {'from': prouter_obj.get_physical_router_vnc_managed(), "to": vnc_managed} |
| prouter_obj.set_physical_router_vnc_managed(vnc_managed) |
| if prouter_obj.get_physical_router_junos_service_ports() != junos_service_ports: |
| changes['junos_service_ports'] = {'from': prouter_obj.get_physical_router_junos_service_ports(), |
| 'to': junos_service_ports} |
| prouter_obj.set_physical_router_junos_service_ports(junos_service_ports) |
| |
| if len(changes) != 0: |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Physical router " + name + " will be updated" |
| else: |
| ret['comment'] = 'Physical router ' + name + ' already exists and is updated' |
| return ret |
| |
| vrouter_objs = vnc_client._objects_list('virtual-router', detail=True) # all vrouter objects |
| c_agents = [] # referenced vrouters |
| for c_agent in prouter_obj.get_virtual_router_refs(): |
| c_agents.append(c_agent['uuid']) |
| # agent_objs = [] # required state of references |
| for vrouter_obj in vrouter_objs: |
| if vrouter_obj._display_name in agents and vrouter_obj._uuid not in c_agents: |
| prouter_obj.add_virtual_router(vrouter_obj) |
| changes['vrouter ' + vrouter_obj._display_name] = "Reference added" |
| if vrouter_obj._display_name not in agents and vrouter_obj._uuid in c_agents: |
| prouter_obj.del_virtual_router(vrouter_obj) |
| changes['vrouter ' + vrouter_obj._display_name] = "Reference removed" |
| vnc_client.physical_router_update(prouter_obj) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "VirtualRouter " + name + " will be created" |
| else: |
| vnc_client.virtual_router_create(vrouter_obj) |
| ret['comment'] = "VirtualRouter " + name + " has been created" |
| ret['changes'] = {'VirtualRouter': {'old': '', 'new': name}} |
| |
| if len(changes) == 0: |
| ret['comment'] = "Physical router exists and is updated" |
| return ret |
| else: |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Physical router " + name + " will be created" |
| return ret |
| prouter_obj = PhysicalRouter( |
| name=name, |
| parent_obj=None, |
| physical_router_management_ip=management_ip, |
| physical_router_dataplane_ip=dataplane_ip, |
| physical_router_vendor_name=vendor_name, |
| physical_router_product_name=product_name, |
| physical_router_vnc_managed=vnc_managed, |
| physical_router_junos_service_ports=junos_service_ports, |
| ) |
| for agent in agents: |
| vrouter = virtual_router_get(agent) |
| vrouter_obj = vnc_client._object_read('virtual-router', id=vrouter[agent]['uuid']) |
| prouter_obj.add_virtual_router(vrouter_obj) |
| vnc_client.physical_router_create(prouter_obj) |
| ret['comment'] = "Physical router " + name + " has been created" |
| ret['changes'] = {'PhysicalRouter': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def physical_router_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail physical router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_router_delete router_name |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| prouter_obj = PhysicalRouter(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Physical router " + name + " will be deleted" |
| else: |
| vnc_client.physical_router_delete(fq_name=prouter_obj.get_fq_name()) |
| ret['comment'] = "Physical router " + name + " has been deleted" |
| ret['changes'] = {'Physical router': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def physical_interface_list(**kwargs): |
| ''' |
| Return a list of all Contrail physical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_interface_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| pinterface_objs = vnc_client._objects_list('physical-interface', detail=True) |
| for pinterface_obj in pinterface_objs: |
| ret[pinterface_obj.name] = { |
| 'uuid': pinterface_obj._uuid, |
| 'fq_name': pinterface_obj.fq_name, |
| 'parent_type': pinterface_obj.parent_type, |
| } |
| |
| return ret |
| |
| |
| def physical_interface_get(name, physical_router, **kwargs): |
| ''' |
| Return a specific Contrail physical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_interface_get interface_name physical_router_name |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| pinterf_objs = vnc_client._objects_list('physical-interface', detail=True) |
| for pinterf_obj in pinterf_objs: |
| if name == pinterf_obj.name and physical_router in pinterf_obj.fq_name: |
| ret[name] = pinterf_obj.__dict__ |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving physical interface.'} |
| return ret |
| |
| |
| def physical_interface_create(name, physical_router, **kwargs): |
| ''' |
| Create specific Contrail physical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_interface_create ge-0/0/10 physical_router_name |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| pinterf_obj = physical_interface_get(name, physical_router, **kwargs) |
| if 'Error' not in pinterf_obj: |
| ret['comment'] = 'Physical interface ' + name + ' on ' + physical_router + ' already exists' |
| return ret |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Physical interface " + name + " will be created" |
| return ret |
| |
| prouter = physical_router_get(physical_router) |
| prouter_obj = vnc_client._object_read('physical-router', id=prouter[physical_router]['_uuid']) |
| pinterf_obj = PhysicalInterface(name, prouter_obj) |
| vnc_client.physical_interface_create(pinterf_obj) |
| ret['comment'] = "Physical interface " + name + " has been created" |
| ret['changes'] = {'Physical interface': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def physical_interface_delete(name, physical_router, **kwargs): |
| ''' |
| Delete specific Contrail physical interface |
| |
| CLI Example: |
| .. code-block:: bash |
| |
| salt '*' contrail.physical_interface_delete ge-0/0/0 phr01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| piface = physical_interface_get(name, physical_router) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Physical interface " + name + " will be deleted" |
| else: |
| vnc_client.physical_interface_delete(id=piface[name]['_uuid']) |
| ret['comment'] = "Physical router " + name + " has been deleted" |
| ret['changes'] = {'Physical router': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def logical_interface_list(**kwargs): |
| ''' |
| Return a list of all Contrail logical interfaces |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.logical_interface_list |
| ''' |
| ret = [] |
| vnc_client = _auth(**kwargs) |
| liface_objs = vnc_client._objects_list('logical-interface', detail=True) |
| for liface_obj in liface_objs: |
| ret.append({ |
| 'name': liface_obj.name, |
| 'uuid': liface_obj._uuid, |
| 'fq_name': liface_obj.fq_name, |
| 'parent_type': liface_obj.parent_type, |
| }) |
| return ret |
| |
| |
| def logical_interface_get(name, parent_names, parent_type=None, **kwargs): |
| ''' |
| Return a specific Contrail logical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01'] |
| or |
| salt '*' contrail.logical_interface_get ge-0/0/0.10 ['ge-0/0/0','phr01'] |
| or |
| salt '*' contrail.logical_interface_get ge-0/0/0.10 ['phr01'] parent_type=physcal-interface |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| liface_objs = vnc_client._objects_list('logical-interface', detail=True) |
| count = 0 |
| for liface_obj in liface_objs: |
| if name == liface_obj.name and set(parent_names).issubset(liface_obj.fq_name): |
| if parent_type and parent_type == liface_obj.parent_type: |
| count += 1 |
| ret[liface_obj.name] = liface_obj.__dict__ |
| if not parent_type: |
| count += 1 |
| ret[liface_obj.name] = liface_obj.__dict__ |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving logical interface.'} |
| if count > 1: |
| return { |
| 'Error': 'Error Was found more then one logical interface. Please put more parent_name or put parent_type to chose one of them.'} |
| return ret |
| |
| |
| def logical_interface_create(name, parent_names, parent_type='physical-interface', vlan_tag=None, interface_type="l2", |
| vmis=None, **kwargs): |
| ''' |
| Create specific Contrail logical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| 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 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| |
| liface_obj = logical_interface_get(name, parent_names, parent_type, **kwargs) |
| if 'Error' not in liface_obj: |
| ret['comment'] = 'Logical interface ' + name + ' already exists' |
| else: |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Logical interface " + name + " will be created" |
| return ret |
| parent_obj = None |
| for router in parent_names: |
| parent_router = physical_router_get(router) |
| if 'Error' not in parent_router: |
| parent_obj = vnc_client._object_read('physical-router', id=parent_router[router]['_uuid']) |
| break |
| if not parent_obj: |
| ret['result'] = False |
| ret['comment'] = 'Physical router have to be defined' |
| return ret |
| if parent_type == 'physical-interface': |
| for interface in parent_names: |
| parent_interface = physical_interface_get(interface, parent_obj.name) |
| if 'Error' not in parent_interface: |
| parent_obj = vnc_client._object_read('physical-interface', id=parent_interface[interface]['_uuid']) |
| break |
| if interface_type.lower() == "l3": |
| ret['result'] = False |
| ret['comment'] = "Virtual Network have to be defined for L3 interface type" |
| return ret |
| |
| liface_obj = LogicalInterface(name, parent_obj, vlan_tag, interface_type.lower()) |
| |
| if vmis: |
| for vmi_name, vmi in vmis.iteritems(): |
| vmi = vnc_client.virtual_machine_interface_read( |
| fq_name=_get_fq_name(vnc_client, resource_name=vmi_name, |
| project_name=kwargs.get('tenant', 'admin'))) |
| liface_obj.add_virtual_machine_interface(vmi) |
| vnc_client.logical_interface_create(liface_obj) |
| |
| ret['comment'] = "Logical interface " + name + " has been created" |
| ret['changes'] = {'Logical interface': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def logical_interface_delete(name, parent_names, parent_type=None, **kwargs): |
| ''' |
| Delete specific Contrail logical interface |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['ge-0/0/0','phr01'] |
| or |
| salt '*' contrail.logical_interface_delete ge-0/0/0.12 ['phr01'] parent_type=physical-router |
| |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| liface = logical_interface_get(name, parent_names, parent_type) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Logical interface " + name + " will be deleted" |
| return ret |
| vnc_client.logical_interface_delete(id=liface[name]['_uuid']) |
| ret['comment'] = "Logical interface " + name + " has been deleted" |
| ret['changes'] = {'LogicalInterface ': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def global_vrouter_config_list(**kwargs): |
| ''' |
| Return a list of all Contrail global vrouter configs |
| |
| CLI Example: |
| |
| .. code-block:: bash" |
| |
| salt '*' global_vrouter_config_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| vrouter_conf_objs = vnc_client._objects_list('global-vrouter-config', detail=True) |
| for vrouter_conf_obj in vrouter_conf_objs: |
| ret[vrouter_conf_obj._display_name] = vrouter_conf_obj.__dict__ |
| return ret |
| |
| |
| def global_vrouter_config_get(name, **kwargs): |
| ''' |
| Return a specific Contrail global vrouter config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_vrouter_get global-vrouter-config |
| ''' |
| ret = {} |
| vrouter_conf_objs = global_vrouter_config_list(**kwargs) |
| if name in vrouter_conf_objs: |
| ret[name] = vrouter_conf_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving global vrouter config.'} |
| return ret |
| |
| |
| def global_vrouter_config_create(name, parent_type, encap_priority, vxlan_vn_id_mode, flow_export_rate, *fq_names, **kwargs): |
| ''' |
| Create specific Contrail global vrouter config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_vrouter_config_create name=global-vrouter-config parent_type=global-system-config encap_priority="MPLSoUDP,MPLSoGRE" vxlan_vn_id_mode="automatic" fq_names="['default-global-system-config', 'default-global-vrouter-config']" |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| # gsc_obj = _get_config(vnc_client) |
| vrouter_conf_objs = global_vrouter_config_list(**kwargs) |
| if name in vrouter_conf_objs: |
| ret['comment'] = 'Global vrouter config ' + name + ' already exists' |
| return ret |
| else: |
| vrouter_conf_obj = GlobalVrouterConfig( |
| name=name, |
| parent_obj=None, |
| encapsulation_priorities=EncapsulationPrioritiesType(encapsulation=encap_priority.split(",")), |
| fq_name=fq_names, |
| vxlan_network_identifier_mode=vxlan_vn_id_mode, |
| parent_type=parent_type, |
| flow_export_rate=flow_export_rate, |
| ) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Global vRouter config " + name + " will be created" |
| return ret |
| vnc_client.global_vrouter_config_create(vrouter_conf_obj) |
| ret['comment'] = "Global vRouter config " + name + " has been created" |
| ret['changes'] = {'Global vRouter config': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def global_vrouter_config_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail global vrouter config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_vrouter_config_delete global-vrouter-config |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| vrouter_conf_obj = GlobalVrouterConfig(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Global vRouter config " + name + " will be deleted" |
| return ret |
| vnc_client.global_vrouter_config_delete( |
| fq_name=vrouter_conf_obj.get_fq_name()) |
| ret['comment'] = "Global vRouter config " + name + " has been deleted" |
| ret['changes'] = {'Global vRouter config': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def analytics_node_list(**kwargs): |
| ''' |
| Return a list of all Contrail analytics nodes |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.analytics_node_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| node_objs = vnc_client._objects_list('analytics-node', detail=True) |
| for node_obj in node_objs: |
| ret[node_obj.name] = node_obj.__dict__ |
| return ret |
| |
| |
| def analytics_node_get(name, **kwargs): |
| ''' |
| Return a specific Contrail analytics node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.analytics_node_get nal01 |
| ''' |
| ret = {} |
| vrouter_objs = analytics_node_list(**kwargs) |
| if name in vrouter_objs: |
| ret[name] = vrouter_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving analytics node.'} |
| return ret |
| |
| |
| def analytics_node_create(name, ip_address, **kwargs): |
| ''' |
| Create specific Contrail analytics node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.analytics_node_create ntw03 10.10.10.103 |
| ''' |
| |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| analytics_node_objs = analytics_node_list(**kwargs) |
| if name in analytics_node_objs: |
| ret['comment'] = 'Analytics node %s already exists' |
| return ret |
| else: |
| analytics_node_obj = AnalyticsNode( |
| name, gsc_obj, |
| analytics_node_ip_address=ip_address) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "AnalyticsNode " + name + " will be created" |
| return ret |
| vnc_client.analytics_node_create(analytics_node_obj) |
| ret['comment'] = "AnalyticsNode " + name + " has been created" |
| ret['changes'] = {'Analytics Node': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def analytics_node_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail analytics node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.analytics_node_delete cmp01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| analytics_node_obj = AnalyticsNode(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "AnalyticsNode " + name + " will be deleted" |
| return ret |
| vnc_client.analytics_node_delete( |
| fq_name=analytics_node_obj.get_fq_name()) |
| ret['comment'] = "AnalyticsNode " + name + " has been deleted" |
| ret['changes'] = {'Analytics Node': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def config_node_list(**kwargs): |
| ''' |
| Return a list of all Contrail config nodes |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.config_node_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| node_objs = vnc_client._objects_list('config-node', detail=True) |
| for node_obj in node_objs: |
| ret[node_obj.name] = node_obj.__dict__ |
| return ret |
| |
| |
| def config_node_get(name, **kwargs): |
| ''' |
| Return a specific Contrail config node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.config_node_get nal01 |
| ''' |
| ret = {} |
| vrouter_objs = config_node_list(**kwargs) |
| if name in vrouter_objs: |
| ret[name] = vrouter_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving config node.'} |
| return ret |
| |
| |
| def config_node_create(name, ip_address, **kwargs): |
| ''' |
| Create specific Contrail config node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.config_node_create ntw03 10.10.10.103 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| config_node_objs = config_node_list(**kwargs) |
| if name in config_node_objs: |
| ret['comment'] = 'Config node ' + name + ' already exists' |
| return ret |
| else: |
| config_node_obj = ConfigNode( |
| name, gsc_obj, |
| config_node_ip_address=ip_address) |
| if __opts__['test']: |
| ret['comment'] = "ConfigNode " + name + " will be created" |
| ret['result'] = None |
| return ret |
| vnc_client.config_node_create(config_node_obj) |
| ret['comment'] = "ConfigNode " + name + " has been created" |
| ret['changes'] = {'ConfigNode': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def config_node_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail config node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.config_node_delete cmp01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| config_node_obj = ConfigNode(name, gsc_obj) |
| if __opts__['test']: |
| ret['comment'] = "ConfigNode " + name + " will be deleted" |
| ret['result'] = None |
| return ret |
| vnc_client.config_node_delete( |
| fq_name=config_node_obj.get_fq_name()) |
| ret['comment'] = "ConfigNode " + name + " has been deleted" |
| ret['changes'] = {'ConfigNode': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def bgp_router_list(**kwargs): |
| ''' |
| Return a list of all Contrail BGP routers |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.bgp_router_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| bgp_router_objs = vnc_client._objects_list('bgp-router', detail=True) |
| for bgp_router_obj in bgp_router_objs: |
| ret[bgp_router_obj.name] = bgp_router_obj.__dict__ |
| return ret |
| |
| |
| def bgp_router_get(name, **kwargs): |
| ''' |
| Return a specific Contrail BGP router |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.bgp_router_get nal01 |
| ''' |
| ret = {} |
| bgp_router_objs = bgp_router_list(**kwargs) |
| if name in bgp_router_objs: |
| ret[name] = bgp_router_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving BGP router.'} |
| return ret |
| |
| |
| def bgp_router_create(name, type, ip_address, asn=64512, key_type=None, key=None, **kwargs): |
| ''' |
| Create specific Contrail control node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.bgp_router_create ntw03 control-node 10.10.10.103 |
| salt '*' contrail.bgp_router_create mx01 router 10.10.10.105 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| |
| address_families = ['route-target', 'inet-vpn', 'e-vpn', 'erm-vpn', |
| 'inet6-vpn'] |
| if type != 'control-node': |
| address_families.remove('erm-vpn') |
| |
| key_type = None if key_type == 'None' else key_type |
| key = None if key == 'None' else key |
| |
| bgp_addr_fams = AddressFamilies(address_families) |
| bgp_sess_attrs = [ |
| BgpSessionAttributes(address_families=bgp_addr_fams)] |
| bgp_sessions = [BgpSession(attributes=bgp_sess_attrs)] |
| bgp_peering_attrs = BgpPeeringAttributes(session=bgp_sessions) |
| rt_inst_obj = _get_rt_inst_obj(vnc_client) |
| |
| bgp_auth_data = None |
| |
| if type == 'control-node': |
| vendor = 'contrail' |
| elif type == 'router': |
| vendor = 'mx' |
| if key_type == 'md5': |
| key_id = 0 |
| key_items = AuthenticationKeyItem(key_id, key) |
| bgp_auth_data = AuthenticationData(key_type, [key_items]) |
| else: |
| vendor = 'unknown' |
| |
| router_params = BgpRouterParams(router_type=type, |
| vendor=vendor, autonomous_system=int(asn), |
| identifier=_get_ip(ip_address), |
| address=_get_ip(ip_address), |
| port=179, address_families=bgp_addr_fams, |
| auth_data=bgp_auth_data) |
| |
| bgp_router_objs = bgp_router_list(**kwargs) |
| if name in bgp_router_objs: |
| bgp_router_obj = vnc_client._object_read('bgp-router', id=bgp_router_objs[name]['_uuid']) |
| |
| if bgp_router_obj.bgp_router_parameters.autonomous_system != asn: |
| ret['changes'].update({"autonomous_system": {'old': bgp_router_obj.bgp_router_parameters.autonomous_system, 'new': asn}}) |
| if bgp_router_obj.bgp_router_parameters.vendor != vendor: |
| ret['changes'].update({"vendor": {'old': bgp_router_obj.bgp_router_parameters.vendor, 'new': vendor}}) |
| if bgp_router_obj.bgp_router_parameters.address != ip_address: |
| ret['changes'].update({"ip_address": {'old': bgp_router_obj.bgp_router_parameters.address, 'new': ip_address}}) |
| try: |
| if bgp_router_obj.bgp_router_parameters.auth_data.key_type != key_type: |
| ret['changes'].update({"key_type": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_type, 'new': key_type}}) |
| except: |
| if key_type != None: |
| ret['changes'].update({"key_type": {'old': None, 'new': key_type}}) |
| if key_type == 'md5': |
| try: |
| if bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key != key: |
| ret['changes'].update({"key_type": {'old': bgp_router_obj.bgp_router_parameters.auth_data.key_items[0].key, 'new': key}}) |
| except: |
| ret['changes'].update({"key_type": {'old': None, 'new': key}}) |
| |
| if len(ret['changes']) == 0: |
| return ret |
| |
| bgp_router_obj.set_bgp_router_parameters(router_params) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "BGP router " + name + " will be updated" |
| return ret |
| vnc_client.bgp_router_update(bgp_router_obj) |
| ret['comment'] = "BGP router " + name + " has been updated" |
| return ret |
| else: |
| bgp_router_obj = BgpRouter(name, rt_inst_obj, bgp_router_parameters=router_params) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "BGP router " + name + " will be created" |
| return ret |
| vnc_client.bgp_router_create(bgp_router_obj) |
| ret['comment'] = "BGP router " + name + " has been created" |
| ret['changes'] = {'BGP router': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def bgp_router_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail control node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.bgp_router_delete mx01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "BGP router " + name + " will be deleted" |
| return ret |
| |
| bgp_router = bgp_router_get(name) |
| if name in bgp_router: |
| vnc_client.bgp_router_delete(fq_name=bgp_router[name]['fq_name']) |
| ret['comment'] = "BGP router " + name + " has been deleted" |
| ret['changes'] = {'BGP router': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def database_node_list(**kwargs): |
| ''' |
| Return a list of all Contrail database nodes |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.database_node_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| node_objs = vnc_client._objects_list('database-node', detail=True) |
| for node_obj in node_objs: |
| ret[node_obj.name] = node_obj.__dict__ |
| return ret |
| |
| |
| def database_node_get(name, **kwargs): |
| ''' |
| Return a specific Contrail database node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.database_node_get nal01 |
| ''' |
| ret = {} |
| vrouter_objs = database_node_list(**kwargs) |
| if name in vrouter_objs: |
| ret[name] = vrouter_objs.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving database node.'} |
| return ret |
| |
| |
| def database_node_create(name, ip_address, **kwargs): |
| ''' |
| Create specific Contrail database node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.database_node_create ntw03 10.10.10.103 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| database_node_objs = database_node_list(**kwargs) |
| if name in database_node_objs: |
| ret['comment'] = 'Database node ' + name + ' already exists' |
| return ret |
| else: |
| database_node_obj = DatabaseNode( |
| name, gsc_obj, |
| database_node_ip_address=ip_address) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "DatabaseNode " + name + " will be created" |
| return ret |
| vnc_client.database_node_create(database_node_obj) |
| ret['comment'] = "DatabaseNode " + name + " has been created" |
| ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def database_node_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail database node |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.database_node_delete cmp01 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| database_node_obj = DatabaseNode(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "DatabaseNode " + name + " will be deleted" |
| return ret |
| vnc_client.database_node_delete( |
| fq_name=database_node_obj.get_fq_name()) |
| ret['comment'] = "DatabaseNode " + name + " has been deleted" |
| ret['changes'] = {'DatabaseNode': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def _get_vrouter_config(vnc_client, gvc_name=None): |
| try: |
| if not gvc_name: |
| gvc_list = global_vrouter_config_list() |
| gvc_name = gvc_list.values()[0]['name'] |
| |
| config = vnc_client.global_vrouter_config_read( |
| fq_name=['default-global-system-config', gvc_name]) |
| except Exception: |
| config = None |
| |
| return config |
| |
| |
| def linklocal_service_list(global_vrouter_config_name=None, **kwargs): |
| ''' |
| Return a list of all Contrail link local services |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.linklocal_service_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| |
| current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name) |
| if current_config is None: |
| return ret |
| |
| service_list_res = current_config.get_linklocal_services() |
| if service_list_res is None: |
| service_list_obj = {'linklocal_service_entry': []} |
| else: |
| service_list_obj = service_list_res.__dict__ |
| for _, value in service_list_obj.iteritems(): |
| for entry in value: |
| service = entry.__dict__ |
| if 'linklocal_service_name' in service: |
| ret[service['linklocal_service_name']] = service |
| return ret |
| |
| |
| def linklocal_service_get(name, **kwargs): |
| ''' |
| Return a specific Contrail link local service |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.linklocal_service_get llservice |
| ''' |
| ret = {} |
| services = linklocal_service_list(**kwargs) |
| if name in services: |
| ret[name] = services.get(name) |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving link local service "{0}"'.format(name)} |
| return ret |
| |
| |
| def linklocal_service_create(name, lls_ip, lls_port, ipf_dns_or_ip, ipf_port, global_vrouter_config_name=None, **kwargs): |
| ''' |
| Create specific Contrail link local service |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.linklocal_service_create \ |
| llservice 10.10.10.103 22 '["20.20.20.20", "30.30.30.30"]' 22 |
| salt '*' contrail.linklocal_service_create \ |
| llservice 10.10.10.103 22 link-local.service.dns-name 22 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| current_config = _get_vrouter_config(vnc_client, global_vrouter_config_name) |
| service_entry = LinklocalServiceEntryType( |
| linklocal_service_name=name, |
| linklocal_service_ip=lls_ip, |
| linklocal_service_port=lls_port, |
| ip_fabric_service_port=ipf_port) |
| if isinstance(ipf_dns_or_ip, basestring): |
| service_entry.ip_fabric_DNS_service_name = ipf_dns_or_ip |
| elif isinstance(ipf_dns_or_ip, list): |
| service_entry.ip_fabric_service_ip = ipf_dns_or_ip |
| service_entry.ip_fabric_DNS_service_name = '' |
| |
| if current_config is None: |
| new_services = LinklocalServicesTypes([service_entry]) |
| new_config = GlobalVrouterConfig(linklocal_services=new_services) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Link local service " + name + " will be created" |
| else: |
| ret['comment'] = "Link local service " + name + " has been created" |
| ret['changes'] = {'LinkLocalSevice': {'old': '', 'new': name}} |
| vnc_client.global_vrouter_config_create(new_config) |
| else: |
| _current_service_list = current_config.get_linklocal_services() |
| if _current_service_list is None: |
| service_list = {'linklocal_service_entry': []} |
| else: |
| service_list = _current_service_list.__dict__ |
| new_services = [service_entry] |
| for key, value in service_list.iteritems(): |
| if key != 'linklocal_service_entry': |
| continue |
| for _entry in value: |
| entry = _entry.__dict__ |
| if 'linklocal_service_name' in entry: |
| if entry['linklocal_service_name'] == name: |
| ret['comment'] = 'Link local service ' + name + ' already exists' |
| return ret |
| new_services.append(_entry) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "LinkLocalSevices " + name + " will be created" |
| service_list[key] = new_services |
| new_config = GlobalVrouterConfig(linklocal_services=service_list) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "LinkLocalSevices " + name + " will be updated" |
| else: |
| vnc_client.global_vrouter_config_update(new_config) |
| ret['comment'] = "LinkLocalSevices " + name + " has been created" |
| ret['changes'] = {'LinkLocalSevices': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def linklocal_service_delete(name, **kwargs): |
| ''' |
| Delete specific link local service entry |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.linklocal_service_delete llservice |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| lls = linklocal_service_get(name) |
| print (lls) |
| if name in lls: |
| if __opts__['test']: |
| print " ------------ Test only ------------" |
| ret['result'] = None |
| ret['comment'] = "Link local service " + name + " will be deleted" |
| return ret |
| else: |
| return ret |
| |
| vnc_client = _auth(**kwargs) |
| current_config = _get_vrouter_config(vnc_client) |
| if current_config is not None: |
| _current_service_list = current_config.get_linklocal_services() |
| if _current_service_list is None: |
| service_list = {'linklocal_service_entry': []} |
| else: |
| service_list = _current_service_list.__dict__ |
| new_services = [] |
| for key, value in service_list.iteritems(): |
| if key != 'linklocal_service_entry': |
| continue |
| for _entry in value: |
| entry = _entry.__dict__ |
| if 'linklocal_service_name' in entry: |
| if entry['linklocal_service_name'] != name: |
| new_services.append(_entry) |
| service_list[key] = new_services |
| new_config = GlobalVrouterConfig(linklocal_services=service_list) |
| vnc_client.global_vrouter_config_update(new_config) |
| ret['comment'] = "Link local service " + name + " will be deleted" |
| ret['changes'] = {'LinkLocalService': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def virtual_machine_interface_list(**kwargs): |
| ''' |
| Return a list of all Contrail virtual machine interfaces |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_machine_interfaces |
| ''' |
| ret = [] |
| vnc_client = _auth(**kwargs) |
| project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin')) |
| project_uuid = project.get_uuid() |
| |
| vm_ifaces = vnc_client.virtual_machine_interfaces_list( |
| detail=True, parent_id=project_uuid) |
| |
| for vm_iface in vm_ifaces: |
| ret.append(vm_iface.__dict__) |
| |
| return ret |
| |
| |
| def virtual_machine_interface_create(name, |
| virtual_network, |
| mac_address=None, |
| ip_address=None, |
| security_group=None, |
| **kwargs): |
| ''' |
| Create specific Contrail virtual machine interface (Port) |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_machine_interface_create port01 net01 mac_address='01:02:03:04:05:06' |
| router_types: |
| - tor-agent |
| - tor-service-node |
| - embedded |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| project = _get_project_obj(vnc_client, name=kwargs.get('tenant', 'admin')) |
| |
| vm_int = VirtualMachineInterface(name, parent_obj=project) |
| |
| if mac_address: |
| mac_address_obj = MacAddressesType([mac_address]) |
| vm_int.set_virtual_machine_interface_mac_addresses(mac_address_obj) |
| |
| if security_group: |
| sgo = vnc_client.security_group_read(fq_name=_get_fq_name( |
| vnc_client, security_group, kwargs.get('tenant', 'admin'))) |
| vm_int.set_security_group(sgo) |
| |
| vnet_uuid = virtual_network_get(virtual_network, **kwargs)[virtual_network]['_uuid'] |
| vnet_obj = vnc_client.virtual_network_read(id=vnet_uuid) |
| vm_int.set_virtual_network(vnet_obj) |
| |
| vmi_uuid = vnc_client.virtual_machine_interface_create(vm_int) |
| vmi = vnc_client.virtual_machine_interface_read(id=vmi_uuid) |
| |
| vm_int.set_port_security_enabled(False) |
| vnc_client.virtual_machine_interface_update(vm_int) |
| |
| # Allocate IP to VMI |
| ip = vnc_api.InstanceIp(name + '.ip') |
| ip.set_virtual_machine_interface(vmi) |
| ip.set_virtual_network(vnet_obj) |
| |
| ip_uuid = vnc_client.instance_ip_create(ip) |
| |
| if ip_address: |
| ip.set_instance_ip_address(ip_address) |
| vnc_client.instance_ip_update(ip) |
| |
| return vmi.__dict__ |
| |
| |
| def virtual_network_list(**kwargs): |
| ''' |
| Return a list of all Contrail virtual network |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_network |
| ''' |
| |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| virtual_networks = vnc_client._objects_list('virtual-network', detail=True) |
| for virtual_network in virtual_networks: |
| ret[virtual_network.name] = virtual_network.__dict__ |
| return ret |
| |
| |
| def virtual_network_get(name, **kwargs): |
| ''' |
| Return a specific Contrail virtual network |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.virtual_network_get net01 |
| ''' |
| ret = {} |
| vnet_objs = virtual_network_list(**kwargs) |
| if name in vnet_objs: |
| ret[name] = vnet_objs.get(name) |
| if len(ret) != 1: |
| return {'result': False, |
| 'Error': 'Error in retrieving virtual networks.'} |
| return ret |
| |
| |
| def virtual_network_create(name, conf=None, **kwargs): |
| ''' |
| Create Contrail virtual network |
| CLI Example: |
| .. code-block:: bash |
| salt '*' contrail.virtual_network_create name |
| |
| salt.cmdRun(pepperEnv, 'ntw01*', 'salt-call contrail.virtual_network_create |
| "testicek" "{"external":"True","ip":"172.16.111.0","prefix":24, |
| "asn":64512,"target":10000}" ') |
| |
| Parameters: |
| name required - name of the new network |
| |
| conf (dict) optional: |
| domain (string) optional - which domain use for vn creation |
| project (string) optional - which project use for vn creation |
| ipam_domain (string) optional - domain for ipam |
| ipam_project (string) optional - project for ipam |
| ipam_name (string) optional - ipam name |
| ip_prefix (string) optional - format is xxx.xxx.xxx.xxx |
| ip_prefix_len (int) optional - format is xx |
| asn (int) optional - autonomus system number |
| target (int) optional - route target number |
| external (boolean) optional - set if network is external |
| |
| allow_transit (boolean) optional - enable allow transit |
| forwarding_mode (any of ['l2_l3','l2','l3']) optional |
| - packet forwarding mode for this virtual network |
| rpf (any of ['enabled','disabled']) optional |
| - Enable or disable Reverse Path Forwarding check |
| for this network |
| mirror_destination (boolean) optional |
| - Mark the vn as mirror destination network |
| ''' |
| if conf is None: |
| conf = {} |
| |
| # check for domain, is missing set to default-domain |
| if 'domain' in conf: |
| vn_domain = str(conf['domain']) |
| else: |
| vn_domain = 'default-domain' |
| # check for project, is missing set to admin |
| if 'project' in conf: |
| vn_project = str(conf['project']) |
| else: |
| vn_project = 'admin' |
| # check for ipam domain,default is default-domain |
| if 'ipam_domain' in conf: |
| ipam_domain = str(conf['ipam_domain']) |
| else: |
| ipam_domain = 'default-domain' |
| # check for ipam domain,default is default-domain |
| if 'ipam_project' in conf: |
| ipam_project = str(conf['ipam_project']) |
| else: |
| ipam_project = 'default-project' |
| |
| if 'ipam_name' in conf: |
| ipam_name = conf['ipam_name'] |
| else: |
| ipam_name = 'default-network-ipam' |
| |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| |
| # list of existing vn networks |
| vn_networks = [] |
| vnc_client = _auth(**kwargs) |
| prj_obj = vnc_client.project_read(fq_name=[vn_domain, |
| vn_project]) |
| # check if the network exists |
| vn_networks_list = vnc_client._objects_list('virtual_network') |
| fq = [vn_domain, vn_project, name] |
| for network in vn_networks_list['virtual-networks']: |
| if fq == network['fq_name']: |
| ret['comment'] = ("Virtual network with name " |
| + name + " already exists") |
| return ret |
| |
| vn_obj = VirtualNetwork(name, prj_obj) |
| vn_type_obj = VirtualNetworkType() |
| # get ipam from default project and domain |
| ipam = vnc_client.network_ipam_read(fq_name=[ipam_domain, |
| ipam_project, |
| ipam_name]) |
| |
| # create subnet |
| if 'ip_prefix' in conf and 'ip_prefix_len' in conf: |
| ipam_subnet_type = IpamSubnetType(subnet=SubnetType( |
| ip_prefix=conf['ip_prefix'], |
| ip_prefix_len=conf['ip_prefix_len'])) |
| |
| vn_subnets_type_obj = VnSubnetsType(ipam_subnets=[ipam_subnet_type]) |
| vn_obj.add_network_ipam(ipam, vn_subnets_type_obj) |
| |
| # add route target to the network |
| if 'asn' in conf and 'target' in conf: |
| route_target_list_obj = RouteTargetList(["target:{0}:{1}" |
| .format(conf['asn'], |
| conf['target'])]) |
| vn_obj.set_route_target_list(route_target_list_obj) |
| |
| if 'external' in conf: |
| vn_obj.set_router_external(conf['external']) |
| |
| if 'allow_transit' in conf: |
| vn_type_obj.set_allow_transit(conf['allow_transit']) |
| |
| if 'forwarding_mode' in conf: |
| if conf['forwarding_mode'] in ['l2_l3', 'l2', 'l3']: |
| vn_type_obj.set_forwarding_mode(conf['forwarding_mode']) |
| |
| if 'rpf' in conf: |
| vn_type_obj.set_rpf(conf['rpf']) |
| |
| if 'mirror_destination' in conf: |
| vn_type_obj.set_mirror_destination(conf['mirror_destination']) |
| |
| vn_obj.set_virtual_network_properties(vn_type_obj) |
| |
| # create virtual network |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = ("Virtual network with name {0} will be created" |
| .format(name)) |
| else: |
| vnc_client.virtual_network_create(vn_obj) |
| # if network is external create floating ip pool |
| if 'external' in conf: |
| if conf['external']: |
| pool_name = 'default' |
| _create_floating_ip_pool(pool_name, |
| vn_obj, |
| **kwargs) |
| |
| ret['comment'] = ("Virtual network with name {0} was created" |
| .format(name)) |
| return ret |
| |
| |
| def service_appliance_set_list(**kwargs): |
| ''' |
| Return a list of Contrail service appliance set |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.service_appliance_set_list |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| service_appliance_sets = vnc_client._objects_list('service-appliance-set', detail=True) |
| for service_appliance_set in service_appliance_sets: |
| ret[service_appliance_set.name] = service_appliance_set.__dict__ |
| return ret |
| |
| |
| def service_appliance_set_get(name, **kwargs): |
| ''' |
| Return a specific Contrail service appliance set |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.service_appliance_set_get name |
| ''' |
| ret = {} |
| sas_objs = service_appliance_set_list(**kwargs) |
| if name in sas_objs: |
| ret[name] = sas_objs.get(name) |
| if len(ret) != 1: |
| return {'result': False, |
| 'Error': "Error in the retrieving service apliance set."} |
| return ret |
| |
| |
| def service_appliance_set_create(name, properties=None, driver=None, ha_mode=None, **kwargs): |
| ''' |
| Create Contrail service appliance set |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.service_appliance_set_create name |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| sas_objs = service_appliance_set_list(**kwargs) |
| if name in sas_objs: |
| ret['commnet'] = 'Service appliance set ' + name + ' already exists' |
| else: |
| service_appliance_set_obj = ServiceApplianceSet( |
| name, gsc_obj) |
| if properties: |
| pairs = KeyValuePairs() |
| for k, v in properties.items(): |
| pairs.add_key_value_pair(KeyValuePair(k, v)) |
| service_appliance_set_obj.set_service_appliance_set_properties(pairs) |
| if driver: |
| service_appliance_set_obj.set_service_appliance_driver(driver) |
| if ha_mode: |
| service_appliance_set_obj.set_service_appliance_ha_mode(ha_mode) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "ServiceApplianceSet " + name + " will be created" |
| else: |
| vnc_client.service_appliance_set_create(service_appliance_set_obj) |
| ret['comment'] = "ServiceApplianceSet " + name + " has been created" |
| ret['changes'] = {'ServiceApplianceSet': {'old': '', 'new': name}} |
| return ret |
| |
| |
| def service_appliance_set_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail service appliance set |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.service_appliance_set_delete name |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| gsc_obj = _get_config(vnc_client) |
| sas_obj = ServiceApplianceSet(name, gsc_obj) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Service appliance set " + name + " will be deleted" |
| else: |
| vnc_client.service_appliance_set_delete(fq_name=sas_obj.get_fq_name()) |
| ret['comment'] = "ServiceApplianceSet " + name + " has been deleted" |
| ret['changes'] = {'ServiceApplianceSet': {'old': name, 'new': ''}} |
| return ret |
| |
| def global_system_config_list(**kwargs): |
| ''' |
| Return a list of all global system configs |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_system_config_list |
| ''' |
| |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| gsysconfs = vnc_client._objects_list('global-system-config', detail=True) |
| for gsysconf in gsysconfs: |
| ret[gsysconf.name] = gsysconf.__dict__ |
| return ret |
| |
| |
| def global_system_config_get(name, **kwargs): |
| ''' |
| Return a specific Contrail global system config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_system_config_get name |
| ''' |
| ret = {} |
| vnc_client = _auth(**kwargs) |
| gsc_objs = vnc_client._objects_list('global-system-config', detail=True) |
| for gsc_obj in gsc_objs: |
| if name == gsc_obj.name: |
| ret[name] = gsc_obj.__dict__ |
| if len(ret) == 0: |
| return {'Error': 'Error in retrieving global system config.'} |
| return ret |
| |
| |
| def global_system_config_create(name, ans=64512, grp=None, **kwargs): |
| ''' |
| Create Contrail global system config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_system_config_create name=default-global-system-config ans=64512 |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| |
| gsc_objs = global_system_config_list(**kwargs) |
| if name in gsc_objs: |
| config_obj = vnc_client.global_system_config_read(fq_name=[name]) |
| if config_obj.graceful_restart_parameters and not HAS_OLD: |
| curr_grp = str(config_obj.graceful_restart_parameters).replace(" ", "").split(",") |
| curr_grpd = dict(item.split('=') for item in curr_grp) |
| else: |
| curr_grpd = None |
| |
| if grp and 'enable' in grp and not HAS_OLD: |
| grp_obj = GracefulRestartParametersType() |
| if 'enable' in grp: |
| grp_obj.enable = grp['enable'] |
| if curr_grpd and str(grp['enable']) != str(curr_grpd['enable']): |
| ret['changes']['enable'] = {"from": str(curr_grpd['enable']), "to": str(grp['enable'])} |
| elif not curr_grpd: |
| ret['changes']['enable'] = {"from": None, "to": grp['enable']} |
| if 'restart_time' in grp: |
| grp_obj.restart_time = grp['restart_time'] |
| if curr_grpd and grp['restart_time'] != int(curr_grpd['restart_time']): |
| ret['changes']['restart_time'] = {"from": int(curr_grpd['restart_time']), "to": grp['restart_time']} |
| elif not curr_grpd: |
| ret['changes']['restart_time'] = {"from": None, "to": grp['restart_time']} |
| if 'end_of_rib_timeout' in grp: |
| grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout'] |
| if curr_grpd and grp['end_of_rib_timeout'] != int(curr_grpd['end_of_rib_timeout']): |
| ret['changes']['end_of_rib_timeout'] = {"from": int(curr_grpd['end_of_rib_timeout']), "to": grp['end_of_rib_timeout']} |
| elif not curr_grpd: |
| ret['changes']['end_of_rib_timeout'] = {"from": None, "to": grp['end_of_rib_timeout']} |
| if 'bgp_helper_enable' in grp: |
| grp_obj.bgp_helper_enable = grp['bgp_helper_enable'] |
| if curr_grpd and str(grp['bgp_helper_enable']) != str(curr_grpd['bgp_helper_enable']): |
| ret['changes']['bgp_helper_enable'] = {"from": str(curr_grpd['bgp_helper_enable']), "to": grp['bgp_helper_enable']} |
| elif not curr_grpd: |
| ret['changes']['bgp_helper_enable'] = {"from": None, "to": grp['bgp_helper_enable']} |
| if 'xmpp_helper_enable' in grp: |
| grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable'] |
| if curr_grpd and str(grp['xmpp_helper_enable']) != str(curr_grpd['xmpp_helper_enable']): |
| ret['changes']['xmpp_helper_enable'] = {"from": str(curr_grpd['xmpp_helper_enable']), "to": grp['xmpp_helper_enable']} |
| elif not curr_grpd: |
| ret['changes']['xmpp_helper_enable'] = {"from": None, "to": grp['xmpp_helper_enable']} |
| if 'long_lived_restart_time' in grp: |
| grp_obj.long_lived_restart_time = grp['long_lived_restart_time'] |
| if curr_grpd and grp['long_lived_restart_time'] != int(curr_grpd['long_lived_restart_time']): |
| ret['changes']['long_lived_restart_time'] = {"from": int(curr_grpd['long_lived_restart_time']), "to": grp['long_lived_restart_time']} |
| elif not curr_grpd: |
| ret['changes']['long_lived_restart_time'] = {"from": None, "to": grp['long_lived_restart_time']} |
| else: |
| grp_obj = None |
| |
| config_obj.graceful_restart_parameters = grp_obj |
| |
| if ans: |
| if config_obj.autonomous_system != ans: |
| ret['changes']['autonomous_system'] = {"from": config_obj.autonomous_system, "to": ans} |
| config_obj.autonomous_system = ans |
| |
| vnc_client.global_system_config_update(config_obj) |
| ret['comment'] = 'Global system config ' + name + ' has been updated' |
| else: |
| config_obj = GlobalSystemConfig(name=name) |
| if grp and not HAS_OLD: |
| grp_obj = GracefulRestartParametersType() |
| if 'enable' in grp: |
| grp_obj.enable = grp['enable'] |
| if 'restart_time' in grp: |
| grp_obj.restart_time = grp['restart_time'] |
| if 'end_of_rib_timeout' in grp: |
| grp_obj.end_of_rib_timeout = grp['end_of_rib_timeout'] |
| if 'bgp_helper_enable' in grp: |
| grp_obj.bgp_helper_enable = grp['bgp_helper_enable'] |
| if 'xmpp_helper_enable' in grp: |
| grp_obj.xmpp_helper_enable = grp['xmpp_helper_enable'] |
| if 'long_lived_restart_time' in grp: |
| grp_obj.long_lived_restart_time = grp['long_lived_restart_time'] |
| config_obj.graceful_restart_parameters = grp_obj |
| if ans: |
| config_obj.autonomous_system = ans |
| |
| vnc_client.global_system_config_create(config_obj) |
| ret['changes'] = {"created": "new"} |
| ret['comment'] = 'Global system config ' + name + ' has been created ' |
| |
| return ret |
| |
| |
| def global_system_config_delete(name, **kwargs): |
| ''' |
| Delete specific Contrail global system config |
| |
| CLI Example: |
| |
| .. code-block:: bash |
| |
| salt '*' contrail.global_system_config_delete name |
| ''' |
| ret = {'name': name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| vnc_client = _auth(**kwargs) |
| |
| gsc_obj = GlobalSystemConfig(name) |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Global system config " + name + " will be deleted" |
| else: |
| vnc_client.global_system_config_delete(fq_name=gsc_obj.get_fq_name()) |
| ret['comment'] = "GlobalSystemConfig " + name + " has been deleted" |
| ret['changes'] = {'GlobalSystemConfig': {'old': name, 'new': ''}} |
| return ret |
| |
| |
| def list_floating_ip_pools(**kwargs): |
| ''' |
| List all floating ip pools |
| |
| CLI Example: |
| .. code-block:: bash |
| salt '*' contrail.list_floating_ip_pools |
| ''' |
| vnc_client = _auth(**kwargs) |
| pools = vnc_client.floating_ip_pools_list() |
| # list of floating ip pools objects |
| fp_list = [] |
| |
| for pool in vnc_client.floating_ip_pools_list()['floating-ip-pools']: |
| fip_obj = vnc_client.floating_ip_pool_read(pool['fq_name']) |
| fp_list.append(fip_obj) |
| # print given pool |
| fip_obj.dump() |
| |
| def update_floating_ip_pool(vn_name, vn_project, vn_domain=None, |
| owner_access=None, global_access=None, |
| projects=None, **kwargs): |
| ''' |
| Update specific floating ip pool |
| |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.update_floating_ip_pool \ |
| 'FLOATING-TEST' \ |
| 'admin' \ |
| 'default-domain' \ |
| 7 7 \ |
| [['pepa',4],['karel',7]] |
| |
| |
| params: |
| vn_name - name of the virtual network, which to use |
| vn-project - project which includes virtual network |
| vn-domain - domain wchich includes vn_project and vn_name |
| owner_access (int) - Permission rights for owner |
| global_access (int) - Permission rights for others |
| projects (list) - list of ShareType(tenant_name,tennat_permissions) |
| ''' |
| ret = {'name': vn_name + "-default pool", |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| |
| if vn_domain is None: |
| vn_domain = 'default-domain' |
| fip_obj = None |
| |
| vnc_client = _auth(**kwargs) |
| p_fq_name = [vn_domain, vn_project, vn_name, 'default'] |
| fip_obj = vnc_client.floating_ip_pool_read(fq_name=p_fq_name) |
| |
| changes = {} |
| # get perms from fip_obj (Floatin ip pool) |
| perms2 = fip_obj.get_perms2() |
| if owner_access is not None: |
| if perms2.get_owner_access() != owner_access: |
| changes['owner_access'] = {'old': str(perms2.get_owner_access()), |
| 'new': str(owner_access)} |
| perms2.set_owner_access(owner_access) |
| |
| if global_access is not None: |
| if perms2.get_global_access() != global_access: |
| changes['global_access'] = {'old': str(perms2.get_global_access()), |
| 'new': str(global_access)} |
| perms2.set_global_access(global_access) |
| |
| # list which represents the new state of perms |
| final_list = [] |
| if projects: |
| for item in perms2.get_share(): |
| for share in projects: |
| if item.get_tenant() == share[0]: |
| # project is in the new and old list |
| # check is the permission number is same |
| if item.get_tenant_access() == share[1]: |
| # this project and permission is without change, keep it |
| final_list.append(item) |
| break |
| else: |
| # project exists but change the permission |
| final_list.append(ShareType(tenant=share[0], |
| tenant_access=share[1])) |
| # show changes |
| n = str('share-'+share[0]) |
| old_str = "permission for project {0} was {1}" |
| new_str = "permission for project {0} will be {1}" |
| old = old_str.format(share[0], |
| str(item.get_tenant_access())) |
| |
| new = new_str.format(share[0], str(share[1])) |
| changes[n] = {'old': old, 'new': new} |
| break |
| else: |
| rm_name = "share-" + item.get_tenant() |
| changes[rm_name] = item.get_tenant() + " will be removed" |
| |
| # check for the completly new projects |
| for item in projects: |
| for share in final_list: |
| if item[0] == share.get_tenant(): |
| break |
| else: |
| final_list.append(ShareType(tenant=item[0], |
| tenant_access=item[1])) |
| name = 'share-' + str(item[0]) |
| c_str = '{0} will be added with permissions {1}' |
| changes[name] = c_str.format(name, item[1]) |
| else: |
| for item in perms2.get_share(): |
| rm_name = "share-" + item.get_tenant() |
| changes[rm_name] = item.get_tenant() + " will be removed" |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = changes |
| |
| return ret |
| else: |
| ret['comment'] = changes |
| perms2.set_share(final_list) |
| fip_obj.set_perms2(perms2) |
| vnc_client.floating_ip_pool_update(fip_obj) |
| |
| return ret |
| |
| |
| def show_rbac_rules(api_access_list_entries): |
| if api_access_list_entries is None: |
| return 'Empty RBAC group!' |
| |
| rule_list = api_access_list_entries.get_rbac_rule() |
| response = 'Rules (%d):' % len(rule_list) + '----------\n' |
| for idx, rule in enumerate(rule_list): |
| o = rule.rule_object |
| f = rule.rule_field |
| ps = ', '.join([p.role_name+':'+p.role_crud for p in rule.rule_perms]) |
| o_f = "%s.%s" % (o, f) if f else o |
| response += '%2d %-32s %s\n' % (idx, o_f, ps) |
| return response |
| |
| |
| def vnc_read_obj(vnc, obj_type, fq_name): |
| method_name = obj_type.replace('-', '_') |
| method = getattr(vnc, "%s_read" % (method_name)) |
| try: |
| return method(fq_name=fq_name) |
| except NoIdError: |
| print '%s %s not found!' % (obj_type, fq_name) |
| return None |
| |
| |
| def rbac_show_group(name, uuid, **kwargs): |
| ''' |
| Show specific RBAC group |
| |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.rbac_show_group name \ |
| 'default-domain:default-project:default' |
| |
| params: |
| name - one of pair {name, uuid} addresing to access-list |
| uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \ |
| including domain and project |
| |
| ''' |
| vnc = _auth(**kwargs) |
| fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':') |
| ret = {'name': fq_name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| rg = vnc_read_obj(vnc, 'api-access-list', fq_name) |
| if not rg: |
| ret['comment'] = 'No rules found' |
| return ret |
| |
| ret['comment'] = show_rbac_rules(rg.get_api_access_list_entries()) |
| return ret |
| |
| |
| def rbac_create_group(uuid, **kwargs): |
| ''' |
| Create RBAC group |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.rbac_create_group name \ |
| 'default-domain:default-project:default' |
| |
| params: |
| name - one of pair {name, uuid} addresing to access-list |
| uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \ |
| including domain and project |
| |
| ''' |
| vnc = _auth(**kwargs) |
| fq_name = uuid.split(':') |
| ret = {'name': fq_name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| if len(fq_name) != 2 and len(fq_name) != 3: |
| ret['comment'] = 'Fully qualified name of rbac group expected' |
| return ret |
| |
| name = fq_name[-1] |
| |
| if len(fq_name) == 2: |
| if fq_name[0] == 'default-global-system-config': |
| pobj = vnc.global_system_config_read(fq_name=fq_name[0:1]) |
| else: |
| pobj = vnc.domain_read(fq_name=fq_name[0:1]) |
| else: |
| pobj = vnc.project_read(fq_name=fq_name[0:2]) |
| |
| rentry = RbacRuleEntriesType([]) |
| rg = ApiAccessList(name, parent_obj=pobj, api_access_list_entries=rentry) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "RBAC group " + uuid + " will be created" |
| |
| return ret |
| else: |
| vnc.api_access_list_create(rg) |
| rg2 = vnc.api_access_list_read(fq_name=fq_name) |
| rge = rg.get_api_access_list_entries() |
| show_rbac_rules(rge) |
| ret['comment'] = "RBAC group " + uuid + " has been created" |
| |
| return ret |
| |
| |
| def rbac_delete_group(name, uuid, **kwargs): |
| ''' |
| Delete RBAC group |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.rbac_delete_group name \ |
| 'default-domain:default-project:default' |
| |
| params: |
| name - one of pair {name, uuid} addresing to access-list |
| uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \ |
| including domain and project |
| |
| ''' |
| vnc = _auth(**kwargs) |
| fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':') |
| ret = {'name': fq_name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| if len(fq_name) != 2 and len(fq_name) != 3: |
| ret['comment'] = 'Fully qualified name of rbac group expected' |
| return ret |
| name = fq_name[-1] |
| |
| rg = vnc_read_obj(vnc, 'api-access-list', fq_name) |
| if not rg: |
| ret['comment'] = 'No rules found' |
| return ret |
| rge = rg.get_api_access_list_entries() |
| show_rbac_rules(rge) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "RBAC group " + uuid + " will be deleted" |
| |
| return ret |
| else: |
| vnc.api_access_list_delete(fq_name=fq_name) |
| ret['comment'] = "RBAC group " + uuid + " has been deleted" |
| |
| return ret |
| |
| |
| def rbac_add_rule(name, uuid, add_rule, **kwargs): |
| ''' |
| Add rule to specific RBAC group |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.rbac_add_rule name \ |
| 'default-domain:default-project:default' \ |
| '* admin:CRUD' |
| |
| params: |
| name - one of pair {name, uuid} addresing to access-list |
| uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \ |
| including domain and project |
| rule(str) - Appropriate RBAC-based rule in format '<object, field> \ |
| list of <role:CRUD>' to be added |
| |
| ''' |
| vnc = _auth(**kwargs) |
| fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':') |
| rule = build_rule(add_rule) |
| ret = {'name': fq_name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| if rule is None: |
| ret['comment'] = 'A rule string must be specified for this operation' |
| return ret |
| |
| # rbac rule entry consists of one or more rules |
| rg = vnc_read_obj(vnc, 'api-access-list', fq_name) |
| if not rg: |
| ret['comment'] = 'No rules found' |
| return ret |
| |
| rge = rg.get_api_access_list_entries() |
| if rge is None: |
| rge = RbacRuleEntriesType([]) |
| show_rbac_rules(rge) |
| |
| # avoid duplicates |
| match = find_rule(rge, rule) |
| if not match: |
| rge.add_rbac_rule(rule) |
| else: |
| build_perms(rge.rbac_rule[match[0]-1], match[3]) |
| |
| show_rbac_rules(rge) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Rule " + add_rule |
| ret['comment'] += " will be created for RBAC group " + uuid |
| |
| return ret |
| else: |
| rg.set_api_access_list_entries(rge) |
| vnc.api_access_list_update(rg) |
| ret['comment'] = "Rule " + add_rule |
| ret['comment'] += " has been added for RBAC group " + uuid |
| |
| return ret |
| |
| |
| def rbac_delete_rule(name, uuid, del_rule, **kwargs): |
| ''' |
| Delete rule to specific RBAC group |
| |
| CLI Example |
| .. code-block:: bash |
| salt-call contrail.rbac_delete_rule name \ |
| 'default-domain:default-project:default' \ |
| '* admin:CRUD' |
| |
| params: |
| name - one of pair {name, uuid} addresing to access-list |
| uuid(str) - UUID in case of "uuid" specified OR full RBAC group name \ |
| including domain and project |
| rule(str) - Appropriate RBAC-based rule in format '<object, field> \ |
| list of <role:CRUD>' to be deleted |
| |
| ''' |
| vnc = _auth(**kwargs) |
| fq_name = vnc.id_to_fq_name(uuid) if name == 'uuid' else uuid.split(':') |
| rg = vnc_read_obj(vnc, 'api-access-list', fq_name) |
| ret = {'name': fq_name, |
| 'changes': {}, |
| 'result': True, |
| 'comment': ''} |
| if not rg: |
| ret['comment'] = 'No rules found' |
| return ret |
| rge = rg.get_api_access_list_entries() |
| show_rbac_rules(rge) |
| |
| del_idx = re.match("^[0-9]+$", del_rule) |
| if del_idx: |
| del_idx = int(del_idx.group()) |
| rc = len(rge.rbac_rule) |
| if del_idx > rc or del_idx < 1: |
| ret['comment'] = 'Invalid rule index to delete.' |
| ret['comment'] += 'Value must be 1-%d' % rc |
| return ret |
| match = (del_idx, True) |
| else: |
| rule = build_rule(del_rule) |
| match = find_rule(rge, rule) |
| |
| if not match: |
| ret['comment'] = "Rule not found. Unchanged" |
| return ret |
| elif match[1]: |
| rge.rbac_rule.pop(match[0]-1) |
| else: |
| build_perms(rge.rbac_rule[match[0]-1], match[2]) |
| show_rbac_rules(rge) |
| |
| if __opts__['test']: |
| ret['result'] = None |
| ret['comment'] = "Rule " + del_rule |
| ret['comment'] += " will be cleared from RBAC group " + uuid |
| |
| return ret |
| else: |
| rg.set_api_access_list_entries(rge) |
| vnc.api_access_list_update(rg) |
| ret['comment'] = "Rule " + del_rule |
| ret['comment'] += " has been cleared from RBAC group " + uuid |
| |
| return ret |