tripleo-heat-templates/firstboot/os-net-config-mappings.yaml
Alex Schultz 1e5ccb4c7d Handle python binary look for scripts
We have some scripts that we deploy via tripleo that use inline python.
For this we need to be able to find an available python on the system in
order for it to work. This change adds a lookup function to the scripts
to find a working version of python as /usr/bin/python may not exist.

Change-Id: Ida7a7cbd064ebdb923f38c9102eb4b0771f9b273
Related-Blueprint: python3-support
2018-11-26 16:48:51 +00:00

120 lines
4.2 KiB
YAML

heat_template_version: rocky
description: >
Configure os-net-config mappings for specific nodes
Your environment file needs to look like:
parameter_defaults:
NetConfigDataLookup:
node1:
nic1: "00:c8:7c:e6:f0:2e"
node2:
nic1: "00:18:7d:99:0c:b6"
node3:
dmiString: 'system-uuid'
id: 'A8C85861-1B16-4803-8689-AFC62984F8F6'
nic1: em3
# Dell PowerEdge
nodegroup1:
dmiString: "system-product-name"
id: "PowerEdge R630"
nic1: em3
nic2: em1
nic3: em2
# Cisco UCS B200-M4"
nodegroup2:
dmiString: "system-product-name"
id: "UCSB-B200-M4"
nic1: enp7s0
nic2: enp6s0
This will result in the first node* entry where either:
a) a mac matches a local device
or b) a DMI String matches the specified id
being written as a mapping file for os-net-config in
/etc/os-net-config/mapping.yaml
parameters:
# Note this requires a liberty heat or newer in the undercloud due to
# the 2015-10-15 (which is required to enable str_replace serializing
# the json parameter to json, another approch with a string parameter
# will be required for older heat versions)
NetConfigDataLookup:
type: json
default: {}
description: per-node configuration map
resources:
userdata:
type: OS::Heat::MultipartMime
properties:
parts:
- config: {get_resource: OsNetConfigMappings}
OsNetConfigMappings:
type: OS::Heat::SoftwareConfig
properties:
group: ungrouped
config:
str_replace:
template: |
#!/bin/sh
eth_addr=$(cat /sys/class/net/*/address | tr '\n' ',')
mkdir -p /etc/os-net-config
# needed to handle where python lives
function get_python() {
command -v python3 || command -v python2 || command -v python || exit 1
}
# Create an os-net-config mapping file, note this defaults to
# /etc/os-net-config/mapping.yaml, so we use that name despite
# rendering the result as json
echo '$node_lookup' | $(get_python) -c "
import json
import sys
import copy
from subprocess import PIPE, Popen
import yaml
def write_mapping_file(interface_mapping):
with open('/etc/os-net-config/mapping.yaml', 'w') as f:
yaml.safe_dump(interface_mapping, f, default_flow_style=False)
# cast to lower case for MAC address match
eth_addr='$eth_addr'.lower()
input = sys.stdin.readline() or '{}'
data = json.loads(input)
for node in data:
interface_mapping = {'interface_mapping':
copy.deepcopy(data[node])}
if 'dmiString' in interface_mapping['interface_mapping']:
del interface_mapping['interface_mapping']['dmiString']
if 'id' in interface_mapping['interface_mapping']:
del interface_mapping['interface_mapping']['id']
# Match on mac addresses first - cast all to lower case
lc_interface_mapping = copy.deepcopy(interface_mapping)
for key,x in lc_interface_mapping['interface_mapping'].items():
lc_interface_mapping['interface_mapping'][key] = x.lower()
if any(x in eth_addr.split(',') for x in lc_interface_mapping['interface_mapping'].values()):
write_mapping_file(lc_interface_mapping)
break
# If data contain dmiString and id keys, try to match node(group)
if 'dmiString' in data[node] and 'id' in data[node]:
ps = Popen([ 'dmidecode',
'--string', data[node].get('dmiString') ],
stdout=PIPE)
out, err = ps.communicate()
if data[node].get('id') == out.rstrip():
write_mapping_file(lc_interface_mapping)
break
"
params:
$node_lookup: {get_param: NetConfigDataLookup}
outputs:
OS::stack_id:
value: {get_resource: userdata}