You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
11 KiB
285 lines
11 KiB
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: |
|
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::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
|
|
|