95245f6ad4
Since os-apply-config changed to the hiera hook here:
c5d10cd9fc
the mapped_data key is no longer required and results in an additional
incorrect key being written to the hiera data. This patch removes it to
ensure the hiera data for cisco ml2 works as expected.
Change-Id: I730b107d4b5a002f82f658a83d11162606e44a16
Closes-Bug: #1791044
285 lines
11 KiB
YAML
285 lines
11 KiB
YAML
heat_template_version: rocky
|
|
|
|
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: ''
|
|
hidden: true
|
|
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: ''
|
|
NetworkUCSMHttpsVerify:
|
|
type: boolean
|
|
description: >
|
|
Enabling/disabling UCS Manager SSL certificate verification
|
|
default: true
|
|
NetworkUCSMSpTemplateList:
|
|
type: string
|
|
description: Host to Service Profile Template mapping with its path
|
|
default: ''
|
|
NetworkUCSMVnicTemplateList:
|
|
type: string
|
|
description: >
|
|
Neutron physical network to vNIC Template mapping with its path
|
|
default: ''
|
|
NetworkNexusConfig:
|
|
type: json
|
|
description: Nexus switch configuration
|
|
default: {}
|
|
NetworkNexusManagedPhysicalNetwork:
|
|
type: string
|
|
description: The name of the physical_network
|
|
default: ''
|
|
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: 30
|
|
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
|
|
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:
|
|
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::ucsm::ucsm_https_verify: {get_input: UCSMHttpsVerify}
|
|
neutron::plugins::ml2::cisco::ucsm::sp_template_list: {get_input: UCSMSpTemplateList}
|
|
neutron::plugins::ml2::cisco::ucsm::vnic_template_list: {get_input: UCSMVnicTemplateList}
|
|
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::switch_heartbeat_time: {get_input: NexusSwitchHeartbeatTime}
|
|
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::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}
|
|
UCSMHttpsVerify: {get_param: NetworkUCSMHttpsVerify}
|
|
UCSMSpTemplateList: {get_param: NetworkUCSMSpTemplateList}
|
|
UCSMVnicTemplateList: {get_param: NetworkUCSMVnicTemplateList}
|
|
NexusConfig: {get_attr: [MappingToNexusDeploymentsController, deploy_stdout]}
|
|
NexusManagedPhysicalNetwork: {get_param: NetworkNexusManagedPhysicalNetwork}
|
|
NexusSwitchHeartbeatTime: {get_param: NetworkNexusSwitchHeartbeatTime}
|
|
NexusProviderVlanAutoCreate: {get_param: NetworkNexusProviderVlanAutoCreate}
|
|
NexusProviderVlanAutoTrunk: {get_param: NetworkNexusProviderVlanAutoTrunk}
|
|
NexusVxlanGlobalConfig: {get_param: NetworkNexusVxlanGlobalConfig}
|
|
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
|