157 lines
4.9 KiB
Python
157 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import logging
|
|
import os
|
|
import yaml
|
|
|
|
from zaza import model
|
|
from zaza.charm_lifecycle import utils as lifecycle_utils
|
|
from zaza.utilities import juju as juju_utils
|
|
|
|
|
|
def dict_to_yaml(dict_data):
|
|
"""Return YAML from dictionary
|
|
|
|
:param dict_data: Dictionary data
|
|
:type dict_data: dict
|
|
:returns: YAML dump
|
|
:rtype: string
|
|
"""
|
|
|
|
return yaml.dump(dict_data, default_flow_style=False)
|
|
|
|
|
|
def get_network_config(net_topology, ignore_env_vars=False,
|
|
net_topology_file="network.yaml"):
|
|
"""Get network info from network.yaml, override the values if specific
|
|
environment variables are set for the undercloud.
|
|
|
|
This function may be used when running network configuration from CLI to
|
|
pass in network configuration settings from a YAML file.
|
|
|
|
:param net_topology: Network topology name from network.yaml
|
|
:type net_topology: string
|
|
:param ignore_env_vars: Ignore enviroment variables or not
|
|
:type ignore_env_vars: boolean
|
|
:returns: Dictionary of network configuration
|
|
:rtype: dict
|
|
"""
|
|
|
|
if os.path.exists(net_topology_file):
|
|
net_info = get_yaml_config(net_topology_file)[net_topology]
|
|
else:
|
|
raise Exception("Network topology file: {} not found."
|
|
.format(net_topology_file))
|
|
|
|
if not ignore_env_vars:
|
|
logging.info("Consuming network environment variables as overrides "
|
|
"for the undercloud.")
|
|
net_info.update(get_undercloud_env_vars())
|
|
|
|
logging.info("Network info: {}".format(dict_to_yaml(net_info)))
|
|
return net_info
|
|
|
|
|
|
def get_pkg_version(application, pkg):
|
|
"""Return package version
|
|
|
|
:param application: Application name
|
|
:type application: string
|
|
:param pkg: Package name
|
|
:type pkg: string
|
|
:returns: List of package version
|
|
:rtype: list
|
|
"""
|
|
|
|
versions = []
|
|
units = model.get_units(
|
|
lifecycle_utils.get_juju_model(), application)
|
|
for unit in units:
|
|
cmd = 'dpkg -l | grep {}'.format(pkg)
|
|
out = juju_utils.remote_run(unit.entity_id, cmd)
|
|
versions.append(out.split('\n')[0].split()[2])
|
|
if len(set(versions)) != 1:
|
|
raise Exception('Unexpected output from pkg version check')
|
|
return versions[0]
|
|
|
|
|
|
def get_undercloud_env_vars():
|
|
""" Get environment specific undercloud network configuration settings from
|
|
environment variables.
|
|
|
|
For each testing substrate, specific undercloud network configuration
|
|
settings should be exported into the environment to enable testing on that
|
|
substrate.
|
|
|
|
Note: *Overcloud* settings should be declared by the test caller and should
|
|
not be overridden here.
|
|
|
|
Return a dictionary compatible with zaza.configure.network functions'
|
|
expected key structure.
|
|
|
|
Example exported environment variables:
|
|
export default_gateway="172.17.107.1"
|
|
export external_net_cidr="172.17.107.0/24"
|
|
export external_dns="10.5.0.2"
|
|
export start_floating_ip="172.17.107.200"
|
|
export end_floating_ip="172.17.107.249"
|
|
|
|
Example o-c-t & uosci non-standard environment variables:
|
|
export NET_ID="a705dd0f-5571-4818-8c30-4132cc494668"
|
|
export GATEWAY="172.17.107.1"
|
|
export CIDR_EXT="172.17.107.0/24"
|
|
export NAMESERVER="10.5.0.2"
|
|
export FIP_RANGE="172.17.107.200:172.17.107.249"
|
|
|
|
:returns: Network environment variables
|
|
:rtype: dict
|
|
"""
|
|
|
|
# Handle backward compatibile OSCI enviornment variables
|
|
_vars = {}
|
|
_vars['net_id'] = os.environ.get('NET_ID')
|
|
_vars['external_dns'] = os.environ.get('NAMESERVER')
|
|
_vars['default_gateway'] = os.environ.get('GATEWAY')
|
|
_vars['external_net_cidr'] = os.environ.get('CIDR_EXT')
|
|
|
|
# Take FIP_RANGE and create start and end floating ips
|
|
_fip_range = os.environ.get('FIP_RANGE')
|
|
if _fip_range and ':' in _fip_range:
|
|
_vars['start_floating_ip'] = os.environ.get('FIP_RANGE').split(':')[0]
|
|
_vars['end_floating_ip'] = os.environ.get('FIP_RANGE').split(':')[1]
|
|
|
|
# Env var naming consistent with zaza.configure.network functions takes
|
|
# priority. Override backward compatible settings.
|
|
_keys = ['default_gateway',
|
|
'start_floating_ip',
|
|
'end_floating_ip',
|
|
'external_dns',
|
|
'external_net_cidr']
|
|
for _key in _keys:
|
|
_val = os.environ.get(_key)
|
|
if _val:
|
|
_vars[_key] = _val
|
|
|
|
# Remove keys and items with a None value
|
|
for k, v in list(_vars.items()):
|
|
if not v:
|
|
del _vars[k]
|
|
|
|
return _vars
|
|
|
|
|
|
def get_yaml_config(config_file):
|
|
"""Return configuration from YAML file
|
|
|
|
:param config_file: Configuration file name
|
|
:type config_file: string
|
|
:returns: Dictionary of configuration
|
|
:rtype: dict
|
|
"""
|
|
|
|
# Note in its original form get_mojo_config it would do a search pattern
|
|
# through mojo stage directories. This version assumes the yaml file is in
|
|
# the pwd.
|
|
logging.info('Using config %s' % (config_file))
|
|
return yaml.load(open(config_file, 'r').read())
|