
When deploying on IPv6 stateful ironic must use the neutron network interface driver. This because we need to configure neutron service ports (provisioning, cleaning etc.) with multiple ip addresses for certain UEFI firmware and chainloading combinations (iPXE -> Ironic IPA) to work. Closes-Bug: #1864491 Change-Id: I5a9890ccb95a21b95f488cd7a5b5fd1a6cdff38b
1097 lines
50 KiB
Python
1097 lines
50 KiB
Python
# Copyright 2017 Red Hat, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives import serialization
|
|
from cryptography import x509
|
|
from cryptography.x509.oid import NameOID
|
|
from datetime import datetime
|
|
from datetime import timedelta
|
|
import fixtures
|
|
import mock
|
|
import os
|
|
import tempfile
|
|
import yaml
|
|
|
|
from oslo_config import cfg
|
|
from oslo_config import fixture as oslo_fixture
|
|
|
|
from tripleo_common.image import kolla_builder
|
|
|
|
from tripleoclient import exceptions
|
|
from tripleoclient.tests import base
|
|
from tripleoclient.v1 import undercloud_config
|
|
|
|
|
|
class TestProcessDriversAndHardwareTypes(base.TestCase):
|
|
def setUp(self):
|
|
super(TestProcessDriversAndHardwareTypes, self).setUp()
|
|
self.conf = mock.Mock(**{key: getattr(undercloud_config.CONF, key)
|
|
for key in (
|
|
'enabled_hardware_types',
|
|
'enable_node_discovery',
|
|
'discovery_default_driver',
|
|
'ironic_enabled_network_interfaces',
|
|
'ironic_default_network_interface')})
|
|
|
|
def test_defaults(self):
|
|
env = {}
|
|
undercloud_config._process_drivers_and_hardware_types(self.conf, env)
|
|
self.assertEqual({
|
|
'IronicEnabledNetworkInterfaces': ['flat'],
|
|
'IronicDefaultNetworkInterface': 'flat',
|
|
'IronicEnabledHardwareTypes': ['idrac', 'ilo', 'ipmi', 'redfish'],
|
|
'IronicEnabledBootInterfaces': ['ilo-pxe', 'ipxe', 'pxe'],
|
|
'IronicEnabledBiosInterfaces': ['ilo', 'no-bios', 'redfish'],
|
|
'IronicEnabledDeployInterfaces': ['ansible', 'direct', 'iscsi'],
|
|
'IronicEnabledInspectInterfaces': ['idrac', 'ilo', 'inspector',
|
|
'no-inspect', 'redfish'],
|
|
'IronicEnabledManagementInterfaces': ['fake', 'idrac', 'ilo',
|
|
'ipmitool', 'noop',
|
|
'redfish'],
|
|
'IronicEnabledPowerInterfaces': ['fake', 'idrac', 'ilo',
|
|
'ipmitool', 'redfish'],
|
|
'IronicEnabledRaidInterfaces': ['idrac', 'no-raid'],
|
|
'IronicEnabledVendorInterfaces': ['idrac', 'ipmitool', 'no-vendor']
|
|
}, env)
|
|
|
|
def test_one_hardware_type_with_discovery(self):
|
|
env = {}
|
|
self.conf.enabled_hardware_types = ['redfish']
|
|
self.conf.enable_node_discovery = True
|
|
|
|
undercloud_config._process_drivers_and_hardware_types(self.conf, env)
|
|
self.assertEqual({
|
|
'IronicEnabledNetworkInterfaces': ['flat'],
|
|
'IronicDefaultNetworkInterface': 'flat',
|
|
# ipmi added because it's the default discovery driver
|
|
'IronicEnabledHardwareTypes': ['ipmi', 'redfish'],
|
|
'IronicEnabledBootInterfaces': ['ipxe', 'pxe'],
|
|
'IronicEnabledBiosInterfaces': ['no-bios', 'redfish'],
|
|
'IronicEnabledDeployInterfaces': ['ansible', 'direct', 'iscsi'],
|
|
'IronicEnabledInspectInterfaces': ['inspector', 'no-inspect',
|
|
'redfish'],
|
|
'IronicEnabledManagementInterfaces': ['fake', 'ipmitool',
|
|
'noop', 'redfish'],
|
|
'IronicEnabledPowerInterfaces': ['fake', 'ipmitool', 'redfish'],
|
|
'IronicEnabledRaidInterfaces': ['no-raid'],
|
|
'IronicEnabledVendorInterfaces': ['ipmitool', 'no-vendor'],
|
|
'IronicInspectorDiscoveryDefaultDriver': 'ipmi',
|
|
'IronicInspectorEnableNodeDiscovery': True
|
|
}, env)
|
|
|
|
def test_all_hardware_types(self):
|
|
env = {}
|
|
self.conf.enabled_hardware_types = (
|
|
self.conf.enabled_hardware_types + ['staging-ovirt', 'snmp',
|
|
'irmc', 'xclarity',
|
|
'fake-hardware']
|
|
)
|
|
|
|
undercloud_config._process_drivers_and_hardware_types(self.conf, env)
|
|
self.assertEqual({
|
|
'IronicEnabledNetworkInterfaces': ['flat'],
|
|
'IronicDefaultNetworkInterface': 'flat',
|
|
'IronicEnabledHardwareTypes': ['fake-hardware', 'idrac', 'ilo',
|
|
'ipmi', 'irmc', 'redfish', 'snmp',
|
|
'staging-ovirt', 'xclarity'],
|
|
'IronicEnabledBootInterfaces': ['fake', 'ilo-pxe', 'ipxe',
|
|
'irmc-pxe', 'pxe'],
|
|
'IronicEnabledBiosInterfaces': ['ilo', 'irmc',
|
|
'no-bios', 'redfish'],
|
|
'IronicEnabledDeployInterfaces': ['ansible', 'direct', 'fake',
|
|
'iscsi'],
|
|
'IronicEnabledInspectInterfaces': ['idrac', 'ilo', 'inspector',
|
|
'irmc', 'no-inspect',
|
|
'redfish'],
|
|
'IronicEnabledManagementInterfaces': ['fake', 'idrac',
|
|
'ilo', 'ipmitool', 'irmc',
|
|
'noop', 'redfish',
|
|
'staging-ovirt', 'xclarity'],
|
|
'IronicEnabledPowerInterfaces': ['fake', 'idrac',
|
|
'ilo', 'ipmitool', 'irmc',
|
|
'redfish', 'snmp',
|
|
'staging-ovirt', 'xclarity'],
|
|
'IronicEnabledRaidInterfaces': ['idrac', 'no-raid'],
|
|
'IronicEnabledVendorInterfaces': ['idrac', 'ipmitool', 'no-vendor']
|
|
}, env)
|
|
|
|
|
|
class TestBaseNetworkSettings(base.TestCase):
|
|
def setUp(self):
|
|
super(TestBaseNetworkSettings, self).setUp()
|
|
self.conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
|
|
# don't actually load config from ~/undercloud.conf
|
|
self.mock_config_load = self.useFixture(
|
|
fixtures.MockPatch('tripleoclient.utils.load_config'))
|
|
self.conf.config(local_ip='192.168.24.1/24',
|
|
undercloud_admin_host='192.168.24.3',
|
|
undercloud_public_host='192.168.24.2',
|
|
undercloud_nameservers=['10.10.10.10', '10.10.10.11'])
|
|
# ctlplane network - config group options
|
|
self.grp0 = cfg.OptGroup(name='ctlplane-subnet',
|
|
title='ctlplane-subnet')
|
|
self.opts = [cfg.StrOpt('cidr'),
|
|
cfg.ListOpt('dhcp_start'),
|
|
cfg.ListOpt('dhcp_end'),
|
|
cfg.ListOpt('dhcp_exclude'),
|
|
cfg.StrOpt('inspection_iprange'),
|
|
cfg.StrOpt('gateway'),
|
|
cfg.BoolOpt('masquerade'),
|
|
cfg.ListOpt('host_routes',
|
|
item_type=cfg.types.Dict(bounds=True),
|
|
bounds=True,),
|
|
cfg.ListOpt('dns_nameservers')]
|
|
self.conf.register_opts(self.opts, group=self.grp0)
|
|
self.grp1 = cfg.OptGroup(name='subnet1', title='subnet1')
|
|
self.grp2 = cfg.OptGroup(name='subnet2', title='subnet2')
|
|
self.conf.config(cidr='192.168.24.0/24',
|
|
dhcp_start='192.168.24.5',
|
|
dhcp_end='192.168.24.24',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.24.100,192.168.24.120',
|
|
gateway='192.168.24.1',
|
|
masquerade=False,
|
|
host_routes=[],
|
|
dns_nameservers=[],
|
|
group='ctlplane-subnet')
|
|
|
|
|
|
class TestNetworkSettings(TestBaseNetworkSettings):
|
|
def test_default(self):
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_ipv6_control_plane_stateless_default(self):
|
|
env = {}
|
|
self.conf.config(local_ip='fd12:3456:789a:1::2/64',
|
|
undercloud_admin_host='fd12:3456:789a:1::3',
|
|
undercloud_public_host='fd12:3456:789a:1::4')
|
|
self.conf.config(cidr='fd12:3456:789a:1::/64',
|
|
dhcp_start='fd12:3456:789a:1::10',
|
|
dhcp_end='fd12:3456:789a:1::20',
|
|
dhcp_exclude=[],
|
|
dns_nameservers=['fd12:3456:789a:1::5',
|
|
'fd12:3456:789a:1::6'],
|
|
inspection_iprange=('fd12:3456:789a:1::30,'
|
|
'fd12:3456:789a:1::40'),
|
|
gateway='fd12:3456:789a:1::1',
|
|
masquerade=False,
|
|
host_routes=[],
|
|
group='ctlplane-subnet')
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'NovaIPv6': True,
|
|
'RabbitIPv6': True,
|
|
'MemcachedIPv6': True,
|
|
'RedisIPv6': True,
|
|
'MysqlIPv6': True,
|
|
'IronicIpVersion': '6',
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': 'fd12:3456:789a:1::1',
|
|
'host_routes': [],
|
|
'ip_range': 'fd12:3456:789a:1::,static',
|
|
'netmask': 'ffff:ffff:ffff:ffff::',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': 'fd12:3456:789a:1::10',
|
|
'end': 'fd12:3456:789a:1::20'}],
|
|
'DnsNameServers': ['fd12:3456:789a:1::5',
|
|
'fd12:3456:789a:1::6'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': 'fd12:3456:789a:1::/64',
|
|
'NetworkGateway': 'fd12:3456:789a:1::1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_ipv6_control_plane_stateful(self):
|
|
env = {}
|
|
self.conf.config(local_ip='fd12:3456:789a:1::2/64',
|
|
undercloud_admin_host='fd12:3456:789a:1::3',
|
|
undercloud_public_host='fd12:3456:789a:1::4',
|
|
ipv6_address_mode='dhcpv6-stateful')
|
|
self.conf.config(cidr='fd12:3456:789a:1::/64',
|
|
dhcp_start='fd12:3456:789a:1::10',
|
|
dhcp_end='fd12:3456:789a:1::20',
|
|
dhcp_exclude=[],
|
|
dns_nameservers=['fd12:3456:789a:1::5',
|
|
'fd12:3456:789a:1::6'],
|
|
inspection_iprange=('fd12:3456:789a:1::30,'
|
|
'fd12:3456:789a:1::40'),
|
|
gateway='fd12:3456:789a:1::1',
|
|
masquerade=False,
|
|
host_routes=[],
|
|
group='ctlplane-subnet')
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'NovaIPv6': True,
|
|
'RabbitIPv6': True,
|
|
'MemcachedIPv6': True,
|
|
'RedisIPv6': True,
|
|
'MysqlIPv6': True,
|
|
'IronicIpVersion': '6',
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': 'fd12:3456:789a:1::1',
|
|
'host_routes': [],
|
|
'ip_range': 'fd12:3456:789a:1::30,fd12:3456:789a:1::40',
|
|
'netmask': 'ffff:ffff:ffff:ffff::',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': 'fd12:3456:789a:1::10',
|
|
'end': 'fd12:3456:789a:1::20'}],
|
|
'DnsNameServers': ['fd12:3456:789a:1::5',
|
|
'fd12:3456:789a:1::6'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': 'fd12:3456:789a:1::/64',
|
|
'NetworkGateway': 'fd12:3456:789a:1::1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateful',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_nameserver_toomany_fail(self):
|
|
env = {}
|
|
self.conf.config(undercloud_nameservers=['1.1.1.1', '1.1.1.2',
|
|
'1.1.1.3', '1.1.1.4',
|
|
'1.1.1.5', '1.1.1.6'])
|
|
self.assertRaises(exceptions.InvalidConfiguration,
|
|
undercloud_config._process_network_args,
|
|
env)
|
|
|
|
def test_undercloud_ips_duplicated_fail(self):
|
|
env = {}
|
|
|
|
# local_ip == undercloud_admin_host
|
|
self.conf.config(local_ip='192.168.24.1/24',
|
|
undercloud_admin_host='192.168.24.1',
|
|
undercloud_public_host='192.168.24.2',
|
|
generate_service_certificate=True)
|
|
self.assertRaises(exceptions.InvalidConfiguration,
|
|
undercloud_config._process_network_args,
|
|
env)
|
|
|
|
# local_ip == undercloud_public_host
|
|
self.conf.config(local_ip='192.168.24.1/24',
|
|
undercloud_admin_host='192.168.24.3',
|
|
undercloud_public_host='192.168.24.1',
|
|
generate_service_certificate=True)
|
|
self.assertRaises(exceptions.InvalidConfiguration,
|
|
undercloud_config._process_network_args,
|
|
env)
|
|
|
|
# undercloud_admin_host == undercloud_public_host
|
|
self.conf.config(local_ip='192.168.24.1/24',
|
|
undercloud_admin_host='192.168.24.2',
|
|
undercloud_public_host='192.168.24.2',
|
|
generate_service_certificate=True)
|
|
self.assertRaises(exceptions.InvalidConfiguration,
|
|
undercloud_config._process_network_args,
|
|
env)
|
|
|
|
# We do not care about ip duplication when ssl is disabled
|
|
self.conf.config(local_ip='192.168.24.1/24',
|
|
undercloud_admin_host='192.168.24.1',
|
|
undercloud_public_host='192.168.24.2',
|
|
generate_service_certificate=False,
|
|
undercloud_service_certificate='')
|
|
undercloud_config._process_network_args(env)
|
|
|
|
def test_start_end_all_addresses(self):
|
|
self.conf.config(dhcp_start='192.168.24.0',
|
|
dhcp_end='192.168.24.255',
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.4', 'end': '192.168.24.99'},
|
|
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_ignore_dhcp_start_end_if_default_but_cidr_not_default(self):
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
inspection_iprange='192.168.10.100,192.168.10.120',
|
|
gateway='192.168.10.1',
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.10.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.100,192.168.10.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.2', 'end': '192.168.10.99'},
|
|
{'start': '192.168.10.121', 'end': '192.168.10.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_dhcp_exclude(self):
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
inspection_iprange='192.168.10.100,192.168.10.120',
|
|
gateway='192.168.10.1',
|
|
dhcp_exclude=['192.168.10.50',
|
|
'192.168.10.80-192.168.10.89'],
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.10.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.100,192.168.10.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.2', 'end': '192.168.10.49'},
|
|
{'start': '192.168.10.51', 'end': '192.168.10.79'},
|
|
{'start': '192.168.10.90', 'end': '192.168.10.99'},
|
|
{'start': '192.168.10.121', 'end': '192.168.10.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_no_dhcp_start_no_dhcp_end(self):
|
|
self.conf.config(dhcp_start=[],
|
|
dhcp_end=[],
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.4', 'end': '192.168.24.99'},
|
|
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'}},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_dhcp_start_no_dhcp_end(self):
|
|
self.conf.config(dhcp_start='192.168.24.10',
|
|
dhcp_end=[],
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.10', 'end': '192.168.24.99'},
|
|
{'start': '192.168.24.121', 'end': '192.168.24.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_dhcp_end_no_dhcp_start(self):
|
|
self.conf.config(dhcp_start=[],
|
|
dhcp_end='192.168.24.220',
|
|
group='ctlplane-subnet')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500}],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.4', 'end': '192.168.24.99'},
|
|
{'start': '192.168.24.121', 'end': '192.168.24.220'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_routed_network(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1', 'subnet2'])
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.register_opts(self.opts, group=self.grp2)
|
|
self.conf.config(masquerade=True,
|
|
dns_nameservers=['10.1.1.100', '10.1.1.101'],
|
|
group='ctlplane-subnet')
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
dhcp_start='192.168.10.10',
|
|
dhcp_end='192.168.10.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.10.100,192.168.10.189',
|
|
gateway='192.168.10.254',
|
|
dns_nameservers=['10.2.2.100', '10.2.2.101'],
|
|
host_routes=[],
|
|
masquerade=True,
|
|
group='subnet1')
|
|
self.conf.config(cidr='192.168.20.0/24',
|
|
dhcp_start='192.168.20.10',
|
|
dhcp_end='192.168.20.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.20.100,192.168.20.189',
|
|
gateway='192.168.20.254',
|
|
dns_nameservers=['10.3.3.100', '10.3.3.101'],
|
|
host_routes=[],
|
|
masquerade=True,
|
|
group='subnet2')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [
|
|
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
|
|
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'}],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.10.254',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.100,192.168.10.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet1',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.20.254',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.20.100,192.168.20.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet2',
|
|
'mtu': 1500}
|
|
],
|
|
'MasqueradeNetworks': {
|
|
'192.168.10.0/24': ['192.168.24.0/24',
|
|
'192.168.10.0/24',
|
|
'192.168.20.0/24'],
|
|
'192.168.20.0/24': ['192.168.24.0/24',
|
|
'192.168.10.0/24',
|
|
'192.168.20.0/24'],
|
|
'192.168.24.0/24': ['192.168.24.0/24',
|
|
'192.168.10.0/24',
|
|
'192.168.20.0/24']},
|
|
'UndercloudCtlplaneSubnets': {
|
|
# The ctlplane-subnet subnet have defaults
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.1.1.100', '10.1.1.101'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
'subnet1': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
|
|
'DnsNameServers': ['10.2.2.100', '10.2.2.101'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.254'},
|
|
'subnet2': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
|
|
'DnsNameServers': ['10.3.3.100', '10.3.3.101'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.20.0/24',
|
|
'NetworkGateway': '192.168.20.254'}
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_routed_network_no_masquerading(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1', 'subnet2'])
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.register_opts(self.opts, group=self.grp2)
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
dhcp_start='192.168.10.10',
|
|
dhcp_end='192.168.10.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.10.100,192.168.10.189',
|
|
gateway='192.168.10.254',
|
|
dns_nameservers=[],
|
|
host_routes=[],
|
|
group='subnet1')
|
|
self.conf.config(cidr='192.168.20.0/24',
|
|
dhcp_start='192.168.20.10',
|
|
dhcp_end='192.168.20.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.20.100,192.168.20.189',
|
|
gateway='192.168.20.254',
|
|
dns_nameservers=[],
|
|
host_routes=[],
|
|
group='subnet2')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [
|
|
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
|
|
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'}],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.10.254',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.100,192.168.10.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet1',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.20.254',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.20.100,192.168.20.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet2',
|
|
'mtu': 1500}
|
|
],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
# The ctlplane-subnet subnet have defaults
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
'subnet1': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.254'},
|
|
'subnet2': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.20.0/24',
|
|
'NetworkGateway': '192.168.20.254'}
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_no_allocation_pool_on_remote_network(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1'])
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.10.200,192.168.10.254',
|
|
gateway='192.168.10.254',
|
|
dns_nameservers=[],
|
|
host_routes=[],
|
|
masquerade=False,
|
|
group='subnet1')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [
|
|
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'}],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.10.254',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.200,192.168.10.254',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet1',
|
|
'mtu': 1500},
|
|
],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
# The ctlplane-subnet subnet have defaults
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
'subnet1': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.1', 'end': '192.168.10.199'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.254'}
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_no_allocation_pool_on_remote_network_three_pools(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1'])
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.10.100,192.168.10.199',
|
|
gateway='192.168.10.222',
|
|
dns_nameservers=[],
|
|
host_routes=[],
|
|
masquerade=False,
|
|
group='subnet1')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [
|
|
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'}],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.10.222',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.10.100,192.168.10.199',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet1',
|
|
'mtu': 1500},
|
|
],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
# The ctlplane-subnet subnet have defaults
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
'subnet1': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.1', 'end': '192.168.10.99'},
|
|
{'start': '192.168.10.200', 'end': '192.168.10.221'},
|
|
{'start': '192.168.10.223', 'end': '192.168.10.254'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.222'}
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless',
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_additional_host_routes(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1', 'subnet2'])
|
|
self.conf.config(host_routes=[{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.24.1'}],
|
|
group='ctlplane-subnet')
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.register_opts(self.opts, group=self.grp2)
|
|
self.conf.config(cidr='192.168.10.0/24',
|
|
dhcp_start='192.168.10.10',
|
|
dhcp_end='192.168.10.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.10.100,192.168.10.189',
|
|
gateway='192.168.10.254',
|
|
dns_nameservers=[],
|
|
host_routes=[{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.10.254'}],
|
|
group='subnet1')
|
|
self.conf.config(cidr='192.168.20.0/24',
|
|
dhcp_start='192.168.20.10',
|
|
dhcp_end='192.168.20.99',
|
|
dhcp_exclude=[],
|
|
inspection_iprange='192.168.20.100,192.168.20.189',
|
|
gateway='192.168.20.254',
|
|
dns_nameservers=[],
|
|
host_routes=[{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.20.254'}],
|
|
group='subnet2')
|
|
env = {}
|
|
undercloud_config._process_network_args(env)
|
|
expected = {
|
|
'ControlPlaneStaticRoutes': [
|
|
{'ip_netmask': '192.168.10.0/24', 'next_hop': '192.168.24.1'},
|
|
{'ip_netmask': '192.168.20.0/24', 'next_hop': '192.168.24.1'},
|
|
{'ip_netmask': '10.10.10.254/32', 'next_hop': '192.168.24.1'}],
|
|
'IronicInspectorSubnets': [
|
|
{'gateway': '192.168.24.1',
|
|
'host_routes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.24.1'}],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.10.254',
|
|
'host_routes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.10.254'}],
|
|
'ip_range': '192.168.10.100,192.168.10.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet1',
|
|
'mtu': 1500},
|
|
{'gateway': '192.168.20.254',
|
|
'host_routes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.20.254'}],
|
|
'ip_range': '192.168.20.100,192.168.20.189',
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'subnet2',
|
|
'mtu': 1500}
|
|
],
|
|
'MasqueradeNetworks': {},
|
|
'UndercloudCtlplaneSubnets': {
|
|
# The ctlplane-subnet subnet have defaults
|
|
'ctlplane-subnet': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.24.1'}],
|
|
'NetworkCidr': '192.168.24.0/24',
|
|
'NetworkGateway': '192.168.24.1'},
|
|
'subnet1': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.10.254'}],
|
|
'NetworkCidr': '192.168.10.0/24',
|
|
'NetworkGateway': '192.168.10.254'},
|
|
'subnet2': {
|
|
'AllocationPools': [
|
|
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
|
|
'DnsNameServers': ['10.10.10.10', '10.10.10.11'],
|
|
'HostRoutes': [{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.20.254'}],
|
|
'NetworkCidr': '192.168.20.0/24',
|
|
'NetworkGateway': '192.168.20.254'}
|
|
},
|
|
'UndercloudCtlplaneIPv6AddressMode': 'dhcpv6-stateless'
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
def test_generate_inspection_subnets(self):
|
|
result = undercloud_config._generate_inspection_subnets()
|
|
expected = [{'gateway': '192.168.24.1',
|
|
'host_routes': [],
|
|
'ip_range': '192.168.24.100,192.168.24.120',
|
|
'mtu': 1500,
|
|
'netmask': '255.255.255.0',
|
|
'tag': 'ctlplane-subnet'}]
|
|
self.assertEqual(expected, result)
|
|
|
|
def test_generate_inspection_subnets_invalid(self):
|
|
self.conf.config(subnets=['ctlplane-subnet', 'subnet1'])
|
|
self.conf.config(host_routes=[{'destination': '10.10.10.254/32',
|
|
'nexthop': '192.168.24.1'}],
|
|
group='ctlplane-subnet')
|
|
self.conf.register_opts(self.opts, group=self.grp1)
|
|
self.conf.config(group='subnet1')
|
|
self.assertRaises(exceptions.DeploymentError,
|
|
undercloud_config._generate_inspection_subnets)
|
|
|
|
|
|
class TestChronySettings(TestBaseNetworkSettings):
|
|
def test_default(self):
|
|
env = {}
|
|
undercloud_config._process_chrony_acls(env)
|
|
expected = {
|
|
'ChronyAclRules': ['allow 192.168.24.0/24'],
|
|
}
|
|
self.assertEqual(expected, env)
|
|
|
|
|
|
class TestTLSSettings(base.TestCase):
|
|
def test_public_host_with_ip_should_give_ip_endpoint_environment(self):
|
|
expected_env_file = os.path.join(
|
|
undercloud_config.THT_HOME,
|
|
"environments/ssl/tls-endpoints-public-ip.yaml")
|
|
|
|
resulting_env_file1 = undercloud_config._get_tls_endpoint_environment(
|
|
'127.0.0.1', undercloud_config.THT_HOME)
|
|
|
|
self.assertEqual(expected_env_file, resulting_env_file1)
|
|
|
|
resulting_env_file2 = undercloud_config._get_tls_endpoint_environment(
|
|
'192.168.1.1', undercloud_config.THT_HOME)
|
|
|
|
self.assertEqual(expected_env_file, resulting_env_file2)
|
|
|
|
def test_public_host_with_fqdn_should_give_dns_endpoint_environment(self):
|
|
expected_env_file = os.path.join(
|
|
undercloud_config.THT_HOME,
|
|
"environments/ssl/tls-endpoints-public-dns.yaml")
|
|
|
|
resulting_env_file1 = undercloud_config._get_tls_endpoint_environment(
|
|
'controller-1', undercloud_config.THT_HOME)
|
|
|
|
self.assertEqual(expected_env_file, resulting_env_file1)
|
|
|
|
resulting_env_file2 = undercloud_config._get_tls_endpoint_environment(
|
|
'controller-1.tripleodomain.com', undercloud_config.THT_HOME)
|
|
|
|
self.assertEqual(expected_env_file, resulting_env_file2)
|
|
|
|
def get_certificate_and_private_key(self):
|
|
private_key = rsa.generate_private_key(public_exponent=3,
|
|
key_size=1024,
|
|
backend=default_backend())
|
|
issuer = x509.Name([
|
|
x509.NameAttribute(NameOID.COUNTRY_NAME, u"FI"),
|
|
x509.NameAttribute(NameOID.LOCALITY_NAME, u"Helsinki"),
|
|
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Some Company"),
|
|
x509.NameAttribute(NameOID.COMMON_NAME, u"Test Certificate"),
|
|
])
|
|
cert_builder = x509.CertificateBuilder(
|
|
issuer_name=issuer, subject_name=issuer,
|
|
public_key=private_key.public_key(),
|
|
serial_number=x509.random_serial_number(),
|
|
not_valid_before=datetime.utcnow(),
|
|
not_valid_after=datetime.utcnow() + timedelta(days=10)
|
|
)
|
|
cert = cert_builder.sign(private_key,
|
|
hashes.SHA256(),
|
|
default_backend())
|
|
cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
|
|
key_pem = private_key.private_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
encryption_algorithm=serialization.NoEncryption())
|
|
return cert_pem, key_pem
|
|
|
|
def test_get_dict_with_cert_and_key_from_bundled_pem(self):
|
|
cert_pem, key_pem = self.get_certificate_and_private_key()
|
|
|
|
with tempfile.NamedTemporaryFile() as tempbundle:
|
|
tempbundle.write(cert_pem)
|
|
tempbundle.write(key_pem)
|
|
tempbundle.seek(0)
|
|
|
|
tls_parameters = undercloud_config._get_public_tls_parameters(
|
|
tempbundle.name)
|
|
|
|
self.assertEqual(cert_pem, tls_parameters['SSLCertificate'])
|
|
self.assertEqual(key_pem, tls_parameters['SSLKey'])
|
|
|
|
def test_get_tls_parameters_fails_cause_of_missing_cert(self):
|
|
_, key_pem = self.get_certificate_and_private_key()
|
|
|
|
with tempfile.NamedTemporaryFile() as tempbundle:
|
|
tempbundle.write(key_pem)
|
|
tempbundle.seek(0)
|
|
|
|
self.assertRaises(ValueError,
|
|
undercloud_config._get_public_tls_parameters,
|
|
tempbundle.name)
|
|
|
|
def test_get_tls_parameters_fails_cause_of_missing_key(self):
|
|
cert_pem, _ = self.get_certificate_and_private_key()
|
|
|
|
with tempfile.NamedTemporaryFile() as tempbundle:
|
|
tempbundle.write(cert_pem)
|
|
tempbundle.seek(0)
|
|
|
|
self.assertRaises(ValueError,
|
|
undercloud_config._get_public_tls_parameters,
|
|
tempbundle.name)
|
|
|
|
def test_get_tls_parameters_fails_cause_of_unexistent_file(self):
|
|
self.assertRaises(IOError,
|
|
undercloud_config._get_public_tls_parameters,
|
|
'/tmp/unexistent-file-12345.pem')
|
|
|
|
|
|
class TestContainerImageConfig(base.TestCase):
|
|
def setUp(self):
|
|
super(TestContainerImageConfig, self).setUp()
|
|
conf_keys = (
|
|
'container_images_file',
|
|
)
|
|
self.conf = mock.Mock(**{key: getattr(undercloud_config.CONF, key)
|
|
for key in conf_keys})
|
|
|
|
@mock.patch('shutil.copy')
|
|
def test_defaults(self, mock_copy):
|
|
env = {}
|
|
deploy_args = []
|
|
cip_default = getattr(kolla_builder,
|
|
'CONTAINER_IMAGE_PREPARE_PARAM', None)
|
|
self.addCleanup(setattr, kolla_builder,
|
|
'CONTAINER_IMAGE_PREPARE_PARAM', cip_default)
|
|
|
|
setattr(kolla_builder, 'CONTAINER_IMAGE_PREPARE_PARAM', [{
|
|
'set': {
|
|
'namespace': 'one',
|
|
'name_prefix': 'two',
|
|
'name_suffix': 'three',
|
|
'tag': 'four',
|
|
},
|
|
'tag_from_label': 'five',
|
|
}])
|
|
|
|
undercloud_config._container_images_config(self.conf, deploy_args,
|
|
env, None)
|
|
self.assertEqual([], deploy_args)
|
|
cip = env['ContainerImagePrepare'][0]
|
|
set = cip['set']
|
|
|
|
self.assertEqual(
|
|
'one', set['namespace'])
|
|
self.assertEqual(
|
|
'two', set['name_prefix'])
|
|
self.assertEqual(
|
|
'three', set['name_suffix'])
|
|
self.assertEqual(
|
|
'four', set['tag'])
|
|
self.assertEqual(
|
|
'five', cip['tag_from_label'])
|
|
|
|
@mock.patch('shutil.copy')
|
|
def test_container_images_file(self, mock_copy):
|
|
env = {}
|
|
deploy_args = []
|
|
self.conf.container_images_file = '/tmp/container_images_file.yaml'
|
|
undercloud_config._container_images_config(self.conf, deploy_args,
|
|
env, None)
|
|
self.assertEqual(['-e', '/tmp/container_images_file.yaml'],
|
|
deploy_args)
|
|
self.assertEqual({}, env)
|
|
|
|
@mock.patch('shutil.copy')
|
|
def test_custom(self, mock_copy):
|
|
env = {}
|
|
deploy_args = []
|
|
with tempfile.NamedTemporaryFile(mode='w') as f:
|
|
yaml.dump({
|
|
'parameter_defaults': {'ContainerImagePrepare': [{
|
|
'set': {
|
|
'namespace': 'one',
|
|
'name_prefix': 'two',
|
|
'name_suffix': 'three',
|
|
'tag': 'four',
|
|
},
|
|
'tag_from_label': 'five',
|
|
}]}
|
|
}, f)
|
|
self.conf.container_images_file = f.name
|
|
cif_name = f.name
|
|
|
|
undercloud_config._container_images_config(
|
|
self.conf, deploy_args, env, None)
|
|
self.assertEqual(['-e', cif_name], deploy_args)
|