summaryrefslogtreecommitdiffstats
path: root/puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml
diff options
context:
space:
mode:
Diffstat (limited to 'puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml')
-rw-r--r--puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml304
1 files changed, 304 insertions, 0 deletions
diff --git a/puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml b/puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml
new file mode 100644
index 00000000..3b7bf40c
--- /dev/null
+++ b/puppet/extraconfig/all_nodes/neutron-ml2-cisco-nexus-ucsm.j2.yaml
@@ -0,0 +1,304 @@
+heat_template_version: pike
+
+description: Configure hieradata for Network Cisco configuration
+
+parameters:
+ # Parameters passed from the parent template
+ servers:
+ type: json
+
+ # extra parameters passed via parameter_defaults
+ NetworkUCSMIp:
+ type: string
+ description: Cisco UCSM IP
+ default: 127.0.0.1
+ NetworkUCSMUsername:
+ type: string
+ description: Cisco UCSM username
+ default: admin
+ NetworkUCSMPassword:
+ type: string
+ description: Cisco UCSM password
+ default: password
+ NetworkUCSMHostList:
+ type: string
+ description: >
+ Mac address to service profile mapping for UCSM-controlled hosts
+ The format is
+ '<host1-mac>:<profile>, <host2-mac>:<profile>, ...'
+ default: ''
+ NetworkUCSMSupportedPciDevs:
+ type: string
+ description: Cisco UCSM SR-IOV and VM-FEX vendors supported
+ default: ''
+ NetworkNexusConfig:
+ type: json
+ description: Nexus switch configuration
+ default: {}
+ NetworkNexusManagedPhysicalNetwork:
+ type: string
+ description: The name of the physical_network
+ default: ''
+ NetworkNexusVlanNamePrefix:
+ type: string
+ description: A short prefix to prepend to the VLAN name
+ default: 'q-'
+ NetworkNexusSviRoundRobin:
+ type: boolean
+ description: A flag to enable round robin scheduling
+ default: false
+ NetworkNexusProviderVlanNamePrefix:
+ type: string
+ description: A short prefix to prepend to the VLAN name
+ default: 'p-'
+ NetworkNexusPersistentSwitchConfig:
+ type: string
+ description: To make Nexus device persistent
+ default: false
+ NetworkNexusSwitchHeartbeatTime:
+ type: number
+ description: >
+ Time interval to check the state of the Nexus device. The units of this
+ object are seconds. Setting this object to a value of 0 disables the
+ replay feature.
+ default: 0
+ NetworkNexusSwitchReplayCount:
+ type: number
+ description: >
+ This configuration item is OBSOLETE. The Nexus driver replay behavior
+ is to continue to attempt to connect to the down Nexus device with a
+ period equal to the heartbeat time interval. This was previously the
+ Number of times to attempt config replay.
+ default: 3
+ NetworkNexusProviderVlanAutoCreate:
+ type: boolean
+ description: A flag whether to manage the creation and removal of VLANs
+ default: true
+ NetworkNexusProviderVlanAutoTrunk:
+ type: boolean
+ description: A flag whether to manage the trunk ports on the Nexus
+ default: true
+ NetworkNexusVxlanGlobalConfig:
+ type: boolean
+ description: A flag whether to manage the VXLAN global settings
+ default: true
+ NetworkNexusHostKeyChecks:
+ type: boolean
+ description: enable strict host key checks when connecting to Nexus switches
+ default: false
+ NetworkNexusVxlanVniRanges:
+ type: string
+ description: VXLAN Network IDs that are available for tenant network
+ default: ''
+ NetworkNexusVxlanMcastRanges:
+ type: string
+ description: Multicast groups for the VXLAN interface.
+ default: ''
+
+
+resources:
+ # First we lay down the base configuration via the static hieradata mappings
+ NetworkCiscoConfig:
+ type: OS::Heat::StructuredConfig
+ properties:
+ group: hiera
+ config:
+ datafiles:
+ neutron_cisco_data:
+ mapped_data:
+ neutron::plugins::ml2::cisco::ucsm::ucsm_ip: {get_input: UCSM_ip}
+ neutron::plugins::ml2::cisco::ucsm::ucsm_username: {get_input: UCSM_username}
+ neutron::plugins::ml2::cisco::ucsm::ucsm_password: {get_input: UCSM_password}
+ neutron::plugins::ml2::cisco::ucsm::ucsm_host_list: {get_input: UCSM_host_list}
+ neutron::plugins::ml2::cisco::ucsm::supported_pci_devs: {get_input: UCSMSupportedPciDevs}
+ neutron::plugins::ml2::cisco::nexus::nexus_config: {get_input: NexusConfig}
+ neutron::plugins::ml2::cisco::nexus::managed_physical_network: {get_input: NexusManagedPhysicalNetwork}
+ neutron::plugins::ml2::cisco::nexus::vlan_name_prefix: {get_input: NexusVlanNamePrefix}
+ neutron::plugins::ml2::cisco::nexus::svi_round_robin: {get_input: NexusSviRoundRobin}
+ neutron::plugins::ml2::cisco::nexus::provider_vlan_name_prefix: {get_input: NexusProviderVlanNamePrefix}
+ neutron::plugins::ml2::cisco::nexus::persistent_switch_config: {get_input: NexusPersistentSwitchConfig}
+ neutron::plugins::ml2::cisco::nexus::switch_heartbeat_time: {get_input: NexusSwitchHeartbeatTime}
+ neutron::plugins::ml2::cisco::nexus::switch_replay_count: {get_input: NexusSwitchReplayCount}
+ neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_create: {get_input: NexusProviderVlanAutoCreate}
+ neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_trunk: {get_input: NexusProviderVlanAutoTrunk}
+ neutron::plugins::ml2::cisco::nexus::vxlan_global_config: {get_input: NexusVxlanGlobalConfig}
+ neutron::plugins::ml2::cisco::nexus::host_key_checks: {get_input: NexusHostKeyChecks}
+ neutron::plugins::ml2::cisco::type_nexus_vxlan::vni_ranges: {get_input: NexusVxlanVniRanges}
+ neutron::plugins::ml2::cisco::type_nexus_vxlan::mcast_ranges: {get_input: NexusVxlanMcastRanges}
+
+ NetworkCiscoDeployment:
+ type: OS::Heat::StructuredDeployments
+ properties:
+ name: NetworkCiscoDeployment
+ config: {get_resource: NetworkCiscoConfig}
+ servers: {get_param: [servers, Controller]}
+ input_values:
+ UCSM_ip: {get_param: NetworkUCSMIp}
+ UCSM_username: {get_param: NetworkUCSMUsername}
+ UCSM_password: {get_param: NetworkUCSMPassword}
+ UCSM_host_list: {get_attr: [MappingToUCSMDeploymentsController, deploy_stdout]}
+ UCSMSupportedPciDevs: {get_param: NetworkUCSMSupportedPciDevs}
+ NexusConfig: {get_attr: [MappingToNexusDeploymentsController, deploy_stdout]}
+ NexusManagedPhysicalNetwork: {get_param: NetworkNexusManagedPhysicalNetwork}
+ NexusVlanNamePrefix: {get_param: NetworkNexusVlanNamePrefix}
+ NexusSviRoundRobin: {get_param: NetworkNexusSviRoundRobin}
+ NexusProviderVlanNamePrefix: {get_param: NetworkNexusProviderVlanNamePrefix}
+ NexusPersistentSwitchConfig: {get_param: NetworkNexusPersistentSwitchConfig}
+ NexusSwitchHeartbeatTime: {get_param: NetworkNexusSwitchHeartbeatTime}
+ NexusSwitchReplayCount: {get_param: NetworkNexusSwitchReplayCount}
+ NexusProviderVlanAutoCreate: {get_param: NetworkNexusProviderVlanAutoCreate}
+ NexusProviderVlanAutoTrunk: {get_param: NetworkNexusProviderVlanAutoTrunk}
+ NexusVxlanGlobalConfig: {get_param: NetworkNexusVxlanGlobalConfig}
+ NexusHostKeyChecks: {get_param: NetworkNexusHostKeyChecks}
+ NexusVxlanVniRanges: {get_param: NetworkNexusVxlanVniRanges}
+ NexusVxlanMcastRanges: {get_param: NetworkNexusVxlanMcastRanges}
+
+ # Now we collect the Mac->Hostname mappings for all nodes, which enables
+ # calculation of the neutron::plugins::ml2::cisco::nexus::nexus_config data
+ CollectMacConfig:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ group: script
+ config: |
+ #!/bin/sh
+ MACS=$(ifconfig | grep ether | awk '{print $2}' | tr "\n" " ")
+ HOST_FQDN=$(hostname -f)
+ if [ -z "$HOST_FQDN" ]; then
+ HOSTNAME=$(hostname -s)
+ # hardcoding the domain name to avoid DNS lookup dependency
+ # same type of hardcoding appears elsewhere
+ # --ie. controller-puppet.yaml
+ # FIXME_HOSTNAME_DOMAIN_HARDCODE
+ echo "$HOSTNAME.localdomain $MACS"
+ else
+ echo "$HOST_FQDN $MACS"
+ fi
+
+{% for role in roles %}
+ CollectMacDeployments{{role.name}}:
+ type: OS::Heat::SoftwareDeployments
+ properties:
+ name: CollectMacDeployments{{role.name}}
+ servers: {get_param: [servers, {{role.name}}]}
+ config: {get_resource: CollectMacConfig}
+ actions: ['CREATE'] # Only do this on CREATE
+{% endfor %}
+
+ # Now we calculate the additional nexus config based on the mappings
+ MappingToNexusConfig:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ group: script
+ inputs:
+ {%- for role in roles %}
+ - name: {{role.name}}_mappings
+ {%- endfor %}
+ - name: nexus_config
+ config: |
+ #!/bin/python
+ import ast
+ import json
+ import os
+ from copy import deepcopy
+
+ mappings = [{%- for role in roles %}
+ '{{role.name}}_mappings',
+ {%- endfor %}
+ 'nexus_config']
+ mapdict_list = []
+ nexus = {}
+ for map_name in mappings:
+ f_name = '/root/' + map_name
+ map_data = os.getenv(map_name, "Nada")
+ with os.fdopen(os.open(f_name,
+ os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644),
+ 'w') as f:
+ f.write(map_data)
+ if map_data is not "Nada":
+ if map_name is not 'nexus_config':
+ mapdict_list.append(ast.literal_eval(map_data))
+ else:
+ nexus = ast.literal_eval(map_data)
+
+ mac2host = {}
+ for mapdict in mapdict_list:
+ for (listnum, host2mac_list) in mapdict.iteritems():
+ vals = host2mac_list.rstrip().split()
+ for mac in vals[1:]:
+ mac2host[mac.lower()] = vals[0]
+
+ with os.fdopen(os.open('/root/mac2host',
+ os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644),
+ 'w') as f:
+ f.write(str(mac2host))
+
+ # now we have mac to host, map host to switchport in hieradata
+ # nexus = ast.literal_eval(os.getenv('nexus_config', None))
+ nexus_cp = deepcopy(nexus)
+ for nexus_switch in nexus:
+ for (mac,swport) in nexus[nexus_switch]['servers'].iteritems():
+ lmac=mac.lower()
+ if lmac in mac2host:
+ hostname = mac2host[lmac]
+ # for puppet we need a unique title even at the 2nd key level
+ serv_key = nexus_switch + "::" + hostname
+ if serv_key in nexus_cp[nexus_switch]['servers']:
+ nexus_cp[nexus_switch]['servers'][serv_key]['ports'] += ',' + swport['ports']
+ else:
+ nexus_cp[nexus_switch]['servers'][serv_key] = swport
+ nexus_cp[nexus_switch]['servers'][serv_key]['hostname'] = hostname
+ del nexus_cp[nexus_switch]['servers'][mac]
+ # Note this echo means you can view the data via heat deployment-show
+ print json.dumps(nexus_cp)
+
+ MappingToNexusDeploymentsController:
+ type: OS::Heat::SoftwareDeployment
+ properties:
+ name: MappingToNexusDeploymentsController
+ server: {get_param: [servers, Controller, '0']}
+ config: {get_resource: MappingToNexusConfig}
+ input_values:
+ # FIXME(shardy): It'd be more convenient if we could join these
+ # items together but because the returned format is a map (not a list)
+ # we can't use list_join or str_replace. Possible Heat TODO.
+ {%- for role in roles %}
+ {{role.name}}_mappings: {get_attr: [CollectMacDeployments{{role.name}}, deploy_stdouts]}
+ {%- endfor %}
+ nexus_config: {get_param: NetworkNexusConfig}
+ actions: ['CREATE'] # Only do this on CREATE
+
+ MappingToUCSMConfig:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ group: script
+ inputs:
+ - name: ucsm_config
+ config: |
+ #!/bin/python
+ import ast
+ import os
+ with open('/root/mac2host', 'r') as f:
+ s=f.read()
+ m2h=ast.literal_eval(s)
+ ucs_config = os.getenv('ucsm_config', "Nada")
+ ucs_data = []
+ lines = ucs_config.split(',')
+ for line in lines:
+ entry=line.rsplit(":",1)
+ mac = entry[0].lower().strip()
+ if mac in m2h:
+ ucs_data.append(m2h[mac] + ":" + entry[1])
+
+ print ", ".join(ucs_data)
+
+
+ MappingToUCSMDeploymentsController:
+ type: OS::Heat::SoftwareDeployment
+ depends_on: MappingToNexusDeploymentsController
+ properties:
+ name: MappingToUCSMDeploymentsController
+ server: {get_param: [servers, Controller, '0']}
+ config: {get_resource: MappingToUCSMConfig}
+ input_values:
+ ucsm_config: {get_param: NetworkUCSMHostList}
+ actions: ['CREATE'] # Only do this on CREATE