python-tripleoclient/tripleoclient/tests/v1/undercloud/test_config.py

761 lines
34 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.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')})
def test_defaults(self):
env = {}
undercloud_config._process_drivers_and_hardware_types(self.conf, env)
self.assertEqual({
'IronicEnabledHardwareTypes': ['idrac', 'ilo', 'ipmi', 'redfish'],
'IronicEnabledBootInterfaces': ['ilo-pxe', 'ipxe', 'pxe'],
'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({
# ipmi added because it's the default discovery driver
'IronicEnabledHardwareTypes': ['ipmi', 'redfish'],
'IronicEnabledBootInterfaces': ['ipxe', 'pxe'],
'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', 'cisco-ucs-managed',
'cisco-ucs-standalone',
'xclarity']
)
undercloud_config._process_drivers_and_hardware_types(self.conf, env)
self.assertEqual({
'IronicEnabledHardwareTypes': ['cisco-ucs-managed',
'cisco-ucs-standalone',
'idrac', 'ilo', 'ipmi', 'irmc',
'redfish', 'snmp', 'staging-ovirt',
'xclarity'],
'IronicEnabledBootInterfaces': ['ilo-pxe', 'ipxe', 'irmc-pxe',
'pxe'],
'IronicEnabledManagementInterfaces': ['cimc', 'fake', 'idrac',
'ilo', 'ipmitool', 'irmc',
'noop', 'redfish',
'staging-ovirt',
'ucsm', 'xclarity'],
'IronicEnabledPowerInterfaces': ['cimc', 'fake', 'idrac',
'ilo', 'ipmitool', 'irmc',
'redfish', 'snmp',
'staging-ovirt', 'ucsm',
'xclarity'],
'IronicEnabledRaidInterfaces': ['idrac', 'no-raid'],
'IronicEnabledVendorInterfaces': ['idrac', 'ipmitool', 'no-vendor']
}, env)
class TestNetworkSettings(base.TestCase):
def setUp(self):
super(TestNetworkSettings, 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')
# 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')]
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,
group='ctlplane-subnet')
def test_default(self):
env = {}
undercloud_config._process_network_args(env)
expected = {
'ControlPlaneStaticRoutes': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'MasqueradeNetworks': {},
'UndercloudCtlplaneSubnets': {
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
self.assertEqual(expected, 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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
'DhcpRangeEnd': '192.168.24.255',
'DhcpRangeStart': '192.168.24.0',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.10.1',
'ip_range': '192.168.10.100,192.168.10.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.1'}}}
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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.10.1',
'ip_range': '192.168.10.100,192.168.10.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.1'}}}
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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}}
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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeStart': '192.168.24.10',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}
}
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': [],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'}],
'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'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeEnd': '192.168.24.220',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'}}
}
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,
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',
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',
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'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'},
{'gateway': '192.168.10.254',
'ip_range': '192.168.10.100,192.168.10.189',
'netmask': '255.255.255.0',
'tag': 'subnet1'},
{'gateway': '192.168.20.254',
'ip_range': '192.168.20.100,192.168.20.189',
'netmask': '255.255.255.0',
'tag': 'subnet2'}
],
'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'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
'DhcpRangeEnd': '192.168.10.99',
'DhcpRangeStart': '192.168.10.10',
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'},
'subnet2': {
'AllocationPools': [
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
'DhcpRangeEnd': '192.168.20.99',
'DhcpRangeStart': '192.168.20.10',
'NetworkCidr': '192.168.20.0/24',
'NetworkGateway': '192.168.20.254'}
}
}
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',
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',
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'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'},
{'gateway': '192.168.10.254',
'ip_range': '192.168.10.100,192.168.10.189',
'netmask': '255.255.255.0',
'tag': 'subnet1'},
{'gateway': '192.168.20.254',
'ip_range': '192.168.20.100,192.168.20.189',
'netmask': '255.255.255.0',
'tag': 'subnet2'}
],
'MasqueradeNetworks': {},
'UndercloudCtlplaneSubnets': {
# The ctlplane-subnet subnet have defaults
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.10', 'end': '192.168.10.99'}],
'DhcpRangeEnd': '192.168.10.99',
'DhcpRangeStart': '192.168.10.10',
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'},
'subnet2': {
'AllocationPools': [
{'start': '192.168.20.10', 'end': '192.168.20.99'}],
'DhcpRangeEnd': '192.168.20.99',
'DhcpRangeStart': '192.168.20.10',
'NetworkCidr': '192.168.20.0/24',
'NetworkGateway': '192.168.20.254'}
}
}
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',
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'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'},
{'gateway': '192.168.10.254',
'ip_range': '192.168.10.200,192.168.10.254',
'netmask': '255.255.255.0',
'tag': 'subnet1'},
],
'MasqueradeNetworks': {},
'UndercloudCtlplaneSubnets': {
# The ctlplane-subnet subnet have defaults
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'NetworkCidr': '192.168.24.0/24',
'NetworkGateway': '192.168.24.1'},
'subnet1': {
'AllocationPools': [
{'start': '192.168.10.1', 'end': '192.168.10.199'}],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.254'}
}
}
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',
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'}],
'DnsServers': '',
'IronicInspectorSubnets': [
{'gateway': '192.168.24.1',
'ip_range': '192.168.24.100,192.168.24.120',
'netmask': '255.255.255.0',
'tag': 'ctlplane-subnet'},
{'gateway': '192.168.10.222',
'ip_range': '192.168.10.100,192.168.10.199',
'netmask': '255.255.255.0',
'tag': 'subnet1'},
],
'MasqueradeNetworks': {},
'UndercloudCtlplaneSubnets': {
# The ctlplane-subnet subnet have defaults
'ctlplane-subnet': {
'AllocationPools': [
{'start': '192.168.24.5', 'end': '192.168.24.24'}],
# TODO(hjensas): Remove DhcpRangeStart and DhcpRangeEnd
# once change: Ifdf3e9d22766c1b5ede151979b93754a3d244cc3 is
# merged and THT uses AllocationPools.
'DhcpRangeEnd': '192.168.24.24',
'DhcpRangeStart': '192.168.24.5',
'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'}],
'NetworkCidr': '192.168.10.0/24',
'NetworkGateway': '192.168.10.222'}
}
}
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)