From cdc9d88086426087cba34abe7cede2dded0263bf Mon Sep 17 00:00:00 2001 From: mattycarroll Date: Thu, 9 May 2019 14:54:20 +0000 Subject: [PATCH] Move provider_networks into os_neutron The provider_networks module is currently only consumed by Neutron (yet it runs inside the integrated repo). This change moves the module and associated vars into this repo. Change-Id: Icd6f420f44da8d05f158764c5d335ae9b533e56a Related-Bug: #1826249 --- library/provider_networks | 367 ++++++++++++++++++++++++++++++++++++++ tasks/main.yml | 17 ++ 2 files changed, 384 insertions(+) create mode 100644 library/provider_networks diff --git a/library/provider_networks b/library/provider_networks new file mode 100644 index 00000000..31e52a4a --- /dev/null +++ b/library/provider_networks @@ -0,0 +1,367 @@ +#!/usr/bin/python +# (c) 2014, Kevin Carter +# +# Copyright 2014, Rackspace US, 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. + + +# import module snippets +from ansible.module_utils.basic import * + + +DOCUMENTATION = """ +--- +module: provider_networks +version_added: "1.8.6" +short_description: + - Parse a list of networks and return data that Ansible can use +description: + - Parse a list of networks and return data that Ansible can use +options: + provider_networks: + description: + - List of networks to parse + required: true + is_metal: + description: + - Enable handling of on metal hosts + required: false + bind_prefix: + description: + - Add a prefix to all network interfaces. + required: false +author: Kevin Carter +""" + +EXAMPLES = """ +## This is what the provider_networks list should look like. +# provider_networks: +# - network: +# container_bridge: "br-mgmt" +# container_type: "veth" +# container_interface: "eth1" +# ip_from_q: "container" +# type: "raw" +# group_binds: +# - all_containers +# - hosts +# is_container_address: true +# is_ssh_address: true +# - network: +# container_bridge: "br-vxlan" +# container_type: "veth" +# container_interface: "eth10" +# ip_from_q: "tunnel" +# type: "vxlan" +# range: "1:1000" +# net_name: "vxlan" +# group_binds: +# - neutron_linuxbridge_agent +# - network: +# container_bridge: "br-vxlan" +# container_type: "veth" +# container_interface: "eth10" +# ip_from_q: "tunnel" +# type: "geneve" +# range: "1:1000" +# net_name: "geneve" +# group_binds: +# - neutron_ovn_northd +# - neutron_ovn_controller +# - network: +# container_bridge: "br-vlan" +# container_type: "veth" +# container_interface: "eth12" +# host_bind_override: "eth12" +# type: "flat" +# net_name: "flat" +# group_binds: +# - neutron_linuxbridge_agent +# - network: +# container_bridge: "br-vlan" +# container_type: "veth" +# container_interface: "eth11" +# host_bind_override: "eth11" +# sriov_host_interfaces: "p1p1,p1p2" +# type: "vlan" +# range: "1:1, 101:101" +# net_name: "vlan" +# group_binds: +# - neutron_linuxbridge_agent +# - network: +# container_bridge: "br-provider" +# container_type: "veth" +# container_interface: "eth11" +# network_interface: "bond1" +# type: "vlan" +# range: "1:1, 101:101" +# net_name: "physnet1" +# group_binds: +# - neutron_openvswitch_agent +# - network: +# container_bridge: "br-storage" +# container_type: "veth" +# container_interface: "eth2" +# ip_from_q: "storage" +# type: "raw" +# group_binds: +# - glance_api +# - cinder_api +# - cinder_volume +# - nova_compute +# - swift_proxy + +- name: Test provider networks + provider_networks: + provider_networks: "{{ provider_networks }}" + register: pndata1 + +- name: Test provider networks is metal + provider_networks: + provider_networks: "{{ provider_networks }}" + is_metal: true + register: pndata2 + +- name: Test provider networks with prfix + provider_networks: + provider_networks: "{{ provider_networks }}" + bind_prefix: "brx" + is_metal: true + register: pndata3 + +## Module output: +# { +# "network_flat_networks": "flat", +# "network_flat_networks_list": [ +# "flat" +# ], +# "network_mappings": "flat:brx-eth12,vlan:brx-eth11", +# "network_mappings_list": [ +# "flat:brx-eth12", +# "vlan:brx-eth11" +# ], +# "network_sriov_mappings": "physnet1:p1p1,physnet1:p1p2", +# "network_sriov_mappings_list": [ +# "physnet1:p1p1" +# "physnet1:p1p2" +# ], +# "network_types": "vxlan,flat,vlan,geneve", +# "network_types_list": [ +# "vxlan", +# "flat", +# "vlan", +# "geneve" +# ], +# "network_vlan_ranges": "vlan:1:1,vlan:1024:1025", +# "network_vlan_ranges_list": [ +# "vlan:1:1", +# "vlan:1024:1025" +# ], +# "network_vxlan_ranges": "1:1000", +# "network_vxlan_ranges_list": [ +# "1:1000" +# ] +# "network_geneve_ranges": "1:1000", +# "network_geneve_ranges_list": [ +# "1:1000" +# ] +# } +""" + + +class ProviderNetworksParsing(object): + def __init__(self, module): + """Generate an integer from a name. + + :param module: Load the ansible module + :type module: ``object`` + """ + self.module = module + self.network_vlan_ranges = list() + self.network_vxlan_ranges = list() + self.network_geneve_ranges = list() + self.network_flat_networks = list() + self.network_mappings = list() + self.network_types = list() + self.network_sriov_mappings = list() + self.network_interface_mappings = list() + + def load_networks(self, provider_networks, is_metal=False, + bind_prefix=None, group_names=None): + """Load the lists of network and network data types. + + :param provider_networks: list of networks defined in user_config + :type provider_networks: ``list`` + :param is_metal: Enable of disable handling of on metal nodes + :type is_metal: ``bol`` + :param bind_prefix: Pre-interface prefix forced within the network map + :type bind_prefix: ``str`` + :param group_names: list of groups associated with node + :type group_names: ``list`` + """ + + for net in provider_networks: + if net['network']['type'] == "vlan": + if ( + set( + net["network"]["group_binds"] + ).intersection(group_names) or + "neutron_server" in group_names + ): + if "vlan" not in self.network_types: + self.network_types.append('vlan') + for vlan_range in net['network']['range'].split(','): + self.network_vlan_ranges.append( + '%s:%s' % ( + net['network']['net_name'], vlan_range.strip() + ) + ) + elif net['network']['type'] == "vxlan": + if "vxlan" not in self.network_types: + self.network_types.append('vxlan') + self.network_vxlan_ranges.append(net['network']['range']) + elif net['network']['type'] == "geneve": + if "geneve" not in self.network_types: + self.network_types.append('geneve') + self.network_geneve_ranges.append(net['network']['range']) + elif net['network']['type'] == "flat": + if ( + set( + net["network"]["group_binds"] + ).intersection(group_names) or + "neutron_server" in group_names + ): + if "flat" not in self.network_types: + self.network_types.append('flat') + self.network_flat_networks.append( + net['network']['net_name'] + ) + + # Create the network mappings + if net['network']['type'] not in ['raw', 'vxlan', 'geneve']: + if ( + set( + net["network"]["group_binds"] + ).intersection(group_names) + ): + if 'net_name' in net['network']: + if is_metal: + if 'host_bind_override' in net['network']: + bind_device = \ + net['network']['host_bind_override'] + else: + bind_device = \ + net['network']['container_bridge'] + else: + bind_device = net['network']['container_interface'] + + if bind_prefix: + bind_device = '%s-%s' % (bind_prefix, bind_device) + + self.network_mappings.append( + '%s:%s' % ( + net['network']['net_name'], + bind_device + ) + ) + + # Builds a list of provider bridge to physical + # interface mappings and is used when adding OVS + # ports to bridges + if 'network_interface' in net['network']: + self.network_interface_mappings.append( + '%s:%s' % ( + net['network']['container_bridge'], + net['network']['network_interface'] + ) + ) + + # SR-IOV interface mappings + if 'sriov_host_interfaces' in net['network']: + host_interfaces = \ + net['network']['sriov_host_interfaces'] + for interface in host_interfaces.split(','): + self.network_sriov_mappings.append( + '%s:%s' % ( + net['network']['net_name'], + interface + ) + ) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + provider_networks=dict( + type='list', + required=True + ), + is_metal=dict( + type='bool', + default='false' + ), + bind_prefix=dict( + type='str', + required=False, + default=None + ), + group_names=dict( + type='list', + required=False, + default=None + ) + ), + supports_check_mode=False + ) + + try: + pnp = ProviderNetworksParsing(module=module) + pnp.load_networks( + provider_networks=module.params.get('provider_networks'), + is_metal=module.params.get('is_metal'), + bind_prefix=module.params.get('bind_prefix'), + group_names=module.params.get('group_names') + ) + + # Response dictionary, this adds commas to all list items in string + # format as well as preserves the list functionality for future data + # processing. + resp = { + 'network_vlan_ranges': ','.join(pnp.network_vlan_ranges), + 'network_vlan_ranges_list': pnp.network_vlan_ranges, + 'network_vxlan_ranges': ','.join(pnp.network_vxlan_ranges), + 'network_vxlan_ranges_list': pnp.network_vxlan_ranges, + 'network_geneve_ranges': ','.join(pnp.network_geneve_ranges), + 'network_geneve_ranges_list': pnp.network_geneve_ranges, + 'network_flat_networks': ','.join(pnp.network_flat_networks), + 'network_flat_networks_list': pnp.network_flat_networks, + 'network_mappings': ','.join(list(set(pnp.network_mappings))), + 'network_mappings_list': pnp.network_mappings, + 'network_types': ','.join(pnp.network_types), + 'network_sriov_mappings': ','.join(pnp.network_sriov_mappings), + 'network_sriov_mappings_list': pnp.network_sriov_mappings, + 'network_interface_mappings': ','.join( + pnp.network_interface_mappings + ), + 'network_interface_mappings_list': pnp.network_interface_mappings + } + + module.exit_json(changed=True, **resp) + except Exception as exp: + resp = {'stderr': exp} + module.fail_json(msg='Failed Process', **resp) + +if __name__ == '__main__': + main() diff --git a/tasks/main.yml b/tasks/main.yml index e628114d..43eac42c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -74,6 +74,23 @@ tags: - always +- name: Create the neutron provider networks fact + provider_networks: + provider_networks: "{{ provider_networks }}" + bind_prefix: "{{ provider_network_bind_prefix | default('') }}" + is_metal: "{{ is_metal }}" + group_names: "{{ group_names }}" + register: pndata + when: neutron_provider_networks is not defined + tags: + - always + +- name: Set provider network fact(s) + set_fact: + neutron_provider_networks: "{{ neutron_provider_networks | default(pndata) }}" + tags: + - always + - name: Set neutron target platform type set_fact: neutron_os_type: "powervm"