Make hardware types configurable, plus fixes
* Made hardware types configurable. IPMI, redfish and iDrac for now * Removed unnecessary class * Explicitly set python_version to 3 * Add functional tests Change-Id: Id774352487da05faa47dc953031b921df40d3ecc Func-Test-Pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/450
This commit is contained in:
parent
40b09a55e7
commit
9883204a85
4
.gitreview
Normal file
4
.gitreview
Normal file
@ -0,0 +1,4 @@
|
||||
[gerrit]
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/charm-ironic-conductor.git
|
4
.zuul.yaml
Normal file
4
.zuul.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-python3-charm-jobs
|
||||
- openstack-cover-jobs
|
@ -159,3 +159,12 @@ options:
|
||||
|
||||
Note: Automated cleaning can be toggled on a per node basis, via node properties.
|
||||
Note: node cleaning may take a long time, especially if secure erase is enabled.
|
||||
enabled-hw-types:
|
||||
default: "ipmi"
|
||||
type: string
|
||||
description: |
|
||||
Comma separated list of hardware types to enable.
|
||||
Valid options are:
|
||||
* ipmi
|
||||
* redfish
|
||||
* idrac
|
||||
|
@ -5,10 +5,10 @@ includes:
|
||||
- interface:rabbitmq
|
||||
- interface:keystone-credentials
|
||||
- interface:ironic-api
|
||||
repo: https://github.com/gabriel-samfira/charm-ironic-conductor
|
||||
repo: https://opendev.org/openstack/charm-ironic-conductor.git
|
||||
options:
|
||||
basic:
|
||||
use_venv: true
|
||||
include_system_packages: False
|
||||
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3.6-dev' ]
|
||||
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3-dev' ]
|
||||
|
||||
|
@ -6,8 +6,10 @@ import glanceclient
|
||||
import swiftclient
|
||||
import keystoneclient
|
||||
|
||||
SYSTEM_CA_BUNDLE = '/etc/ssl/certs/ca-certificates.crt'
|
||||
|
||||
def create_keystone_session(keystone, verify=True):
|
||||
|
||||
def create_keystone_session(keystone):
|
||||
plugin_name = "password"
|
||||
username = keystone.credentials_username()
|
||||
password = keystone.credentials_password()
|
||||
@ -41,17 +43,17 @@ def create_keystone_session(keystone, verify=True):
|
||||
|
||||
loader = loading.get_plugin_loader(plugin_name)
|
||||
auth = loader.load_from_options(**plugin_args)
|
||||
return ks_session.Session(auth=auth, verify=verify)
|
||||
return ks_session.Session(auth=auth, verify=SYSTEM_CA_BUNDLE)
|
||||
|
||||
|
||||
class OSClients(object):
|
||||
|
||||
def __init__(self, session, cacert=None):
|
||||
def __init__(self, session):
|
||||
self._session = session
|
||||
self._img_cli = glanceclient.Client(
|
||||
session=self._session, version=2)
|
||||
self._obj_cli = swiftclient.Connection(
|
||||
session=self._session, cacert=cacert)
|
||||
session=self._session, cacert=SYSTEM_CA_BUNDLE)
|
||||
self._ks = keystoneclient.v3.Client(
|
||||
session=session)
|
||||
self._stores = None
|
||||
|
@ -25,7 +25,7 @@ class PXEBootBase(object):
|
||||
"/usr/lib/syslinux/modules/bios/chain.c32": "chain.c32",
|
||||
"/usr/lib/syslinux/modules/bios/ldlinux.c32": "ldlinux.c32",
|
||||
"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed": "grubx64.efi",
|
||||
"/usr/lib/shim/shim.efi.signed": "bootx64.efi",
|
||||
"/usr/lib/shim/shimx64.efi.signed": "bootx64.efi",
|
||||
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
|
||||
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
|
||||
}
|
||||
@ -65,7 +65,7 @@ class PXEBootBase(object):
|
||||
for f in self.FILE_MAP:
|
||||
if os.path.isfile(f) is False:
|
||||
raise ValueError(
|
||||
"Missing required file %s. Package not installes?" % f)
|
||||
"Missing required file %s. Package not installed?" % f)
|
||||
shutil.copy(
|
||||
f, os.path.join(self.TFTP_ROOT, self.FILE_MAP[f]),
|
||||
follow_symlinks=True)
|
||||
@ -88,27 +88,9 @@ class PXEBootBase(object):
|
||||
self.HTTP_ROOT, _IRONIC_USER, _IRONIC_GROUP, chowntopdir=True)
|
||||
|
||||
|
||||
class PXEBootBionic(PXEBootBase):
|
||||
|
||||
# This is a file map of source to destination. The destination is
|
||||
# relative to self.TFTP_ROOT
|
||||
FILE_MAP = {
|
||||
"/usr/lib/PXELINUX/pxelinux.0": "pxelinux.0",
|
||||
"/usr/lib/syslinux/modules/bios/chain.c32": "chain.c32",
|
||||
"/usr/lib/syslinux/modules/bios/ldlinux.c32": "ldlinux.c32",
|
||||
"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed": "grubx64.efi",
|
||||
"/usr/lib/shim/shimx64.efi.signed": "bootx64.efi",
|
||||
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
|
||||
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
|
||||
}
|
||||
|
||||
|
||||
def get_pxe_config_class(charm_config):
|
||||
# We may need to make slight adjustments to package names and/or
|
||||
# configuration files, based on the version of Ubuntu we are installing
|
||||
# on. This function serves as a factory which will return an instance
|
||||
# of the proper class to the charm. For now we only have one class.
|
||||
series = ch_host.get_distrib_codename()
|
||||
if series == "bionic":
|
||||
return PXEBootBionic(charm_config)
|
||||
return PXEBootBase(charm_config)
|
||||
|
@ -10,6 +10,7 @@ from charms_openstack.adapters import (
|
||||
DatabaseRelationAdapter,
|
||||
OpenStackRelationAdapters,
|
||||
)
|
||||
from charmhelpers.contrib.openstack.utils import os_release
|
||||
|
||||
import charm.openstack.ironic.controller_utils as controller_utils
|
||||
import charms_openstack.adapters as adapters
|
||||
@ -19,15 +20,14 @@ import charms.reactive as reactive
|
||||
|
||||
PACKAGES = [
|
||||
'ironic-conductor',
|
||||
'python3-dracclient',
|
||||
'python3-keystoneauth1',
|
||||
'python3-keystoneclient',
|
||||
'python3-glanceclient',
|
||||
'python3-swiftclient',
|
||||
'python-mysqldb',
|
||||
'python3-dracclient',
|
||||
'python3-sushy',
|
||||
'python3-swiftclient',
|
||||
'python3-mysqldb',
|
||||
'python3-ironicclient',
|
||||
'python3-scciclient',
|
||||
'shellinabox',
|
||||
'openssl',
|
||||
'socat',
|
||||
@ -50,6 +50,100 @@ VALID_DEPLOY_INTERFACES = ["direct", "iscsi"]
|
||||
DEFAULT_DEPLOY_IFACE = "flat"
|
||||
DEFAULT_NET_IFACE = "direct"
|
||||
|
||||
# The IPMI HW type requires only ipmitool to function. This HW type
|
||||
# remains pretty much unchanged across OpenStack releases and *should*
|
||||
# work
|
||||
_NOOP_INTERFACES = {
|
||||
'enabled_bios_interfaces': 'no-bios',
|
||||
'enabled_management_interfaces': 'noop',
|
||||
'enabled_inspect_interfaces': 'no-inspect',
|
||||
'enabled_console_interfaces': 'no-console',
|
||||
'enabled_raid_interfaces': 'no-raid',
|
||||
'enabled_vendor_interfaces': 'no-vendor',
|
||||
}
|
||||
_IPMI_HARDWARE_TYPE = {
|
||||
'needed_packages': ['ipmitool', 'shellinabox', 'socat'],
|
||||
'config_options': {
|
||||
'enabled_hardware_types': ['ipmi', 'intel-ipmi'],
|
||||
'enabled_management_interfaces': [
|
||||
'ipmitool', 'intel-ipmitool'],
|
||||
'enabled_inspect_interfaces': [],
|
||||
'enabled_power_interfaces': ['ipmitool'],
|
||||
'enabled_console_interfaces': [
|
||||
'ipmitool-socat',
|
||||
'ipmitool-shellinabox'],
|
||||
'enabled_raid_interfaces': [],
|
||||
'enabled_vendor_interfaces': ['ipmitool'],
|
||||
'enabled_boot_interfaces': ['pxe'],
|
||||
'enabled_bios_interfaces': []
|
||||
}
|
||||
}
|
||||
|
||||
_HW_TYPES_MAP = collections.OrderedDict([
|
||||
('train', {
|
||||
'ipmi': _IPMI_HARDWARE_TYPE,
|
||||
'redfish': {
|
||||
'needed_packages': ['python3-sushy'],
|
||||
'config_options': {
|
||||
'enabled_hardware_types': ['redfish'],
|
||||
'enabled_management_interfaces': ['redfish'],
|
||||
'enabled_inspect_interfaces': ['redfish'],
|
||||
'enabled_power_interfaces': ['redfish'],
|
||||
'enabled_console_interfaces': [],
|
||||
'enabled_raid_interfaces': [],
|
||||
'enabled_vendor_interfaces': [],
|
||||
'enabled_boot_interfaces': ['pxe'],
|
||||
'enabled_bios_interfaces': []
|
||||
}
|
||||
},
|
||||
'idrac': {
|
||||
'needed_packages': ['python-dracclient', 'python3-sushy'],
|
||||
'config_options': {
|
||||
'enabled_hardware_types': ['idrac'],
|
||||
'enabled_management_interfaces': ['idrac-redfish'],
|
||||
'enabled_inspect_interfaces': ['idrac-redfish'],
|
||||
'enabled_power_interfaces': ['idrac-redfish'],
|
||||
'enabled_console_interfaces': [],
|
||||
'enabled_raid_interfaces': ['idrac-wsman'],
|
||||
'enabled_vendor_interfaces': ['idrac-wsman'],
|
||||
'enabled_boot_interfaces': ['pxe'],
|
||||
'enabled_bios_interfaces': []
|
||||
}
|
||||
}
|
||||
}),
|
||||
('ussuri', {
|
||||
'ipmi': _IPMI_HARDWARE_TYPE,
|
||||
'redfish': {
|
||||
'needed_packages': ['python3-sushy'],
|
||||
'config_options': {
|
||||
'enabled_hardware_types': ['redfish'],
|
||||
'enabled_management_interfaces': ['redfish'],
|
||||
'enabled_inspect_interfaces': ['redfish'],
|
||||
'enabled_power_interfaces': ['redfish'],
|
||||
'enabled_console_interfaces': [],
|
||||
'enabled_raid_interfaces': [],
|
||||
'enabled_vendor_interfaces': [],
|
||||
'enabled_boot_interfaces': ['pxe', 'redfish-virtual-media'],
|
||||
'enabled_bios_interfaces': [],
|
||||
}
|
||||
},
|
||||
'idrac': {
|
||||
'needed_packages': ['python-dracclient', 'python3-sushy'],
|
||||
'config_options': {
|
||||
'enabled_hardware_types': ['idrac'],
|
||||
'enabled_management_interfaces': ['idrac-redfish'],
|
||||
'enabled_inspect_interfaces': ['idrac-redfish'],
|
||||
'enabled_power_interfaces': ['idrac-redfish'],
|
||||
'enabled_console_interfaces': [],
|
||||
'enabled_raid_interfaces': ['idrac-wsman'],
|
||||
'enabled_vendor_interfaces': ['idrac-wsman'],
|
||||
'enabled_boot_interfaces': ['pxe'],
|
||||
'enabled_bios_interfaces': ['idrac-wsman']
|
||||
}
|
||||
}
|
||||
})
|
||||
])
|
||||
|
||||
OPENSTACK_RELEASE_KEY = 'ironic-charm.openstack-release-version'
|
||||
|
||||
|
||||
@ -89,6 +183,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
release = 'train'
|
||||
name = 'ironic'
|
||||
packages = PACKAGES
|
||||
python_version = 3
|
||||
|
||||
service_type = 'ironic'
|
||||
default_service = 'ironic-conductor'
|
||||
@ -127,6 +222,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
self.pxe_config = controller_utils.get_pxe_config_class(
|
||||
self.config)
|
||||
self._setup_pxe_config(self.pxe_config)
|
||||
self._setup_power_adapter_config()
|
||||
self._configure_defaults()
|
||||
if "neutron" in self.enabled_network_interfaces:
|
||||
self.mandatory_config.extend([
|
||||
@ -141,6 +237,65 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
if not iface:
|
||||
self.config["default-deploy-interface"] = DEFAULT_DEPLOY_IFACE
|
||||
|
||||
def _get_hw_type_map(self):
|
||||
release = os_release(self.release_pkg)
|
||||
supported = list(_HW_TYPES_MAP.keys())
|
||||
latest = supported[-1]
|
||||
hw_type_map = _HW_TYPES_MAP.get(
|
||||
release, _HW_TYPES_MAP[latest])
|
||||
return hw_type_map
|
||||
|
||||
def _get_power_adapter_packages(self):
|
||||
pkgs = []
|
||||
hw_type_map = self._get_hw_type_map()
|
||||
for hw_type in self.enabled_hw_types:
|
||||
needed_pkgs = hw_type_map.get(
|
||||
hw_type, {}).get("needed_packages", [])
|
||||
pkgs.extend(needed_pkgs)
|
||||
return list(set(pkgs))
|
||||
|
||||
def _get_hardware_types_config(self):
|
||||
hw_type_map = self._get_hw_type_map()
|
||||
configs = {}
|
||||
for hw_type in self.enabled_hw_types:
|
||||
details = hw_type_map.get(hw_type, None)
|
||||
if details is None:
|
||||
# Not a valid hardware type. No need to raise here,
|
||||
# we will let the operator know when we validate the
|
||||
# config in custom_assess_status_check()
|
||||
continue
|
||||
driver_cfg = details['config_options']
|
||||
for cfg_opt in driver_cfg.items():
|
||||
if not configs.get(cfg_opt[0], None):
|
||||
configs[cfg_opt[0]] = cfg_opt[1]
|
||||
else:
|
||||
configs[cfg_opt[0]].extend(cfg_opt[1])
|
||||
opt_list = list(set(configs[cfg_opt[0]]))
|
||||
opt_list.sort()
|
||||
configs[cfg_opt[0]] = opt_list
|
||||
|
||||
if self.config.get('use-ipxe', None):
|
||||
configs["enabled_boot_interfaces"].append('ipxe')
|
||||
|
||||
# append the noop interfaces at the end
|
||||
for noop in _NOOP_INTERFACES:
|
||||
if configs.get(noop, None) is not None:
|
||||
configs[noop].append(_NOOP_INTERFACES[noop])
|
||||
|
||||
for opt in configs:
|
||||
if len(configs[opt]) > 0:
|
||||
configs[opt] = ", ".join(configs[opt])
|
||||
else:
|
||||
configs[opt] = ""
|
||||
return configs
|
||||
|
||||
def _setup_power_adapter_config(self):
|
||||
pkgs = self._get_power_adapter_packages()
|
||||
config = self._get_hardware_types_config()
|
||||
self.packages.extend(pkgs)
|
||||
self.packages = list(set(self.packages))
|
||||
self.config["hardware_type_cfg"] = config
|
||||
|
||||
def _setup_pxe_config(self, cfg):
|
||||
self.packages.extend(cfg.determine_packages())
|
||||
self.packages = list(set(self.packages))
|
||||
@ -178,7 +333,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
for interface in interfaces:
|
||||
if interface not in valid_interfaces:
|
||||
raise ValueError(
|
||||
'Network interface "%s" is not valid. Valid '
|
||||
'Network interface %s is not valid. Valid '
|
||||
'interfaces are: %s' % (
|
||||
interface, ", ".join(valid_interfaces)))
|
||||
|
||||
@ -197,14 +352,14 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
for interface in interfaces:
|
||||
if interface not in valid_interfaces:
|
||||
raise ValueError(
|
||||
'Deploy interface "%s" is not valid. Valid '
|
||||
'Deploy interface %s is not valid. Valid '
|
||||
'interfaces are: %s' % (
|
||||
interface, ", ".join(valid_interfaces)))
|
||||
if reactive.is_flag_set("config.complete"):
|
||||
if "direct" in interfaces and has_secret is False:
|
||||
raise ValueError(
|
||||
'run "set-temp-url-secret" action on leader to '
|
||||
'enable "direct" deploy method')
|
||||
'run set-temp-url-secret action on leader to '
|
||||
'enable direct deploy method')
|
||||
|
||||
def _validate_default_deploy_interface(self):
|
||||
iface = self.config["default-deploy-interface"]
|
||||
@ -215,12 +370,29 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
iface, ", ".join(
|
||||
self.enabled_deploy_interfaces)))
|
||||
|
||||
def _validate_enabled_hw_type(self):
|
||||
hw_types = self._get_hw_type_map()
|
||||
unsupported = []
|
||||
for hw_type in self.enabled_hw_types:
|
||||
if hw_types.get(hw_type, None) is None:
|
||||
unsupported.append(hw_type)
|
||||
if len(unsupported) > 0:
|
||||
raise ValueError(
|
||||
'hardware type(s) %s not supported at '
|
||||
'this time' % ", ".join(unsupported))
|
||||
|
||||
@property
|
||||
def enabled_network_interfaces(self):
|
||||
network_interfaces = self.config.get(
|
||||
'enabled-network-interfaces', "").replace(" ", "")
|
||||
return network_interfaces.split(",")
|
||||
|
||||
@property
|
||||
def enabled_hw_types(self):
|
||||
hw_types = self.config.get(
|
||||
'enabled-hw-types', "ipmi").replace(" ", "")
|
||||
return hw_types.split(",")
|
||||
|
||||
@property
|
||||
def enabled_deploy_interfaces(self):
|
||||
network_interfaces = self.config.get(
|
||||
@ -231,25 +403,32 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||
try:
|
||||
self._validate_network_interfaces(self.enabled_network_interfaces)
|
||||
except Exception as err:
|
||||
msg = ("invalid enabled-network-interfaces config: %s" % err)
|
||||
msg = ("invalid enabled-network-interfaces config, %s" % err)
|
||||
return ('blocked', msg)
|
||||
|
||||
try:
|
||||
self._validate_default_net_interface()
|
||||
except Exception as err:
|
||||
msg = ("invalid default-network-interface config: %s" % err)
|
||||
msg = ("invalid default-network-interface config, %s" % err)
|
||||
return ('blocked', msg)
|
||||
|
||||
try:
|
||||
self._validate_deploy_interfaces(
|
||||
self.enabled_deploy_interfaces)
|
||||
except Exception as err:
|
||||
msg = ("invalid enabled-deploy-interfaces config: %s" % err)
|
||||
msg = ("invalid enabled-deploy-interfaces config, %s" % err)
|
||||
return ('blocked', msg)
|
||||
|
||||
try:
|
||||
self._validate_default_deploy_interface()
|
||||
except Exception as err:
|
||||
msg = ("invalid default-deploy-interface config: %s" % err)
|
||||
msg = ("invalid default-deploy-interface config, %s" % err)
|
||||
return ('blocked', msg)
|
||||
|
||||
try:
|
||||
self._validate_enabled_hw_type()
|
||||
except Exception as err:
|
||||
msg = ("invalid enabled-hw-types config, %s" % err)
|
||||
return ('blocked', msg)
|
||||
|
||||
return (None, None)
|
||||
|
@ -5,20 +5,21 @@ auth_strategy=keystone
|
||||
my_ip = {{ options.internal_interface_ip }}
|
||||
|
||||
enabled_deploy_interfaces = {{ options.enabled_deploy_interfaces }}
|
||||
enabled_hardware_types = ipmi,ilo,idrac,redfish,irmc
|
||||
{% if options.use_ipxe -%}
|
||||
enabled_boot_interfaces = pxe,ipxe,ilo-pxe,ilo-ipxe,irmc-pxe
|
||||
{% else -%}
|
||||
enabled_boot_interfaces = pxe,ilo-pxe,irmc-pxe
|
||||
{% endif -%}
|
||||
enabled_management_interfaces = ipmitool,redfish,ilo,irmc,idrac,noop
|
||||
enabled_inspect_interfaces = idrac,ilo,irmc,redfish,no-inspect
|
||||
enabled_hardware_types = {{ options.hardware_type_cfg.enabled_hardware_types }}
|
||||
enabled_boot_interfaces = {{ options.hardware_type_cfg.enabled_boot_interfaces }}
|
||||
|
||||
enabled_management_interfaces = {{ options.hardware_type_cfg.enabled_management_interfaces }}
|
||||
enabled_inspect_interfaces = {{ options.hardware_type_cfg.enabled_inspect_interfaces }}
|
||||
|
||||
enabled_network_interfaces = {{ options.enabled_network_interfaces }}
|
||||
enabled_power_interfaces = ipmitool,redfish,ilo,irmc,idrac
|
||||
|
||||
enabled_power_interfaces = {{ options.hardware_type_cfg.enabled_power_interfaces }}
|
||||
enabled_storage_interfaces = cinder,noop
|
||||
enabled_console_interfaces = ipmitool-socat,ipmitool-shellinabox,no-console
|
||||
enabled_raid_interfaces = agent,idrac,irmc,no-raid
|
||||
enabled_vendor_interfaces = ipmitool,idrac,ilo,no-vendor
|
||||
|
||||
enabled_console_interfaces = {{ options.hardware_type_cfg.enabled_console_interfaces }}
|
||||
enabled_raid_interfaces = {{ options.hardware_type_cfg.enabled_raid_interfaces }}
|
||||
enabled_vendor_interfaces = {{ options.hardware_type_cfg.enabled_vendor_interfaces }}
|
||||
enabled_bios_interfaces = {{ options.hardware_type_cfg.enabled_bios_interfaces }}
|
||||
|
||||
default_deploy_interface = {{ options.default_deploy_interface }}
|
||||
default_network_interface = {{ options.default_network_interface }}
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo add-apt-repository ppa:juju/stable -y
|
||||
sudo apt-get update
|
||||
sudo apt-get install amulet python-requests -y
|
@ -1,35 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import amulet
|
||||
import requests
|
||||
import unittest
|
||||
|
||||
|
||||
class TestCharm(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.d = amulet.Deployment()
|
||||
|
||||
self.d.add('charm-ironic')
|
||||
self.d.expose('charm-ironic')
|
||||
|
||||
self.d.setup(timeout=900)
|
||||
self.d.sentry.wait()
|
||||
|
||||
self.unit = self.d.sentry['charm-ironic'][0]
|
||||
|
||||
def test_service(self):
|
||||
# test we can access over http
|
||||
page = requests.get('http://{}'.format(self.unit.info['public-address']))
|
||||
self.assertEqual(page.status_code, 200)
|
||||
# Now you can use self.d.sentry[SERVICE][UNIT] to address each of the units and perform
|
||||
# more in-depth steps. Each self.d.sentry[SERVICE][UNIT] has the following methods:
|
||||
# - .info - An array of the information of that unit from Juju
|
||||
# - .file(PATH) - Get the details of a file on that unit
|
||||
# - .file_contents(PATH) - Get plain text output of PATH file from that unit
|
||||
# - .directory(PATH) - Get details of directory
|
||||
# - .directory_contents(PATH) - List files and folders in PATH on that unit
|
||||
# - .relation(relation, service:rel) - Get relation data from return service
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
250
src/tests/bundles/bionic-train.yaml
Normal file
250
src/tests/bundles/bionic-train.yaml
Normal file
@ -0,0 +1,250 @@
|
||||
options:
|
||||
source: &source cloud:bionic-train/proposed
|
||||
series: bionic
|
||||
local_overlay_enabled: false
|
||||
relations:
|
||||
- - nova-ironic
|
||||
- ironic-api
|
||||
- - ironic-conductor
|
||||
- ironic-api
|
||||
- - neutron-ironic-agent:identity-credentials
|
||||
- keystone
|
||||
- - neutron-ironic-agent
|
||||
- neutron-api
|
||||
- - neutron-openvswitch
|
||||
- neutron-api
|
||||
- - ironic-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-api
|
||||
- keystone
|
||||
- - ironic-api:shared-db
|
||||
- mysql:shared-db
|
||||
- - ironic-conductor:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-conductor
|
||||
- keystone
|
||||
- - ironic-conductor:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-ironic:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-ironic
|
||||
- glance
|
||||
- - nova-ironic
|
||||
- keystone
|
||||
- - nova-ironic
|
||||
- nova-cloud-controller
|
||||
- - neutron-gateway:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - keystone:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-cloud-controller:identity-service
|
||||
- keystone:identity-service
|
||||
- - glance:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:shared-db
|
||||
- mysql:shared-db
|
||||
- - neutron-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - neutron-gateway:neutron-plugin-api
|
||||
- neutron-api:neutron-plugin-api
|
||||
- - glance:shared-db
|
||||
- mysql:shared-db
|
||||
- - glance:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:image-service
|
||||
- glance:image-service
|
||||
- - nova-cloud-controller:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:quantum-network-service
|
||||
- neutron-gateway:quantum-network-service
|
||||
- - nova-cloud-controller:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-cloud-controller:neutron-api
|
||||
- neutron-api:neutron-api
|
||||
- - cinder:image-service
|
||||
- glance:image-service
|
||||
- - cinder:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - cinder:identity-service
|
||||
- keystone:identity-service
|
||||
- - cinder:cinder-volume-service
|
||||
- nova-cloud-controller:cinder-volume-service
|
||||
- - cinder:shared-db
|
||||
- mysql:shared-db
|
||||
- - placement
|
||||
- mysql
|
||||
- - placement
|
||||
- keystone
|
||||
- - placement
|
||||
- nova-cloud-controller
|
||||
- - ceph-mon:client
|
||||
- nova-ironic:ceph
|
||||
- - ceph-mon:client
|
||||
- glance:ceph
|
||||
- - ceph-radosgw:mon
|
||||
- ceph-mon:radosgw
|
||||
- - ceph-radosgw:identity-service
|
||||
- keystone:identity-service
|
||||
- - ceph-osd:mon
|
||||
- ceph-mon:osd
|
||||
- - ceph-radosgw:object-store
|
||||
- glance
|
||||
- - vault:shared-db
|
||||
- mysql:shared-db
|
||||
- - vault:certificates
|
||||
- ceph-radosgw
|
||||
- - vault:certificates
|
||||
- cinder
|
||||
- - vault:certificates
|
||||
- glance:certificates
|
||||
- - vault:certificates
|
||||
- keystone:certificates
|
||||
- - vault:certificates
|
||||
- neutron-api:certificates
|
||||
- - vault:certificates
|
||||
- nova-cloud-controller:certificates
|
||||
- - vault:certificates
|
||||
- placement:certificates
|
||||
- - vault
|
||||
- ironic-conductor
|
||||
- - vault:certificates
|
||||
- ironic-api:certificates
|
||||
- - ironic-api
|
||||
- hacluster-ironic
|
||||
services:
|
||||
cinder:
|
||||
charm: cs:~openstack-charmers-next/cinder
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
block-device: vdb
|
||||
glance-api-version: 2
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
storage:
|
||||
block-devices: cinder,50G
|
||||
ceph-radosgw:
|
||||
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
namespace-tenants: True
|
||||
ceph-mon:
|
||||
charm: cs:ceph-mon
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
expected-osd-count: 3
|
||||
source: *source
|
||||
ceph-osd:
|
||||
charm: cs:ceph-osd
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
storage:
|
||||
osd-devices: 'cinder,30G'
|
||||
glance:
|
||||
charm: cs:~openstack-charmers-next/glance
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
keystone:
|
||||
charm: cs:~openstack-charmers-next/keystone
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
mysql:
|
||||
charm: cs:percona-cluster
|
||||
num_units: 1
|
||||
constraints: mem=4G
|
||||
options:
|
||||
innodb-buffer-pool-size: 256M
|
||||
max-connections: 1000
|
||||
performance-schema: true
|
||||
neutron-api:
|
||||
charm: cs:~openstack-charmers-next/neutron-api
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
flat-network-providers: "physnet1"
|
||||
neutron-security-groups: true
|
||||
openstack-origin: *source
|
||||
manage-neutron-plugin-legacy-mode: false
|
||||
worker-multiplier: 0.25
|
||||
neutron-gateway:
|
||||
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
enable-isolated-metadata: true
|
||||
enable-metadata-network: true
|
||||
bridge-mappings: physnet1:br-ex
|
||||
nova-cloud-controller:
|
||||
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
network-manager: Neutron
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
nova-ironic:
|
||||
charm: cs:~openstack-charmers-next/nova-compute
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
enable-live-migration: false
|
||||
enable-resize: false
|
||||
openstack-origin: *source
|
||||
virt-type: ironic
|
||||
placement:
|
||||
charm: cs:placement
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
rabbitmq-server:
|
||||
charm: cs:rabbitmq-server
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
hacluster-ironic:
|
||||
charm: cs:~openstack-charmers-next/hacluster
|
||||
num_units: 0
|
||||
ironic-api:
|
||||
charm: cs:~openstack-charmers-next/ironic-api
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
ironic-conductor:
|
||||
charm: ../../../ironic-conductor
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
max-tftp-block-size: 1418
|
||||
disable-secure-erase: true
|
||||
use-ipxe: true
|
||||
enabled-network-interfaces: "flat, noop"
|
||||
neutron-openvswitch:
|
||||
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||
num_units: 0
|
||||
options:
|
||||
bridge-mappings: physnet1:br-ex
|
||||
neutron-ironic-agent:
|
||||
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||
num_units: 0
|
||||
options:
|
||||
openstack-origin: *source
|
||||
vault:
|
||||
charm: cs:~openstack-charmers-next/vault
|
||||
num_units: 1
|
250
src/tests/bundles/bionic-ussuri.yaml
Normal file
250
src/tests/bundles/bionic-ussuri.yaml
Normal file
@ -0,0 +1,250 @@
|
||||
options:
|
||||
source: &source cloud:bionic-ussuri/proposed
|
||||
series: bionic
|
||||
local_overlay_enabled: false
|
||||
relations:
|
||||
- - nova-ironic
|
||||
- ironic-api
|
||||
- - ironic-conductor
|
||||
- ironic-api
|
||||
- - neutron-ironic-agent:identity-credentials
|
||||
- keystone
|
||||
- - neutron-ironic-agent
|
||||
- neutron-api
|
||||
- - neutron-openvswitch
|
||||
- neutron-api
|
||||
- - ironic-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-api
|
||||
- keystone
|
||||
- - ironic-api:shared-db
|
||||
- mysql:shared-db
|
||||
- - ironic-conductor:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-conductor
|
||||
- keystone
|
||||
- - ironic-conductor:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-ironic:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-ironic
|
||||
- glance
|
||||
- - nova-ironic
|
||||
- keystone
|
||||
- - nova-ironic
|
||||
- nova-cloud-controller
|
||||
- - neutron-gateway:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - keystone:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-cloud-controller:identity-service
|
||||
- keystone:identity-service
|
||||
- - glance:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:shared-db
|
||||
- mysql:shared-db
|
||||
- - neutron-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - neutron-gateway:neutron-plugin-api
|
||||
- neutron-api:neutron-plugin-api
|
||||
- - glance:shared-db
|
||||
- mysql:shared-db
|
||||
- - glance:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:image-service
|
||||
- glance:image-service
|
||||
- - nova-cloud-controller:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:quantum-network-service
|
||||
- neutron-gateway:quantum-network-service
|
||||
- - nova-cloud-controller:shared-db
|
||||
- mysql:shared-db
|
||||
- - nova-cloud-controller:neutron-api
|
||||
- neutron-api:neutron-api
|
||||
- - cinder:image-service
|
||||
- glance:image-service
|
||||
- - cinder:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - cinder:identity-service
|
||||
- keystone:identity-service
|
||||
- - cinder:cinder-volume-service
|
||||
- nova-cloud-controller:cinder-volume-service
|
||||
- - cinder:shared-db
|
||||
- mysql:shared-db
|
||||
- - placement
|
||||
- mysql
|
||||
- - placement
|
||||
- keystone
|
||||
- - placement
|
||||
- nova-cloud-controller
|
||||
- - ceph-mon:client
|
||||
- nova-ironic:ceph
|
||||
- - ceph-mon:client
|
||||
- glance:ceph
|
||||
- - ceph-radosgw:mon
|
||||
- ceph-mon:radosgw
|
||||
- - ceph-radosgw:identity-service
|
||||
- keystone:identity-service
|
||||
- - ceph-osd:mon
|
||||
- ceph-mon:osd
|
||||
- - ceph-radosgw:object-store
|
||||
- glance
|
||||
- - vault:shared-db
|
||||
- mysql:shared-db
|
||||
- - vault:certificates
|
||||
- ceph-radosgw
|
||||
- - vault:certificates
|
||||
- cinder
|
||||
- - vault:certificates
|
||||
- glance:certificates
|
||||
- - vault:certificates
|
||||
- keystone:certificates
|
||||
- - vault:certificates
|
||||
- neutron-api:certificates
|
||||
- - vault:certificates
|
||||
- nova-cloud-controller:certificates
|
||||
- - vault:certificates
|
||||
- placement:certificates
|
||||
- - vault
|
||||
- ironic-conductor
|
||||
- - vault:certificates
|
||||
- ironic-api:certificates
|
||||
- - ironic-api
|
||||
- hacluster-ironic
|
||||
services:
|
||||
cinder:
|
||||
charm: cs:~openstack-charmers-next/cinder
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
block-device: vdb
|
||||
glance-api-version: 2
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
storage:
|
||||
block-devices: cinder,50G
|
||||
ceph-radosgw:
|
||||
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
namespace-tenants: True
|
||||
ceph-mon:
|
||||
charm: cs:ceph-mon
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
expected-osd-count: 3
|
||||
source: *source
|
||||
ceph-osd:
|
||||
charm: cs:ceph-osd
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
storage:
|
||||
osd-devices: 'cinder,30G'
|
||||
glance:
|
||||
charm: cs:~openstack-charmers-next/glance
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
keystone:
|
||||
charm: cs:~openstack-charmers-next/keystone
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
mysql:
|
||||
charm: cs:percona-cluster
|
||||
num_units: 1
|
||||
constraints: mem=4G
|
||||
options:
|
||||
innodb-buffer-pool-size: 256M
|
||||
max-connections: 1000
|
||||
performance-schema: true
|
||||
hacluster-ironic:
|
||||
charm: cs:~openstack-charmers-next/hacluster
|
||||
num_units: 0
|
||||
neutron-api:
|
||||
charm: cs:~openstack-charmers-next/neutron-api
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
flat-network-providers: "physnet1"
|
||||
neutron-security-groups: true
|
||||
openstack-origin: *source
|
||||
manage-neutron-plugin-legacy-mode: false
|
||||
worker-multiplier: 0.25
|
||||
neutron-gateway:
|
||||
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
enable-isolated-metadata: true
|
||||
enable-metadata-network: true
|
||||
bridge-mappings: physnet1:br-ex
|
||||
nova-cloud-controller:
|
||||
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
network-manager: Neutron
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
nova-ironic:
|
||||
charm: cs:~openstack-charmers-next/nova-compute
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
enable-live-migration: false
|
||||
enable-resize: false
|
||||
openstack-origin: *source
|
||||
virt-type: ironic
|
||||
placement:
|
||||
charm: cs:placement
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
rabbitmq-server:
|
||||
charm: cs:rabbitmq-server
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
ironic-api:
|
||||
charm: cs:~openstack-charmers-next/ironic-api
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
ironic-conductor:
|
||||
charm: ../../../ironic-conductor
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
max-tftp-block-size: 1418
|
||||
disable-secure-erase: true
|
||||
use-ipxe: true
|
||||
enabled-network-interfaces: "flat, noop"
|
||||
neutron-openvswitch:
|
||||
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||
num_units: 0
|
||||
options:
|
||||
bridge-mappings: physnet1:br-ex
|
||||
neutron-ironic-agent:
|
||||
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||
num_units: 0
|
||||
options:
|
||||
openstack-origin: *source
|
||||
vault:
|
||||
charm: cs:~openstack-charmers-next/vault
|
||||
num_units: 1
|
284
src/tests/bundles/focal-ussuri.yaml
Normal file
284
src/tests/bundles/focal-ussuri.yaml
Normal file
@ -0,0 +1,284 @@
|
||||
options:
|
||||
source: &source distro
|
||||
series: focal
|
||||
local_overlay_enabled: false
|
||||
relations:
|
||||
- - nova-ironic
|
||||
- ironic-api
|
||||
- - ironic-conductor
|
||||
- ironic-api
|
||||
- - neutron-ironic-agent:identity-credentials
|
||||
- keystone
|
||||
- - neutron-ironic-agent
|
||||
- neutron-api
|
||||
- - neutron-openvswitch
|
||||
- neutron-api
|
||||
- - ironic-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-api
|
||||
- keystone
|
||||
- - ironic-api:shared-db
|
||||
- ironic-api-mysql-router:shared-db
|
||||
- - ironic-conductor:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-conductor
|
||||
- keystone
|
||||
- - ironic-conductor:shared-db
|
||||
- ironic-conductor-mysql-router:shared-db
|
||||
- - nova-ironic:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-ironic
|
||||
- glance
|
||||
- - nova-ironic
|
||||
- keystone
|
||||
- - nova-ironic
|
||||
- nova-cloud-controller
|
||||
- - neutron-gateway:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - keystone:shared-db
|
||||
- keystone-mysql-router:shared-db
|
||||
- - nova-cloud-controller:identity-service
|
||||
- keystone:identity-service
|
||||
- - glance:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:shared-db
|
||||
- neutron-api-mysql-router:shared-db
|
||||
- - neutron-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - neutron-gateway:neutron-plugin-api
|
||||
- neutron-api:neutron-plugin-api
|
||||
- - glance:shared-db
|
||||
- glance-mysql-router:shared-db
|
||||
- - glance:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:image-service
|
||||
- glance:image-service
|
||||
- - nova-cloud-controller:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:quantum-network-service
|
||||
- neutron-gateway:quantum-network-service
|
||||
- - nova-cloud-controller:shared-db
|
||||
- nova-cloud-controller-mysql-router:shared-db
|
||||
- - nova-cloud-controller:neutron-api
|
||||
- neutron-api:neutron-api
|
||||
- - cinder:image-service
|
||||
- glance:image-service
|
||||
- - cinder:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - cinder:identity-service
|
||||
- keystone:identity-service
|
||||
- - cinder:cinder-volume-service
|
||||
- nova-cloud-controller:cinder-volume-service
|
||||
- - cinder:shared-db
|
||||
- cinder-mysql-router:shared-db
|
||||
- - placement:shared-db
|
||||
- placement-mysql-router:shared-db
|
||||
- - placement
|
||||
- keystone
|
||||
- - placement
|
||||
- nova-cloud-controller
|
||||
- - ceph-mon:client
|
||||
- nova-ironic:ceph
|
||||
- - ceph-mon:client
|
||||
- glance:ceph
|
||||
- - ceph-radosgw:mon
|
||||
- ceph-mon:radosgw
|
||||
- - ceph-radosgw:identity-service
|
||||
- keystone:identity-service
|
||||
- - ceph-osd:mon
|
||||
- ceph-mon:osd
|
||||
- - ceph-radosgw:object-store
|
||||
- glance
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- nova-cloud-controller-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- keystone-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- glance-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- neutron-api-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- placement-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- cinder-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- ironic-api-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- ironic-conductor-mysql-router:db-router
|
||||
- - vault-mysql-router:db-router
|
||||
- mysql-innodb-cluster:db-router
|
||||
- - vault:shared-db
|
||||
- vault-mysql-router:shared-db
|
||||
- - vault:certificates
|
||||
- ceph-radosgw
|
||||
- - vault:certificates
|
||||
- cinder
|
||||
- - vault:certificates
|
||||
- glance:certificates
|
||||
- - vault:certificates
|
||||
- keystone:certificates
|
||||
- - vault:certificates
|
||||
- neutron-api:certificates
|
||||
- - vault:certificates
|
||||
- nova-cloud-controller:certificates
|
||||
- - vault:certificates
|
||||
- placement:certificates
|
||||
- - vault
|
||||
- ironic-conductor
|
||||
- - vault:certificates
|
||||
- ironic-api:certificates
|
||||
- - ironic-api
|
||||
- hacluster-ironic
|
||||
services:
|
||||
nova-cloud-controller-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
keystone-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
glance-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
neutron-api-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
placement-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
vault-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
cinder-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
ironic-api-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
ironic-conductor-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
mysql-innodb-cluster:
|
||||
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||
num_units: 3
|
||||
constraints: mem=4G
|
||||
options:
|
||||
source: *source
|
||||
cinder:
|
||||
charm: cs:~openstack-charmers-next/cinder
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
block-device: vdb
|
||||
glance-api-version: 2
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
storage:
|
||||
block-devices: cinder,50G
|
||||
ceph-radosgw:
|
||||
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
namespace-tenants: True
|
||||
ceph-mon:
|
||||
charm: cs:ceph-mon
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
expected-osd-count: 3
|
||||
source: *source
|
||||
ceph-osd:
|
||||
charm: cs:ceph-osd
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
storage:
|
||||
osd-devices: 'cinder,30G'
|
||||
glance:
|
||||
charm: cs:~openstack-charmers-next/glance
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
keystone:
|
||||
charm: cs:~openstack-charmers-next/keystone
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
neutron-api:
|
||||
charm: cs:~openstack-charmers-next/neutron-api
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
flat-network-providers: "physnet1"
|
||||
neutron-security-groups: true
|
||||
openstack-origin: *source
|
||||
manage-neutron-plugin-legacy-mode: false
|
||||
worker-multiplier: 0.25
|
||||
neutron-gateway:
|
||||
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
enable-isolated-metadata: true
|
||||
enable-metadata-network: true
|
||||
bridge-mappings: physnet1:br-ex
|
||||
nova-cloud-controller:
|
||||
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
network-manager: Neutron
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
nova-ironic:
|
||||
charm: cs:~openstack-charmers-next/nova-compute
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
enable-live-migration: false
|
||||
enable-resize: false
|
||||
openstack-origin: *source
|
||||
virt-type: ironic
|
||||
placement:
|
||||
charm: cs:placement
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
rabbitmq-server:
|
||||
charm: cs:rabbitmq-server
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
hacluster-ironic:
|
||||
charm: cs:~openstack-charmers-next/hacluster
|
||||
num_units: 0
|
||||
ironic-api:
|
||||
charm: cs:~openstack-charmers-next/ironic-api
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
ironic-conductor:
|
||||
charm: ../../../ironic-conductor
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
max-tftp-block-size: 1418
|
||||
disable-secure-erase: true
|
||||
use-ipxe: true
|
||||
enabled-network-interfaces: "flat, noop"
|
||||
neutron-openvswitch:
|
||||
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||
num_units: 0
|
||||
options:
|
||||
bridge-mappings: physnet1:br-ex
|
||||
neutron-ironic-agent:
|
||||
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||
num_units: 0
|
||||
options:
|
||||
openstack-origin: *source
|
||||
vault:
|
||||
charm: cs:~openstack-charmers-next/vault
|
||||
num_units: 1
|
284
src/tests/bundles/focal-victoria.yaml
Normal file
284
src/tests/bundles/focal-victoria.yaml
Normal file
@ -0,0 +1,284 @@
|
||||
options:
|
||||
source: &source cloud:focal-victoria/proposed
|
||||
series: focal
|
||||
local_overlay_enabled: false
|
||||
relations:
|
||||
- - nova-ironic
|
||||
- ironic-api
|
||||
- - ironic-conductor
|
||||
- ironic-api
|
||||
- - neutron-ironic-agent:identity-credentials
|
||||
- keystone
|
||||
- - neutron-ironic-agent
|
||||
- neutron-api
|
||||
- - neutron-openvswitch
|
||||
- neutron-api
|
||||
- - ironic-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-api
|
||||
- keystone
|
||||
- - ironic-api:shared-db
|
||||
- ironic-api-mysql-router:shared-db
|
||||
- - ironic-conductor:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - ironic-conductor
|
||||
- keystone
|
||||
- - ironic-conductor:shared-db
|
||||
- ironic-conductor-mysql-router:shared-db
|
||||
- - nova-ironic:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-ironic
|
||||
- glance
|
||||
- - nova-ironic
|
||||
- keystone
|
||||
- - nova-ironic
|
||||
- nova-cloud-controller
|
||||
- - neutron-gateway:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - keystone:shared-db
|
||||
- keystone-mysql-router:shared-db
|
||||
- - nova-cloud-controller:identity-service
|
||||
- keystone:identity-service
|
||||
- - glance:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:identity-service
|
||||
- keystone:identity-service
|
||||
- - neutron-api:shared-db
|
||||
- neutron-api-mysql-router:shared-db
|
||||
- - neutron-api:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - neutron-gateway:neutron-plugin-api
|
||||
- neutron-api:neutron-plugin-api
|
||||
- - glance:shared-db
|
||||
- glance-mysql-router:shared-db
|
||||
- - glance:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:image-service
|
||||
- glance:image-service
|
||||
- - nova-cloud-controller:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - nova-cloud-controller:quantum-network-service
|
||||
- neutron-gateway:quantum-network-service
|
||||
- - nova-cloud-controller:shared-db
|
||||
- nova-cloud-controller-mysql-router:shared-db
|
||||
- - nova-cloud-controller:neutron-api
|
||||
- neutron-api:neutron-api
|
||||
- - cinder:image-service
|
||||
- glance:image-service
|
||||
- - cinder:amqp
|
||||
- rabbitmq-server:amqp
|
||||
- - cinder:identity-service
|
||||
- keystone:identity-service
|
||||
- - cinder:cinder-volume-service
|
||||
- nova-cloud-controller:cinder-volume-service
|
||||
- - cinder:shared-db
|
||||
- cinder-mysql-router:shared-db
|
||||
- - placement:shared-db
|
||||
- placement-mysql-router:shared-db
|
||||
- - placement
|
||||
- keystone
|
||||
- - placement
|
||||
- nova-cloud-controller
|
||||
- - ceph-mon:client
|
||||
- nova-ironic:ceph
|
||||
- - ceph-mon:client
|
||||
- glance:ceph
|
||||
- - ceph-radosgw:mon
|
||||
- ceph-mon:radosgw
|
||||
- - ceph-radosgw:identity-service
|
||||
- keystone:identity-service
|
||||
- - ceph-osd:mon
|
||||
- ceph-mon:osd
|
||||
- - ceph-radosgw:object-store
|
||||
- glance
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- nova-cloud-controller-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- keystone-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- glance-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- neutron-api-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- placement-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- cinder-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- ironic-api-mysql-router:db-router
|
||||
- - mysql-innodb-cluster:db-router
|
||||
- ironic-conductor-mysql-router:db-router
|
||||
- - vault-mysql-router:db-router
|
||||
- mysql-innodb-cluster:db-router
|
||||
- - vault:shared-db
|
||||
- vault-mysql-router:shared-db
|
||||
- - vault:certificates
|
||||
- ceph-radosgw
|
||||
- - vault:certificates
|
||||
- cinder
|
||||
- - vault:certificates
|
||||
- glance:certificates
|
||||
- - vault:certificates
|
||||
- keystone:certificates
|
||||
- - vault:certificates
|
||||
- neutron-api:certificates
|
||||
- - vault:certificates
|
||||
- nova-cloud-controller:certificates
|
||||
- - vault:certificates
|
||||
- placement:certificates
|
||||
- - vault
|
||||
- ironic-conductor
|
||||
- - vault:certificates
|
||||
- ironic-api:certificates
|
||||
- - ironic-api
|
||||
- hacluster-ironic
|
||||
services:
|
||||
nova-cloud-controller-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
keystone-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
glance-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
neutron-api-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
placement-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
vault-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
cinder-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
ironic-api-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
ironic-conductor-mysql-router:
|
||||
charm: cs:~openstack-charmers-next/mysql-router
|
||||
mysql-innodb-cluster:
|
||||
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||
num_units: 3
|
||||
constraints: mem=4G
|
||||
options:
|
||||
source: *source
|
||||
cinder:
|
||||
charm: cs:~openstack-charmers-next/cinder
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
block-device: vdb
|
||||
glance-api-version: 2
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
storage:
|
||||
block-devices: cinder,50G
|
||||
ceph-radosgw:
|
||||
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
namespace-tenants: True
|
||||
ceph-mon:
|
||||
charm: cs:ceph-mon
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
expected-osd-count: 3
|
||||
source: *source
|
||||
ceph-osd:
|
||||
charm: cs:ceph-osd
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
source: *source
|
||||
storage:
|
||||
osd-devices: 'cinder,30G'
|
||||
glance:
|
||||
charm: cs:~openstack-charmers-next/glance
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
keystone:
|
||||
charm: cs:~openstack-charmers-next/keystone
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
neutron-api:
|
||||
charm: cs:~openstack-charmers-next/neutron-api
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
flat-network-providers: "physnet1"
|
||||
neutron-security-groups: true
|
||||
openstack-origin: *source
|
||||
manage-neutron-plugin-legacy-mode: false
|
||||
worker-multiplier: 0.25
|
||||
neutron-gateway:
|
||||
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
enable-isolated-metadata: true
|
||||
enable-metadata-network: true
|
||||
bridge-mappings: physnet1:br-ex
|
||||
nova-cloud-controller:
|
||||
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
network-manager: Neutron
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
nova-ironic:
|
||||
charm: cs:~openstack-charmers-next/nova-compute
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
enable-live-migration: false
|
||||
enable-resize: false
|
||||
openstack-origin: *source
|
||||
virt-type: ironic
|
||||
placement:
|
||||
charm: cs:placement
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
worker-multiplier: 0.25
|
||||
rabbitmq-server:
|
||||
charm: cs:rabbitmq-server
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
hacluster-ironic:
|
||||
charm: cs:~openstack-charmers-next/hacluster
|
||||
num_units: 0
|
||||
ironic-api:
|
||||
charm: cs:~openstack-charmers-next/ironic-api
|
||||
num_units: 3
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
ironic-conductor:
|
||||
charm: ../../../ironic-conductor
|
||||
num_units: 1
|
||||
constraints: mem=2G
|
||||
options:
|
||||
openstack-origin: *source
|
||||
max-tftp-block-size: 1418
|
||||
disable-secure-erase: true
|
||||
use-ipxe: true
|
||||
enabled-network-interfaces: "flat, noop"
|
||||
neutron-openvswitch:
|
||||
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||
num_units: 0
|
||||
options:
|
||||
bridge-mappings: physnet1:br-ex
|
||||
neutron-ironic-agent:
|
||||
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||
num_units: 0
|
||||
options:
|
||||
openstack-origin: *source
|
||||
vault:
|
||||
charm: cs:~openstack-charmers-next/vault
|
||||
num_units: 1
|
1
src/tests/bundles/overlays/bionic-train.yaml.j2
Symbolic link
1
src/tests/bundles/overlays/bionic-train.yaml.j2
Symbolic link
@ -0,0 +1 @@
|
||||
ironic.j2
|
1
src/tests/bundles/overlays/bionic-ussuri.yaml.j2
Symbolic link
1
src/tests/bundles/overlays/bionic-ussuri.yaml.j2
Symbolic link
@ -0,0 +1 @@
|
||||
ironic.j2
|
1
src/tests/bundles/overlays/focal-ussuri.yaml.j2
Symbolic link
1
src/tests/bundles/overlays/focal-ussuri.yaml.j2
Symbolic link
@ -0,0 +1 @@
|
||||
ironic.j2
|
1
src/tests/bundles/overlays/focal-victoria.yaml.j2
Symbolic link
1
src/tests/bundles/overlays/focal-victoria.yaml.j2
Symbolic link
@ -0,0 +1 @@
|
||||
ironic.j2
|
4
src/tests/bundles/overlays/ironic.j2
Normal file
4
src/tests/bundles/overlays/ironic.j2
Normal file
@ -0,0 +1,4 @@
|
||||
applications:
|
||||
ironic-api:
|
||||
options:
|
||||
vip: '{{ OS_VIP00 }}'
|
29
src/tests/tests.yaml
Normal file
29
src/tests/tests.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
charm_name: ironic-api
|
||||
gate_bundles:
|
||||
- focal-ussuri
|
||||
- bionic-train
|
||||
- bionic-ussuri
|
||||
smoke_bundles:
|
||||
- bionic-ussuri
|
||||
dev_bundles:
|
||||
- focal-victoria
|
||||
target_deploy_status:
|
||||
vault:
|
||||
workload-status: blocked
|
||||
workload-status-message: Vault needs to be initialized
|
||||
ironic-conductor:
|
||||
workload-status: blocked
|
||||
workload-status-message: invalid enabled-deploy-interfaces config
|
||||
configure:
|
||||
- zaza.openstack.charm_tests.vault.setup.auto_initialize
|
||||
- zaza.openstack.charm_tests.ironic.setup.set_temp_url_secret
|
||||
- zaza.openstack.charm_tests.ironic.setup.add_ironic_deployment_image
|
||||
- zaza.openstack.charm_tests.ironic.setup.add_ironic_os_image
|
||||
- zaza.openstack.charm_tests.ironic.setup.create_bm_flavors
|
||||
# Ironic will require a flat network to test the flat network type. Once a proper
|
||||
# testing environment will be available for Ironic, we will need to add the setup
|
||||
# call to create that flat network
|
||||
#- zaza.openstack.charm_tests.neutron.setup.basic_overcloud_network
|
||||
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
|
||||
tests:
|
||||
- zaza.openstack.charm_tests.ironic.tests.IronicTest
|
@ -7,3 +7,4 @@ python-glanceclient
|
||||
python-swiftclient
|
||||
python-keystoneclient
|
||||
zipp < 2.0.0
|
||||
importlib-metadata>=2.0
|
||||
|
@ -45,3 +45,15 @@ sys.modules['charms.reactive.bus'] = charms.reactive.bus
|
||||
sys.modules['charms.reactive.bus'] = charms.reactive.decorators
|
||||
sys.modules['charms.reactive.flags'] = charms.reactive.flags
|
||||
sys.modules['charms.reactive.relations'] = charms.reactive.relations
|
||||
|
||||
keystoneauth1 = mock.MagicMock()
|
||||
sys.modules['keystoneauth1'] = keystoneauth1
|
||||
|
||||
glanceclient = mock.MagicMock()
|
||||
sys.modules['glanceclient'] = glanceclient
|
||||
|
||||
swiftclient = mock.MagicMock()
|
||||
sys.modules['swiftclient'] = swiftclient
|
||||
|
||||
keystoneclient = mock.MagicMock()
|
||||
sys.modules['keystoneclient'] = keystoneclient
|
||||
|
@ -20,6 +20,10 @@ from keystoneauth1 import exceptions as ks_exc
|
||||
import charm.openstack.ironic.api_utils as api_utils
|
||||
|
||||
|
||||
class _NotFoundException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||
|
||||
def setUp(self):
|
||||
@ -54,7 +58,8 @@ class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||
|
||||
self.loading.get_plugin_loader.assert_called_with("v3password")
|
||||
loader.load_from_options.assert_called_with(**self.ks_expect)
|
||||
self.ks_session.Session.assert_called_with(auth=auth, verify=True)
|
||||
self.ks_session.Session.assert_called_with(
|
||||
auth=auth, verify=api_utils.SYSTEM_CA_BUNDLE)
|
||||
|
||||
def test_create_keystone_session_v2(self):
|
||||
self.patch_object(api_utils, 'loading')
|
||||
@ -70,7 +75,8 @@ class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||
|
||||
self.loading.get_plugin_loader.assert_called_with("password")
|
||||
loader.load_from_options.assert_called_with(**self.ks_expect)
|
||||
self.ks_session.Session.assert_called_with(auth=auth, verify=True)
|
||||
self.ks_session.Session.assert_called_with(
|
||||
auth=auth, verify=api_utils.SYSTEM_CA_BUNDLE)
|
||||
|
||||
|
||||
class TestOSClients(test_utils.PatchHelper):
|
||||
@ -108,7 +114,8 @@ class TestOSClients(test_utils.PatchHelper):
|
||||
|
||||
self.target = api_utils.OSClients(self.session)
|
||||
self.glance_client.assert_called_with(session=self.session, version=2)
|
||||
self.swift_con.assert_called_with(session=self.session, cacert=None)
|
||||
self.swift_con.assert_called_with(
|
||||
session=self.session, cacert=api_utils.SYSTEM_CA_BUNDLE)
|
||||
self.ks_client.assert_called_with(session=self.session)
|
||||
|
||||
def test_stores_info(self):
|
||||
@ -173,6 +180,7 @@ class TestOSClients(test_utils.PatchHelper):
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_does_not_have_service_type(self):
|
||||
ks_exc.http.NotFound = _NotFoundException
|
||||
self.ks_client.services.find.side_effect = ks_exc.http.NotFound()
|
||||
self.target._ks = self.ks_client
|
||||
|
||||
|
@ -24,16 +24,6 @@ import charm.openstack.ironic.controller_utils as controller_utils
|
||||
|
||||
class TestGetPXEBootClass(test_utils.PatchHelper):
|
||||
|
||||
def test_get_pxe_config_class_bionic(self):
|
||||
self.patch_object(
|
||||
ch_host, 'get_distrib_codename')
|
||||
self.get_distrib_codename.return_value = "bionic"
|
||||
charm_config = {}
|
||||
pxe_class = controller_utils.get_pxe_config_class(charm_config)
|
||||
self.assertTrue(
|
||||
isinstance(
|
||||
pxe_class, controller_utils.PXEBootBionic))
|
||||
|
||||
def test_get_pxe_config_class(self):
|
||||
self.patch_object(
|
||||
ch_host, 'get_distrib_codename')
|
||||
|
@ -19,6 +19,8 @@ import charms.leadership as leadership
|
||||
import charmhelpers.core.hookenv as hookenv
|
||||
import charms.reactive as reactive
|
||||
|
||||
from charmhelpers.contrib.openstack.utils import os_release
|
||||
|
||||
from charm.openstack.ironic import ironic
|
||||
from charm.openstack.ironic import controller_utils as ctrl_util
|
||||
|
||||
@ -70,6 +72,118 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
|
||||
self.get_pxe_config_class.return_value = self.mocked_pxe_cfg
|
||||
|
||||
def test_setup_power_adapter_config_train(self):
|
||||
os_release.return_value = "train"
|
||||
cfg_data = {
|
||||
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||
}
|
||||
|
||||
hookenv.config.return_value = cfg_data
|
||||
|
||||
target = ironic.IronicConductorCharm()
|
||||
target._setup_power_adapter_config()
|
||||
expected = {
|
||||
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||
"ipmitool, redfish, noop"),
|
||||
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||
"ipmitool-socat, no-console"),
|
||||
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||
"enabled_boot_interfaces": "pxe",
|
||||
"enabled_bios_interfaces": "no-bios"
|
||||
}
|
||||
self.assertEqual(
|
||||
target.config["hardware_type_cfg"],
|
||||
expected)
|
||||
|
||||
def test_setup_power_adapter_config_train_ipxe(self):
|
||||
os_release.return_value = "train"
|
||||
cfg_data = {
|
||||
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||
"use-ipxe": True,
|
||||
}
|
||||
|
||||
hookenv.config.return_value = cfg_data
|
||||
|
||||
target = ironic.IronicConductorCharm()
|
||||
target._setup_power_adapter_config()
|
||||
expected = {
|
||||
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||
"ipmitool, redfish, noop"),
|
||||
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||
"ipmitool-socat, no-console"),
|
||||
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||
"enabled_boot_interfaces": "pxe, ipxe",
|
||||
"enabled_bios_interfaces": "no-bios"
|
||||
}
|
||||
|
||||
self.assertEqual(
|
||||
target.config["hardware_type_cfg"],
|
||||
expected)
|
||||
|
||||
def test_setup_power_adapter_config_unknown(self):
|
||||
# test that it defaults to latest, in this case ussuri
|
||||
os_release.return_value = "unknown"
|
||||
cfg_data = {
|
||||
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||
}
|
||||
|
||||
hookenv.config.return_value = cfg_data
|
||||
|
||||
target = ironic.IronicConductorCharm()
|
||||
target._setup_power_adapter_config()
|
||||
expected = {
|
||||
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||
"ipmitool, redfish, noop"),
|
||||
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||
"ipmitool-socat, no-console"),
|
||||
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||
"enabled_boot_interfaces": "pxe, redfish-virtual-media",
|
||||
"enabled_bios_interfaces": "idrac-wsman, no-bios"
|
||||
}
|
||||
self.assertEqual(
|
||||
target.config["hardware_type_cfg"],
|
||||
expected)
|
||||
|
||||
def test_setup_power_adapter_config_ussuri(self):
|
||||
os_release.return_value = "ussuri"
|
||||
cfg_data = {
|
||||
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||
}
|
||||
|
||||
hookenv.config.return_value = cfg_data
|
||||
|
||||
target = ironic.IronicConductorCharm()
|
||||
target._setup_power_adapter_config()
|
||||
self.maxDiff = None
|
||||
expected = {
|
||||
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||
"ipmitool, redfish, noop"),
|
||||
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||
"ipmitool-socat, no-console"),
|
||||
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||
"enabled_boot_interfaces": "pxe, redfish-virtual-media",
|
||||
"enabled_bios_interfaces": "idrac-wsman, no-bios"
|
||||
}
|
||||
self.assertEqual(
|
||||
target.config["hardware_type_cfg"],
|
||||
expected)
|
||||
|
||||
def test_get_amqp_credentials(self):
|
||||
cfg_data = {
|
||||
"rabbit-user": "ironic",
|
||||
@ -159,11 +273,24 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target = ironic.IronicConductorCharm()
|
||||
target._setup_pxe_config(self.mocked_pxe_cfg)
|
||||
expected_pkgs = ironic.PACKAGES + ["fakepkg1", "fakepkg2"]
|
||||
|
||||
expected_cfg = {
|
||||
'tftpboot': ctrl_util.PXEBootBase.TFTP_ROOT,
|
||||
'httpboot': ctrl_util.PXEBootBase.HTTP_ROOT,
|
||||
'ironic_user': ctrl_util.PXEBootBase.IRONIC_USER,
|
||||
'ironic_group': ctrl_util.PXEBootBase.IRONIC_GROUP,
|
||||
'hardware_type_cfg': {
|
||||
'enabled_hardware_types': 'intel-ipmi, ipmi',
|
||||
'enabled_management_interfaces': ('intel-ipmitool, ipmitool,'
|
||||
' noop'),
|
||||
'enabled_inspect_interfaces': 'no-inspect',
|
||||
'enabled_power_interfaces': 'ipmitool',
|
||||
'enabled_console_interfaces': ('ipmitool-shellinabox, '
|
||||
'ipmitool-socat, no-console'),
|
||||
'enabled_raid_interfaces': 'no-raid',
|
||||
'enabled_vendor_interfaces': 'ipmitool, no-vendor',
|
||||
'enabled_boot_interfaces': 'pxe',
|
||||
'enabled_bios_interfaces': 'no-bios'},
|
||||
'default-network-interface': 'fake_net',
|
||||
'default-deploy-interface': 'fake_deploy'}
|
||||
|
||||
@ -188,7 +315,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target._validate_deploy_interfaces(["bogus"])
|
||||
|
||||
expected_msg = (
|
||||
'Deploy interface "bogus" is not valid.'
|
||||
'Deploy interface bogus is not valid.'
|
||||
' Valid interfaces are: direct, iscsi')
|
||||
|
||||
self.assertIsNone(
|
||||
@ -204,8 +331,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
with self.assertRaises(ValueError) as err:
|
||||
target._validate_deploy_interfaces(["direct"])
|
||||
expected_msg = (
|
||||
'run "set-temp-url-secret" action on '
|
||||
'leader to enable "direct" deploy method')
|
||||
'run set-temp-url-secret action on '
|
||||
'leader to enable direct deploy method')
|
||||
self.assertEqual(str(err.exception), expected_msg)
|
||||
|
||||
def test_validate_default_net_interface(self):
|
||||
@ -266,8 +393,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target = ironic.IronicConductorCharm()
|
||||
expected_status = (
|
||||
'blocked',
|
||||
'invalid enabled-network-interfaces config: Network interface '
|
||||
'"bogus" is not valid. Valid interfaces are: neutron, flat, noop'
|
||||
'invalid enabled-network-interfaces config, Network interface '
|
||||
'bogus is not valid. Valid interfaces are: neutron, flat, noop'
|
||||
)
|
||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||
|
||||
@ -280,8 +407,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target = ironic.IronicConductorCharm()
|
||||
expected_status = (
|
||||
'blocked',
|
||||
'invalid enabled-deploy-interfaces config: Deploy interface '
|
||||
'"bogus" is not valid. Valid interfaces are: direct, iscsi'
|
||||
'invalid enabled-deploy-interfaces config, Deploy interface '
|
||||
'bogus is not valid. Valid interfaces are: direct, iscsi'
|
||||
)
|
||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||
|
||||
@ -294,7 +421,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target = ironic.IronicConductorCharm()
|
||||
expected_status = (
|
||||
'blocked',
|
||||
'invalid default-network-interface config: '
|
||||
'invalid default-network-interface config, '
|
||||
'default-network-interface (bogus) is not enabled '
|
||||
'in enabled-network-interfaces: neutron, flat, noop'
|
||||
)
|
||||
@ -309,7 +436,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||
target = ironic.IronicConductorCharm()
|
||||
expected_status = (
|
||||
'blocked',
|
||||
'invalid default-deploy-interface config: default-deploy-interface'
|
||||
'invalid default-deploy-interface config, default-deploy-interface'
|
||||
' (bogus) is not enabled in enabled-deploy-interfaces: direct, '
|
||||
'iscsi')
|
||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||
|
Loading…
Reference in New Issue
Block a user