Merge "Introduce Puppet variables for primary and secondary pool addresses."
This commit is contained in:
commit
1b9bc6ed76
|
@ -1037,6 +1037,20 @@ class ConductorManager(service.PeriodicService):
|
|||
True)
|
||||
return address.address
|
||||
except exception.AddressNotFoundByName:
|
||||
LOG.info(f"cannot find address with name={name}")
|
||||
return None
|
||||
|
||||
def _lookup_static_ip_address_family(self, name, networktype, family):
|
||||
""""Find a statically configured address based on name, network type,
|
||||
and address family."""
|
||||
try:
|
||||
# address names are refined by network type to ensure they are
|
||||
# unique across different address pools
|
||||
name = cutils.format_address_name(name, networktype)
|
||||
address = self.dbapi.address_get_by_name_and_family(name, family)
|
||||
return address.address
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
LOG.info(f"cannot find address with name={name}, family={family}")
|
||||
return None
|
||||
|
||||
def _using_static_ip(self, ihost, personality=None, hostname=None):
|
||||
|
@ -1378,7 +1392,7 @@ class ConductorManager(service.PeriodicService):
|
|||
)
|
||||
|
||||
func = "_generate_dnsmasq_hosts_file"
|
||||
with open(temp_dnsmasq_hosts_file, 'w') as f_out,\
|
||||
with open(temp_dnsmasq_hosts_file, 'w') as f_out, \
|
||||
open(temp_dnsmasq_addn_hosts_file, 'w') as f_out_addn:
|
||||
|
||||
# Write entry for pxecontroller into addn_hosts file
|
||||
|
@ -2054,7 +2068,19 @@ class ConductorManager(service.PeriodicService):
|
|||
pass
|
||||
|
||||
def _create_or_update_address(self, context, hostname, ip_address,
|
||||
iface_type, iface_id=None):
|
||||
iface_type, iface_id=None, pool_uuid=None):
|
||||
"""Searches the address database and create or update accordingly
|
||||
|
||||
Args:
|
||||
hostname (str): The host name
|
||||
ip_address (str): The IP address to be created or updated.
|
||||
iface_type (str): The interface network type.
|
||||
iface_id (int, optional): Interface ID that uses this address. Defaults to None.
|
||||
pool_uuid (str, optional): The address pool uuid. Defaults to None.
|
||||
|
||||
Returns:
|
||||
sysinv.object.address: The updated or created address
|
||||
"""
|
||||
if hostname is None or ip_address is None:
|
||||
return
|
||||
address_name = cutils.format_address_name(hostname, iface_type)
|
||||
|
@ -2062,34 +2088,41 @@ class ConductorManager(service.PeriodicService):
|
|||
try:
|
||||
address = self.dbapi.address_get_by_address(ip_address)
|
||||
address_uuid = address['uuid']
|
||||
search_addr = self.dbapi.address_get_by_name_and_family(address_name,
|
||||
address_family)
|
||||
# If name is already set, return
|
||||
search_addr = cutils.get_primary_address_by_name(self.dbapi,
|
||||
address_name,
|
||||
iface_type, True)
|
||||
if search_addr:
|
||||
if (search_addr.uuid == address_uuid and iface_id is None):
|
||||
LOG.info(f"returning, address '{address_uuid}' exists and iface_id is None")
|
||||
return
|
||||
except exception.AddressNotFoundByAddress:
|
||||
address_uuid = None
|
||||
except exception.AddressNotFoundByName:
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
pass
|
||||
network = self.dbapi.network_get_by_type(iface_type)
|
||||
address_pool_uuid = network.pool_uuid
|
||||
address_pool = self.dbapi.address_pool_get(address_pool_uuid)
|
||||
values = {
|
||||
'name': address_name,
|
||||
'family': address_family,
|
||||
'prefix': address_pool.prefix,
|
||||
'address': ip_address,
|
||||
'address_pool_id': address_pool.id,
|
||||
}
|
||||
|
||||
if iface_id:
|
||||
values['interface_id'] = iface_id
|
||||
if address_uuid:
|
||||
address = self.dbapi.address_update(address_uuid, values)
|
||||
address_pool = None
|
||||
if pool_uuid:
|
||||
address_pool = self.dbapi.address_pool_get(pool_uuid)
|
||||
else:
|
||||
address = self.dbapi.address_create(values)
|
||||
network = self.dbapi.network_get_by_type(iface_type)
|
||||
address_pool = self.dbapi.address_pool_get(network.pool_uuid)
|
||||
|
||||
if address_pool:
|
||||
values = {
|
||||
'name': address_name,
|
||||
'family': address_family,
|
||||
'prefix': address_pool.prefix,
|
||||
'address': ip_address,
|
||||
'address_pool_id': address_pool.id,
|
||||
}
|
||||
if iface_id:
|
||||
values['interface_id'] = iface_id
|
||||
|
||||
if address_uuid:
|
||||
address = self.dbapi.address_update(address_uuid, values)
|
||||
else:
|
||||
address = self.dbapi.address_create(values)
|
||||
|
||||
self._generate_dnsmasq_hosts_file()
|
||||
return address
|
||||
|
||||
|
@ -2110,19 +2143,32 @@ class ConductorManager(service.PeriodicService):
|
|||
|
||||
# controller must have cluster-host address already allocated
|
||||
if (host.personality != constants.CONTROLLER):
|
||||
network = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(network.id)
|
||||
pool_uuid_list = list()
|
||||
if net_pools:
|
||||
for net_pool in net_pools:
|
||||
pool_uuid_list.append(net_pool.address_pool_uuid)
|
||||
else:
|
||||
# we are coming from an upgrade without data-migration implemented for the
|
||||
# dual stack feature
|
||||
LOG.warning(f"Network {network.name} does not have network to address pool objects")
|
||||
pool_uuid_list.append(network.pool_uuid)
|
||||
|
||||
cluster_host_address = self._lookup_static_ip_address(
|
||||
host.hostname, constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
hostname = host.hostname
|
||||
|
||||
if cluster_host_address is None:
|
||||
address_name = cutils.format_address_name(
|
||||
host.hostname, constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
LOG.info("{} address not found. Allocating address for {}.".format(
|
||||
address_name, host.hostname))
|
||||
host_network = self.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
self._allocate_pool_address(None, host_network.pool_uuid,
|
||||
address_name)
|
||||
for pool_uuid in pool_uuid_list:
|
||||
pool = self.dbapi.address_pool_get(pool_uuid)
|
||||
|
||||
cluster_host_address = self._lookup_static_ip_address_family(
|
||||
host.hostname, constants.NETWORK_TYPE_CLUSTER_HOST, pool.family)
|
||||
|
||||
if cluster_host_address is None:
|
||||
address_name = cutils.format_address_name(
|
||||
hostname, constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
resp_addr = self._allocate_pool_address(None, pool.uuid, address_name)
|
||||
LOG.info(f"{address_name} address not found."
|
||||
f" Allocating address {resp_addr.address} for {hostname}.")
|
||||
|
||||
def _allocate_addresses_for_host(self, context, host):
|
||||
"""Allocates addresses for a given host.
|
||||
|
@ -2142,28 +2188,40 @@ class ConductorManager(service.PeriodicService):
|
|||
mgmt_interface_id = None
|
||||
if mgmt_interfaces:
|
||||
mgmt_interface_id = mgmt_interfaces[0]['id']
|
||||
hostname = host.hostname
|
||||
|
||||
# check for static mgmt IP
|
||||
mgmt_ip = self._lookup_static_ip_address(
|
||||
hostname, constants.NETWORK_TYPE_MGMT
|
||||
)
|
||||
# make sure address in address table and update dnsmasq host file
|
||||
if mgmt_ip:
|
||||
LOG.info("Static mgmt ip {} for host{}".format(mgmt_ip, hostname))
|
||||
self._create_or_update_address(context, hostname, mgmt_ip,
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
mgmt_interface_id)
|
||||
# if no static address, then allocate one
|
||||
if not mgmt_ip:
|
||||
mgmt_pool = self.dbapi.network_get_by_type(
|
||||
constants.NETWORK_TYPE_MGMT
|
||||
).pool_uuid
|
||||
address_name = cutils.format_address_name(hostname,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
mgmt_ip = self._allocate_pool_address(mgmt_interface_id, mgmt_pool,
|
||||
address_name).address
|
||||
LOG.info("Allocated mgmt ip {} for host{}".format(mgmt_ip, hostname))
|
||||
hostname = host.hostname
|
||||
mgmt_net = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_MGMT)
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(mgmt_net.id)
|
||||
pool_uuid_list = list()
|
||||
if net_pools:
|
||||
for net_pool in net_pools:
|
||||
pool_uuid_list.append(net_pool.address_pool_uuid)
|
||||
else:
|
||||
# we are coming from an upgrade without data-migration implemented for the
|
||||
# dual stack feature
|
||||
LOG.warning(f"Network {mgmt_net.name} does not have network to address pool objects")
|
||||
pool_uuid_list.append(mgmt_net.pool_uuid)
|
||||
|
||||
for pool_uuid in pool_uuid_list:
|
||||
pool = self.dbapi.address_pool_get(pool_uuid)
|
||||
|
||||
# check for static mgmt IP
|
||||
mgmt_ip = self._lookup_static_ip_address_family(
|
||||
hostname, constants.NETWORK_TYPE_MGMT, pool.family)
|
||||
|
||||
# make sure address in address table and update dnsmasq host file
|
||||
if mgmt_ip:
|
||||
LOG.info("Static mgmt ip {} for host{}".format(mgmt_ip, hostname))
|
||||
self._create_or_update_address(context, hostname, mgmt_ip,
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
mgmt_interface_id, pool_uuid)
|
||||
# if no static address, then allocate one
|
||||
if not mgmt_ip:
|
||||
address_name = cutils.format_address_name(hostname,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
mgmt_ip = self._allocate_pool_address(mgmt_interface_id, pool_uuid,
|
||||
address_name).address
|
||||
LOG.info(f"Allocated mgmt ip {mgmt_ip} for host={hostname}")
|
||||
|
||||
self._generate_dnsmasq_hosts_file(existing_host=host)
|
||||
self._allocate_cluster_host_address_for_host(host)
|
||||
|
@ -2930,6 +2988,7 @@ class ConductorManager(service.PeriodicService):
|
|||
puppet_common.puppet_apply_manifest(host.hostname,
|
||||
constants.WORKER,
|
||||
do_reboot=True)
|
||||
|
||||
return host
|
||||
|
||||
def unconfigure_ihost(self, context, ihost_obj):
|
||||
|
@ -3616,23 +3675,29 @@ class ConductorManager(service.PeriodicService):
|
|||
if set_address_interface:
|
||||
if new_interface and 'id' in new_interface:
|
||||
values = {'interface_id': new_interface['id']}
|
||||
address = cutils.get_primary_address_by_name(self.dbapi,
|
||||
cutils.format_address_name(ihost.hostname, new_interface_networktype),
|
||||
new_interface_networktype)
|
||||
if address:
|
||||
self.dbapi.address_update(address['uuid'], values)
|
||||
try:
|
||||
addr_name = cutils.format_address_name(
|
||||
ihost.hostname, new_interface_networktype)
|
||||
addresses = self.dbapi.address_get_by_name(addr_name)
|
||||
for address in addresses:
|
||||
self.dbapi.address_update(address['uuid'], values)
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
# Do any potential distributed cloud config
|
||||
# We do this here where the interface is created.
|
||||
cutils.perform_distributed_cloud_config(self.dbapi,
|
||||
new_interface['id'])
|
||||
if port:
|
||||
values = {'interface_id': port.interface_id}
|
||||
address = cutils.get_primary_address_by_name(self.dbapi,
|
||||
cutils.format_address_name(ihost.hostname, networktype),
|
||||
networktype)
|
||||
if address:
|
||||
if address['interface_id'] is None:
|
||||
self.dbapi.address_update(address['uuid'], values)
|
||||
try:
|
||||
addr_name = cutils.format_address_name(ihost.hostname,
|
||||
networktype)
|
||||
addresses = self.dbapi.address_get_by_name(addr_name)
|
||||
for address in addresses:
|
||||
if address['interface_id'] is None:
|
||||
self.dbapi.address_update(address['uuid'], values)
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
|
||||
if ihost.invprovision not in [constants.PROVISIONED, constants.PROVISIONING, constants.UPGRADING]:
|
||||
LOG.info("Updating %s host invprovision from %s to %s" %
|
||||
|
@ -12359,7 +12424,7 @@ class ConductorManager(service.PeriodicService):
|
|||
if not drbd_fs_updated:
|
||||
rc = True
|
||||
else:
|
||||
while(loop_timeout <= max_loop):
|
||||
while (loop_timeout <= max_loop):
|
||||
if constants.DRBD_PGSQL in (drbd_fs_updated - drbd_fs_resized):
|
||||
if (not standby_host or (standby_host and
|
||||
constants.DRBD_PGSQL in self._drbd_fs_sync())):
|
||||
|
|
|
@ -5154,3 +5154,11 @@ class Connection(object):
|
|||
@abc.abstractmethod
|
||||
def kube_app_bundle_destroy_by_file_path(self, file_path):
|
||||
"""Delete records from kube_app_bundle that match a file path"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_get_by_name_and_family(self, name, family):
|
||||
""" Search database address using name and family
|
||||
|
||||
:param name: address name.
|
||||
:param family: address family (4 or 6).
|
||||
"""
|
||||
|
|
|
@ -183,6 +183,14 @@ class BasePuppet(object):
|
|||
|
||||
return address
|
||||
|
||||
def _get_address_by_name_and_family(self, name, family, networktype):
|
||||
"""
|
||||
Retrieve an address entry by name and scoped by network type
|
||||
"""
|
||||
address_name = utils.format_address_name(name, networktype)
|
||||
return self.dbapi.address_get_by_name_and_family(address_name,
|
||||
family)
|
||||
|
||||
def _get_management_address(self):
|
||||
address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_MGMT)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import netaddr
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from sysinv.common import constants
|
||||
from sysinv.common import exception
|
||||
from sysinv.common import utils
|
||||
|
@ -13,6 +15,11 @@ from sysinv.common import utils
|
|||
from sysinv.puppet import base
|
||||
from sysinv.puppet import interface
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
IPv4 = constants.IP_FAMILIES[constants.IPV4_FAMILY].lower()
|
||||
IPv6 = constants.IP_FAMILIES[constants.IPV6_FAMILY].lower()
|
||||
|
||||
|
||||
class NetworkingPuppet(base.BasePuppet):
|
||||
"""Class to encapsulate puppet operations for networking configuration"""
|
||||
|
@ -49,16 +56,7 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
|
||||
config = self._get_network_config(networktype)
|
||||
|
||||
try:
|
||||
gateway_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_GATEWAY, networktype).address
|
||||
except exception.AddressNotFoundByName:
|
||||
gateway_address = None
|
||||
|
||||
config.update({
|
||||
'platform::network::%s::params::gateway_address' % networktype:
|
||||
gateway_address,
|
||||
})
|
||||
config = self._get_network_gateway_config(networktype, config)
|
||||
|
||||
# create flag for the mate controller to use FQDN or not
|
||||
if utils.is_fqdn_ready_to_use(True):
|
||||
|
@ -100,16 +98,7 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
|
||||
config = self._get_network_config(networktype)
|
||||
|
||||
try:
|
||||
gateway_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_GATEWAY, networktype).address
|
||||
except exception.AddressNotFoundByName:
|
||||
gateway_address = None
|
||||
|
||||
config.update({
|
||||
'platform::network::%s::params::gateway_address' % networktype:
|
||||
gateway_address,
|
||||
})
|
||||
config = self._get_network_gateway_config(networktype, config)
|
||||
|
||||
return config
|
||||
|
||||
|
@ -132,71 +121,125 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
try:
|
||||
network = self.dbapi.network_get_by_type(networktype)
|
||||
except exception.NetworkTypeNotFound:
|
||||
# network not configured
|
||||
LOG.debug(f"Network type {networktype} not found")
|
||||
return {}
|
||||
|
||||
address_pool = self.dbapi.address_pool_get(network.pool_uuid)
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(network.id)
|
||||
pool_uuid_list = list()
|
||||
if net_pools:
|
||||
for net_pool in net_pools:
|
||||
pool_uuid_list.append(net_pool.address_pool_uuid)
|
||||
else:
|
||||
# we are coming from an upgrade without data-migration implemented for the
|
||||
# dual stack feature
|
||||
LOG.warning(f"Network {network.name} does not have network to address pool objects")
|
||||
pool_uuid_list.append(network.pool_uuid)
|
||||
|
||||
subnet = netaddr.IPNetwork(
|
||||
str(address_pool.network) + '/' + str(address_pool.prefix))
|
||||
configdata = dict()
|
||||
config = dict()
|
||||
|
||||
subnet_version = address_pool.family
|
||||
subnet_network = str(subnet.network)
|
||||
subnet_netmask = str(subnet.netmask)
|
||||
subnet_prefixlen = subnet.prefixlen
|
||||
for pool_uuid in pool_uuid_list:
|
||||
|
||||
subnet_start = str(address_pool.ranges[0][0])
|
||||
subnet_end = str(address_pool.ranges[0][-1])
|
||||
address_pool = self.dbapi.address_pool_get(pool_uuid)
|
||||
|
||||
try:
|
||||
controller_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, networktype).address
|
||||
except exception.AddressNotFoundByName:
|
||||
controller_address = None
|
||||
family_name = IPv4 if address_pool.family == constants.IPV4_FAMILY else IPv6
|
||||
configdata.update({family_name: {}})
|
||||
|
||||
try:
|
||||
controller0_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_0_HOSTNAME, networktype).address
|
||||
except exception.AddressNotFoundByName:
|
||||
controller0_address = None
|
||||
subnet = netaddr.IPNetwork(
|
||||
str(address_pool.network) + '/' + str(address_pool.prefix))
|
||||
configdata[family_name].update({'subnet': subnet})
|
||||
|
||||
try:
|
||||
controller1_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_1_HOSTNAME, networktype).address
|
||||
except exception.AddressNotFoundByName:
|
||||
controller1_address = None
|
||||
configdata[family_name].update({'subnet_version': address_pool.family})
|
||||
configdata[family_name].update({'subnet_network': str(subnet.network)})
|
||||
configdata[family_name].update({'subnet_netmask': str(subnet.netmask)})
|
||||
configdata[family_name].update({'subnet_prefixlen': subnet.prefixlen})
|
||||
configdata[family_name].update({'subnet_start': str(address_pool.ranges[0][0])})
|
||||
configdata[family_name].update({'subnet_end': str(address_pool.ranges[0][-1])})
|
||||
|
||||
controller_address_url = self._format_url_address(controller_address)
|
||||
subnet_network_url = self._format_url_address(subnet_network)
|
||||
try:
|
||||
controller_address = self._get_address_by_name_and_family(
|
||||
constants.CONTROLLER_HOSTNAME, address_pool.family, networktype).address
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
controller_address = None
|
||||
configdata[family_name].update({'controller_address': controller_address})
|
||||
|
||||
try:
|
||||
controller0_address = self._get_address_by_name_and_family(
|
||||
constants.CONTROLLER_0_HOSTNAME, address_pool.family, networktype).address
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
controller0_address = None
|
||||
configdata[family_name].update({'controller0_address': controller0_address})
|
||||
|
||||
try:
|
||||
controller1_address = self._get_address_by_name_and_family(
|
||||
constants.CONTROLLER_1_HOSTNAME, address_pool.family, networktype).address
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
controller1_address = None
|
||||
configdata[family_name].update({'controller1_address': controller1_address})
|
||||
|
||||
configdata[family_name].update({'controller_address_url':
|
||||
self._format_url_address(controller_address)})
|
||||
configdata[family_name].update({'subnet_network_url':
|
||||
self._format_url_address(str(subnet.network))})
|
||||
|
||||
# Convert the dash to underscore because puppet parameters cannot have
|
||||
# dashes
|
||||
networktype = networktype.replace('-', '_')
|
||||
|
||||
return {
|
||||
'platform::network::%s::params::subnet_version' % networktype:
|
||||
subnet_version,
|
||||
'platform::network::%s::params::subnet_network' % networktype:
|
||||
subnet_network,
|
||||
'platform::network::%s::params::subnet_network_url' % networktype:
|
||||
subnet_network_url,
|
||||
'platform::network::%s::params::subnet_prefixlen' % networktype:
|
||||
subnet_prefixlen,
|
||||
'platform::network::%s::params::subnet_netmask' % networktype:
|
||||
subnet_netmask,
|
||||
'platform::network::%s::params::subnet_start' % networktype:
|
||||
subnet_start,
|
||||
'platform::network::%s::params::subnet_end' % networktype:
|
||||
subnet_end,
|
||||
'platform::network::%s::params::controller_address' % networktype:
|
||||
controller_address,
|
||||
'platform::network::%s::params::controller_address_url' % networktype:
|
||||
controller_address_url,
|
||||
'platform::network::%s::params::controller0_address' % networktype:
|
||||
controller0_address,
|
||||
'platform::network::%s::params::controller1_address' % networktype:
|
||||
controller1_address,
|
||||
}
|
||||
for family in configdata:
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_version'] = \
|
||||
configdata[family]['subnet_version']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_network'] = \
|
||||
configdata[family]['subnet_network']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_network_url'] = \
|
||||
configdata[family]['subnet_network_url']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_prefixlen'] = \
|
||||
configdata[family]['subnet_prefixlen']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_netmask'] = \
|
||||
configdata[family]['subnet_netmask']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_start'] = \
|
||||
configdata[family]['subnet_start']
|
||||
config[f'platform::network::{networktype}::{family}::params::subnet_end'] = \
|
||||
configdata[family]['subnet_end']
|
||||
config[f'platform::network::{networktype}::{family}::params::controller_address'] = \
|
||||
configdata[family]['controller_address']
|
||||
config[f'platform::network::{networktype}::{family}::params::controller_address_url'] = \
|
||||
configdata[family]['controller_address_url']
|
||||
config[f'platform::network::{networktype}::{family}::params::controller0_address'] = \
|
||||
configdata[family]['controller0_address']
|
||||
config[f'platform::network::{networktype}::{family}::params::controller1_address'] = \
|
||||
configdata[family]['controller1_address']
|
||||
|
||||
if network.primary_pool_family \
|
||||
and (network.primary_pool_family).lower() in configdata.keys():
|
||||
family = network.primary_pool_family.lower()
|
||||
config[f'platform::network::{networktype}::params::subnet_version'] = \
|
||||
configdata[family]['subnet_version']
|
||||
config[f'platform::network::{networktype}::params::subnet_network'] = \
|
||||
configdata[family]['subnet_network']
|
||||
config[f'platform::network::{networktype}::params::subnet_network_url'] = \
|
||||
configdata[family]['subnet_network_url']
|
||||
config[f'platform::network::{networktype}::params::subnet_prefixlen'] = \
|
||||
configdata[family]['subnet_prefixlen']
|
||||
config[f'platform::network::{networktype}::params::subnet_netmask'] = \
|
||||
configdata[family]['subnet_netmask']
|
||||
config[f'platform::network::{networktype}::params::subnet_start'] = \
|
||||
configdata[family]['subnet_start']
|
||||
config[f'platform::network::{networktype}::params::subnet_end'] = \
|
||||
configdata[family]['subnet_end']
|
||||
config[f'platform::network::{networktype}::params::controller_address'] = \
|
||||
configdata[family]['controller_address']
|
||||
config[f'platform::network::{networktype}::params::controller_address_url'] = \
|
||||
configdata[family]['controller_address_url']
|
||||
config[f'platform::network::{networktype}::params::controller0_address'] = \
|
||||
configdata[family]['controller0_address']
|
||||
config[f'platform::network::{networktype}::params::controller1_address'] = \
|
||||
configdata[family]['controller1_address']
|
||||
else:
|
||||
LOG.error(f"Network {network.name}, type {network.type} does not have a valid"
|
||||
f" primary pool address family: {network.primary_pool_family}.")
|
||||
|
||||
return config
|
||||
|
||||
def _get_pxeboot_interface_config(self):
|
||||
return self._get_interface_config(constants.NETWORK_TYPE_PXEBOOT)
|
||||
|
@ -219,6 +262,53 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
def _get_admin_interface_config(self):
|
||||
return self._get_interface_config(constants.NETWORK_TYPE_ADMIN)
|
||||
|
||||
def _get_network_gateway_config(self, networktype, config):
|
||||
try:
|
||||
network = self.dbapi.network_get_by_type(networktype)
|
||||
except exception.NetworkTypeNotFound:
|
||||
LOG.debug(f"Network type {networktype} not found")
|
||||
return {}
|
||||
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(network.id)
|
||||
pool_uuid_list = list()
|
||||
if net_pools:
|
||||
for net_pool in net_pools:
|
||||
pool_uuid_list.append(net_pool.address_pool_uuid)
|
||||
else:
|
||||
# we are coming from an upgrade without data-migration implemented for the
|
||||
# dual stack feature
|
||||
LOG.warning(f"Network {network.name} does not have network to address pool objects")
|
||||
pool_uuid_list.append(network.pool_uuid)
|
||||
|
||||
configdata = dict()
|
||||
for pool_uuid in pool_uuid_list:
|
||||
address_pool = self.dbapi.address_pool_get(pool_uuid)
|
||||
|
||||
family = IPv4 if address_pool.family == constants.IPV4_FAMILY else IPv6
|
||||
configdata.update({family: {}})
|
||||
|
||||
try:
|
||||
gateway_address = self._get_address_by_name_and_family(
|
||||
constants.CONTROLLER_GATEWAY, address_pool.family, networktype).address
|
||||
except exception.AddressNotFoundByNameAndFamily:
|
||||
gateway_address = None
|
||||
configdata[family].update({'gateway_address': gateway_address})
|
||||
|
||||
for family in configdata:
|
||||
config.update({f'platform::network::{networktype}::{family}::params::gateway_address':
|
||||
configdata[family]['gateway_address']})
|
||||
|
||||
if network.primary_pool_family \
|
||||
and (network.primary_pool_family).lower() in configdata.keys():
|
||||
family = network.primary_pool_family.lower()
|
||||
config.update({f'platform::network::{networktype}::params::gateway_address':
|
||||
configdata[family]['gateway_address']})
|
||||
else:
|
||||
LOG.error(f"Network {network.name}, type {network.type} does not have a valid"
|
||||
f" primary pool address family: {network.primary_pool_family}.")
|
||||
|
||||
return config
|
||||
|
||||
def _set_ptp_instance_global_parameters(self, ptp_instances, ptp_parameters_instance):
|
||||
|
||||
default_global_parameters = {
|
||||
|
@ -546,10 +636,9 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
self.context, network_interface)
|
||||
interface_devices = interface.get_interface_devices(
|
||||
self.context, network_interface)
|
||||
network_id = interface.find_network_id_by_networktype(
|
||||
self.context, networktype)
|
||||
# Convert the dash to underscore because puppet parameters cannot
|
||||
# have dashes
|
||||
network = self.context['networks'].get(networktype, None)
|
||||
networktype = networktype.replace('-', '_')
|
||||
config.update({
|
||||
'platform::network::%s::params::interface_name' % networktype:
|
||||
|
@ -560,13 +649,23 @@ class NetworkingPuppet(base.BasePuppet):
|
|||
network_interface.imtu
|
||||
})
|
||||
|
||||
interface_address = interface.get_interface_primary_address(
|
||||
self.context, network_interface, network_id)
|
||||
if interface_address:
|
||||
addresses = self.context['addresses'].get(network_interface['ifname'], [])
|
||||
for address in addresses:
|
||||
family = "ipv4" if address.family == constants.IPV4_FAMILY else "ipv6"
|
||||
config.update({
|
||||
'platform::network::%s::params::interface_address' %
|
||||
networktype:
|
||||
interface_address['address']
|
||||
f'platform::network::{networktype}::{family}::params::interface_address':
|
||||
address.address
|
||||
})
|
||||
|
||||
if network:
|
||||
for address in addresses:
|
||||
family = "ipv4" if address.family == constants.IPV4_FAMILY else "ipv6"
|
||||
prim_family = network.primary_pool_family.lower()
|
||||
if prim_family == family:
|
||||
config.update({
|
||||
f'platform::network::{networktype}::params::interface_address':
|
||||
address.address
|
||||
})
|
||||
break
|
||||
|
||||
return config
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import copy
|
||||
import mock
|
||||
import os.path
|
||||
import netaddr
|
||||
import subprocess
|
||||
import tempfile
|
||||
import uuid
|
||||
|
@ -5924,6 +5925,34 @@ class ManagerTestCaseInternal(base.BaseHostTestCase):
|
|||
self.service = manager.ConductorManager('test-host', 'test-topic')
|
||||
self.service.dbapi = dbapi.get_instance()
|
||||
|
||||
def _create_test_ihost(self, **kwargs):
|
||||
# ensure the system ID for proper association
|
||||
kwargs['forisystemid'] = self.system['id']
|
||||
ihost_dict = utils.get_test_ihost(**kwargs)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kwargs:
|
||||
del ihost_dict['id']
|
||||
ihost = self.service.dbapi.ihost_create(ihost_dict)
|
||||
return ihost
|
||||
|
||||
def create_ipv6_pools(self):
|
||||
mgmt_subnet6 = netaddr.IPNetwork('fd01::/64')
|
||||
oam_subnet6 = netaddr.IPNetwork('fd00::/64')
|
||||
cluster_host_subnet6 = netaddr.IPNetwork('fd02::/64')
|
||||
cluster_pod_subnet6 = netaddr.IPNetwork('fd03::/64')
|
||||
cluster_service_subnet6 = netaddr.IPNetwork('fd04::/112')
|
||||
multicast_subnet6 = netaddr.IPNetwork('ff08::1:1:0/124')
|
||||
storage_subnet6 = netaddr.IPNetwork('fd05::/64')
|
||||
admin_subnet6 = netaddr.IPNetwork('fd09::/64')
|
||||
self._create_test_address_pool(name="management-ipv6", subnet=mgmt_subnet6)
|
||||
self._create_test_address_pool(name="oam-ipv6", subnet=oam_subnet6)
|
||||
self._create_test_address_pool(name="cluster-host-ipv6", subnet=cluster_host_subnet6)
|
||||
self._create_test_address_pool(name="cluster-pod-ipv6", subnet=cluster_pod_subnet6)
|
||||
self._create_test_address_pool(name="cluster-service-ipv6", subnet=cluster_service_subnet6)
|
||||
self._create_test_address_pool(name="multicast-ipv6", subnet=multicast_subnet6)
|
||||
self._create_test_address_pool(name="storage-ipv6", subnet=storage_subnet6)
|
||||
self._create_test_address_pool(name="admin-ipv6", subnet=admin_subnet6)
|
||||
|
||||
def test_remove_lease_for_address(self):
|
||||
# create test interface
|
||||
ihost = self._create_test_host(
|
||||
|
@ -5969,3 +5998,138 @@ class ManagerTestCaseInternal(base.BaseHostTestCase):
|
|||
|
||||
self.service._remove_lease_for_address(ihost.hostname,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
def test_configure_ihost_allocate_addresses_for_host(self):
|
||||
# Test skipped to prevent error message in Jenkins. Error thrown is:
|
||||
# in test_configure_ihost_allocate_addresses_for_host
|
||||
# with open(self.dnsmasq_hosts_file, 'w') as f:
|
||||
# IOError: [Errno 13] Permission denied: '/tmp/dnsmasq.hosts'
|
||||
# self.skipTest("Skipping to prevent failure notification on Jenkins")
|
||||
|
||||
self.context = context.get_admin_context()
|
||||
self.service._generate_dnsmasq_hosts_file = mock.Mock()
|
||||
self.service._puppet = mock.Mock()
|
||||
self.service._update_pxe_config = mock.Mock()
|
||||
|
||||
# create a basic ihost object
|
||||
ihost = self._create_test_ihost()
|
||||
|
||||
self.create_ipv6_pools()
|
||||
|
||||
net_mgmt = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_MGMT)
|
||||
pool_mgmt6 = self.dbapi.address_pool_query({"name": "management-ipv6"})
|
||||
pool_mgmt4 = self.dbapi.address_pool_query({"name": "management"})
|
||||
dbutils.create_test_network_addrpool(address_pool_id=pool_mgmt6.id, network_id=net_mgmt.id)
|
||||
|
||||
net_clhost = self.dbapi.network_get_by_type(constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
pool_clhost6 = self.dbapi.address_pool_query({"name": "cluster-host-ipv6"})
|
||||
pool_clhost4 = self.dbapi.address_pool_query({"name": "cluster-host"})
|
||||
dbutils.create_test_network_addrpool(address_pool_id=pool_clhost6.id, network_id=net_clhost.id)
|
||||
|
||||
worker_name = 'newhost'
|
||||
ihost['mgmt_mac'] = '00:11:22:33:44:55'
|
||||
ihost['hostname'] = worker_name
|
||||
ihost['invprovision'] = 'unprovisioned'
|
||||
ihost['personality'] = 'worker'
|
||||
ihost['administrative'] = 'locked'
|
||||
ihost['operational'] = 'disabled'
|
||||
ihost['availability'] = 'not-installed'
|
||||
ihost['serialid'] = '1234567890abc'
|
||||
ihost['boot_device'] = 'sda'
|
||||
ihost['rootfs_device'] = 'sda'
|
||||
ihost['hw_settle'] = '0'
|
||||
ihost['install_output'] = 'text'
|
||||
ihost['console'] = 'ttyS0,115200'
|
||||
|
||||
self.service.configure_ihost(self.context, ihost)
|
||||
|
||||
addr_mgmt4 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_MGMT}",
|
||||
constants.IPV4_FAMILY)
|
||||
self.assertEqual(addr_mgmt4.pool_uuid, pool_mgmt4.uuid)
|
||||
self.assertEqual(addr_mgmt4.family, pool_mgmt4.family)
|
||||
|
||||
addr_mgmt6 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_MGMT}",
|
||||
constants.IPV6_FAMILY)
|
||||
self.assertEqual(addr_mgmt6.pool_uuid, pool_mgmt6.uuid)
|
||||
self.assertEqual(addr_mgmt6.family, pool_mgmt6.family)
|
||||
|
||||
addr_clhost4 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_CLUSTER_HOST}",
|
||||
constants.IPV4_FAMILY)
|
||||
self.assertEqual(addr_clhost4.pool_uuid, pool_clhost4.uuid)
|
||||
|
||||
addr_clhost6 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_CLUSTER_HOST}",
|
||||
constants.IPV6_FAMILY)
|
||||
self.assertEqual(addr_clhost6.pool_uuid, pool_clhost6.uuid)
|
||||
|
||||
def test_configure_ihost_allocate_addresses_for_host_no_net_pool_object(self):
|
||||
# the data-migration for upgrade was not implemented yet for the dual-stack feature
|
||||
# this test aims to validate this condition
|
||||
# self.skipTest("Skipping to prevent failure notification on Jenkins")
|
||||
|
||||
self.context = context.get_admin_context()
|
||||
self.service._generate_dnsmasq_hosts_file = mock.Mock()
|
||||
self.service._puppet = mock.Mock()
|
||||
self.service._update_pxe_config = mock.Mock()
|
||||
|
||||
# create a basic ihost object
|
||||
ihost = self._create_test_ihost()
|
||||
|
||||
self.create_ipv6_pools()
|
||||
|
||||
pool_mgmt4 = self.dbapi.address_pool_query({"name": "management"})
|
||||
pool_clhost4 = self.dbapi.address_pool_query({"name": "cluster-host"})
|
||||
net_pools = self.dbapi.network_addrpool_get_all()
|
||||
for net_pool in net_pools:
|
||||
self.dbapi.network_addrpool_destroy(net_pool.uuid)
|
||||
|
||||
worker_name = 'newhost'
|
||||
ihost['mgmt_mac'] = '00:11:22:33:44:55'
|
||||
ihost['hostname'] = worker_name
|
||||
ihost['invprovision'] = 'unprovisioned'
|
||||
ihost['personality'] = 'worker'
|
||||
ihost['administrative'] = 'locked'
|
||||
ihost['operational'] = 'disabled'
|
||||
ihost['availability'] = 'not-installed'
|
||||
ihost['serialid'] = '1234567890abc'
|
||||
ihost['boot_device'] = 'sda'
|
||||
ihost['rootfs_device'] = 'sda'
|
||||
ihost['hw_settle'] = '0'
|
||||
ihost['install_output'] = 'text'
|
||||
ihost['console'] = 'ttyS0,115200'
|
||||
|
||||
self.assertRaises(exception.AddressNotFoundByNameAndFamily,
|
||||
self.dbapi.address_get_by_name_and_family,
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_MGMT}",
|
||||
constants.IPV4_FAMILY)
|
||||
|
||||
self.assertRaises(exception.AddressNotFoundByNameAndFamily,
|
||||
self.dbapi.address_get_by_name_and_family,
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_CLUSTER_HOST}",
|
||||
constants.IPV6_FAMILY)
|
||||
|
||||
self.service.configure_ihost(self.context, ihost)
|
||||
|
||||
addr_mgmt4 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_MGMT}",
|
||||
constants.IPV4_FAMILY)
|
||||
self.assertEqual(addr_mgmt4.pool_uuid, pool_mgmt4.uuid)
|
||||
self.assertEqual(addr_mgmt4.family, pool_mgmt4.family)
|
||||
|
||||
self.assertRaises(exception.AddressNotFoundByNameAndFamily,
|
||||
self.dbapi.address_get_by_name_and_family,
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_MGMT}",
|
||||
constants.IPV6_FAMILY)
|
||||
|
||||
addr_clhost4 = self.dbapi.address_get_by_name_and_family(
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_CLUSTER_HOST}",
|
||||
constants.IPV4_FAMILY)
|
||||
self.assertEqual(addr_clhost4.pool_uuid, pool_clhost4.uuid)
|
||||
|
||||
self.assertRaises(exception.AddressNotFoundByNameAndFamily,
|
||||
self.dbapi.address_get_by_name_and_family,
|
||||
f"{worker_name}-{constants.NETWORK_TYPE_CLUSTER_HOST}",
|
||||
constants.IPV6_FAMILY)
|
||||
|
|
|
@ -0,0 +1,677 @@
|
|||
# Copyright (c) 2024 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import uuid
|
||||
import os
|
||||
import yaml
|
||||
|
||||
import netaddr
|
||||
from sysinv.tests.puppet import base
|
||||
from sysinv.puppet import puppet
|
||||
from sysinv.tests.db import base as dbbase
|
||||
from sysinv.common import constants
|
||||
from sysinv.tests.db import utils as dbutils
|
||||
from sysinv.db import api as db_api
|
||||
|
||||
|
||||
class NetworkingTestCaseMixin(base.PuppetTestCaseMixin):
|
||||
""" This PlatformFirewallTestCaseMixin needs to be used with a subclass
|
||||
of BaseHostTestCase
|
||||
"""
|
||||
@puppet.puppet_context
|
||||
def _update_context(self):
|
||||
# interface is added as an operator by systemconfig.puppet_plugins
|
||||
self.context = self.operator.interface._create_interface_context(self.host) # pylint: disable=no-member
|
||||
|
||||
# Update the puppet context with generated interface context
|
||||
self.operator.context.update(self.context)
|
||||
|
||||
def _setup_context(self):
|
||||
self.ports = []
|
||||
self.interfaces = []
|
||||
self.addresses = []
|
||||
self.routes = []
|
||||
self._setup_configuration()
|
||||
self._update_context()
|
||||
|
||||
def _setup_configuration(self):
|
||||
pass
|
||||
|
||||
def _create_hieradata_directory(self):
|
||||
hiera_path = os.path.join(os.environ['VIRTUAL_ENV'], 'hieradata')
|
||||
if not os.path.exists(hiera_path):
|
||||
os.mkdir(hiera_path, 0o755)
|
||||
return hiera_path
|
||||
|
||||
def _get_config_filename(self, hiera_directory):
|
||||
class_name = self.__class__.__name__
|
||||
return os.path.join(hiera_directory, class_name) + ".yaml"
|
||||
|
||||
def _find_network_by_type(self, networktype):
|
||||
for network in self.networks:
|
||||
if network['type'] == networktype:
|
||||
return network
|
||||
|
||||
def _get_network_ids_by_type(self, networktype):
|
||||
if isinstance(networktype, list):
|
||||
networktypelist = networktype
|
||||
elif networktype:
|
||||
networktypelist = [networktype]
|
||||
else:
|
||||
networktypelist = []
|
||||
networks = []
|
||||
for network_type in networktypelist:
|
||||
network = self._find_network_by_type(network_type)
|
||||
networks.append(str(network['id']))
|
||||
return networks
|
||||
|
||||
def _create_ethernet_test(self, ifname=None, ifclass=None,
|
||||
networktype=None, host_id=None, **kwargs):
|
||||
if not host_id:
|
||||
host_id = self.host.id
|
||||
interface_id = len(self.interfaces)
|
||||
if not ifname:
|
||||
ifname = (networktype or 'eth') + str(interface_id)
|
||||
if not ifclass:
|
||||
ifclass = constants.INTERFACE_CLASS_NONE
|
||||
if ifclass == constants.INTERFACE_CLASS_PLATFORM:
|
||||
networks = self._get_network_ids_by_type(networktype)
|
||||
else:
|
||||
networks = []
|
||||
interface = {'id': interface_id,
|
||||
'uuid': str(uuid.uuid4()),
|
||||
'forihostid': host_id,
|
||||
'ifname': ifname,
|
||||
'iftype': constants.INTERFACE_TYPE_ETHERNET,
|
||||
'imac': '02:11:22:33:44:' + str(10 + interface_id),
|
||||
'uses': [],
|
||||
'used_by': [],
|
||||
'ifclass': ifclass,
|
||||
'networks': networks,
|
||||
'networktype': networktype,
|
||||
'imtu': 1500,
|
||||
'sriov_numvfs': kwargs.get('sriov_numvfs', 0),
|
||||
'sriov_vf_driver': kwargs.get('iface_sriov_vf_driver', None)}
|
||||
db_interface = dbutils.create_test_interface(**interface)
|
||||
for network in networks:
|
||||
dbutils.create_test_interface_network_assign(db_interface['id'], network)
|
||||
self.interfaces.append(db_interface)
|
||||
|
||||
port_id = len(self.ports)
|
||||
port = {'id': port_id,
|
||||
'uuid': str(uuid.uuid4()),
|
||||
'name': 'eth' + str(port_id),
|
||||
'interface_id': interface_id,
|
||||
'host_id': host_id,
|
||||
'mac': interface['imac'],
|
||||
'driver': kwargs.get('driver', 'ixgbe'),
|
||||
'dpdksupport': kwargs.get('dpdksupport', True),
|
||||
'pdevice': kwargs.get('pdevice',
|
||||
"Ethernet Controller X710 for 10GbE SFP+ [1572]"),
|
||||
'pciaddr': kwargs.get('pciaddr',
|
||||
'0000:00:00.' + str(port_id + 1)),
|
||||
'dev_id': kwargs.get('dev_id', 0),
|
||||
'sriov_vf_driver': kwargs.get('port_sriov_vf_driver', None),
|
||||
'sriov_vf_pdevice_id': kwargs.get('sriov_vf_pdevice_id', None),
|
||||
'sriov_vfs_pci_address': kwargs.get('sriov_vfs_pci_address', '')}
|
||||
db_port = dbutils.create_test_ethernet_port(**port)
|
||||
self.ports.append(db_port)
|
||||
return db_port, db_interface
|
||||
|
||||
|
||||
class NetworkingTestTestCaseControllerDualStackIPv4Primary(NetworkingTestCaseMixin,
|
||||
dbbase.BaseHostTestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv4Primary, self).__init__(*args, **kwargs)
|
||||
self.test_interfaces = dict()
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv4Primary, self).setUp()
|
||||
self.dbapi = db_api.get_instance()
|
||||
self._setup_context()
|
||||
|
||||
def _update_context(self):
|
||||
# ensure DB entries are updated prior to updating the context which
|
||||
# will re-read the entries from the DB.
|
||||
|
||||
self.host.save(self.admin_context)
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv4Primary, self)._update_context()
|
||||
|
||||
def _setup_configuration(self):
|
||||
# Create a single port/interface for basic function testing
|
||||
print("=== _setup_configuration")
|
||||
self.host = self._create_test_host(personality=constants.CONTROLLER)
|
||||
|
||||
_, c0_oam = self._create_ethernet_test("oam0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_OAM, self.host.id)
|
||||
|
||||
_, c0_mgmt = self._create_ethernet_test("mgmt0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_MGMT, self.host.id)
|
||||
|
||||
_, c0_clhost = self._create_ethernet_test("cluster0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, self.host.id)
|
||||
|
||||
_, c0_pxe = self._create_ethernet_test("pxe0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_PXEBOOT, self.host.id)
|
||||
|
||||
self.host_c1 = self._create_test_host(personality=constants.CONTROLLER,
|
||||
unit=1)
|
||||
|
||||
port, c1_oam = self._create_ethernet_test("oam0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_OAM, self.host_c1.id)
|
||||
|
||||
port, c1_mgmt = self._create_ethernet_test("mgmt0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_MGMT, self.host_c1.id)
|
||||
|
||||
port, c1_clhost = self._create_ethernet_test("cluster0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, self.host_c1.id)
|
||||
|
||||
port, c1_pxe = self._create_ethernet_test("pxe0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_PXEBOOT, self.host_c1.id)
|
||||
|
||||
self.create_ipv6_pools()
|
||||
|
||||
# associate addresses with its interfaces
|
||||
addresses = self.dbapi.addresses_get_all()
|
||||
for addr in addresses:
|
||||
for hostname in [self.host.hostname, self.host_c1.hostname]:
|
||||
if addr.name == f"{hostname}-{constants.NETWORK_TYPE_OAM}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_oam.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_oam.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_MGMT}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_mgmt.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_mgmt.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_CLUSTER_HOST}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_clhost.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_clhost.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_PXEBOOT}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_pxe.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_pxe.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
|
||||
# associate addresses with its pools
|
||||
for net_type in [constants.NETWORK_TYPE_OAM,
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT]:
|
||||
net = self.dbapi.network_get_by_type(net_type)
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(net.id)
|
||||
for net_pool in net_pools:
|
||||
address_pool = self.dbapi.address_pool_get(net_pool.address_pool_uuid)
|
||||
addresses = self.dbapi.addresses_get_all()
|
||||
for addr in addresses:
|
||||
if (addr.name.endswith(f"-{net_type}")) \
|
||||
and (addr.family == address_pool.family):
|
||||
values = {'address_pool_id': address_pool.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
|
||||
def create_ipv6_pools(self):
|
||||
to_add = [
|
||||
(constants.NETWORK_TYPE_MGMT, (netaddr.IPNetwork('fd01::/64'),
|
||||
'management-ipv6')),
|
||||
(constants.NETWORK_TYPE_OAM, (netaddr.IPNetwork('fd00::/64'),
|
||||
'oam-ipv6')),
|
||||
(constants.NETWORK_TYPE_ADMIN, (netaddr.IPNetwork('fd09::/64'),
|
||||
'admin-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_HOST, (netaddr.IPNetwork('fd03::/64'),
|
||||
'cluster-host-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_POD, (netaddr.IPNetwork('fd03::/64'),
|
||||
'cluster-pod-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_SERVICE, (netaddr.IPNetwork('fd04::/112'),
|
||||
'cluster-service-ipv6')),
|
||||
(constants.NETWORK_TYPE_STORAGE, (netaddr.IPNetwork('fd05::/64'),
|
||||
'storage-ipv6'))
|
||||
]
|
||||
|
||||
hosts = [constants.CONTROLLER_HOSTNAME,
|
||||
constants.CONTROLLER_0_HOSTNAME,
|
||||
constants.CONTROLLER_1_HOSTNAME]
|
||||
|
||||
for cfgdata in to_add:
|
||||
net = self.dbapi.network_get_by_type(cfgdata[0])
|
||||
pool = self._create_test_address_pool(name=cfgdata[1][1],
|
||||
subnet=cfgdata[1][0])
|
||||
network_addrpool = dbutils.create_test_network_addrpool(address_pool_id=pool.id,
|
||||
network_id=net.id)
|
||||
self._create_test_addresses(hostnames=hosts, subnet=cfgdata[1][0],
|
||||
network_type=cfgdata[0], start=2)
|
||||
if cfgdata[0] in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_OAM]:
|
||||
self._create_test_addresses(hostnames=[constants.CONTROLLER_GATEWAY],
|
||||
subnet=cfgdata[1][0],
|
||||
network_type=cfgdata[0], start=1, stop=2)
|
||||
self.network_addrpools.append(network_addrpool)
|
||||
|
||||
def test_generate_networking_host_config(self):
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_host_config(self.host) # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv4', 'ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["interface_address"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::interface_address'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["interface_address", "interface_devices", "interface_name", "mtu"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# ipv4 is the primary, chack the addresses match
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
self.assertEqual(hiera_data[f'platform::network::{type}::params::interface_address'],
|
||||
hiera_data[f'platform::network::{type}::ipv4::params::interface_address'])
|
||||
|
||||
def test_generate_networking_system_config(self):
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_system_config() # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv4', 'ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::{field}'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check the primary pool (no family indication) presence
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check if the the primary pool subnet_version is with the correct value
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertEqual(constants.IPV4_FAMILY, hiera_data[test_key])
|
||||
|
||||
|
||||
class NetworkingTestTestCaseControllerDualStackIPv6Primary(NetworkingTestCaseMixin,
|
||||
dbbase.BaseIPv6Mixin,
|
||||
dbbase.BaseHostTestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv6Primary, self).__init__(*args, **kwargs)
|
||||
self.test_interfaces = dict()
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv6Primary, self).setUp()
|
||||
self.dbapi = db_api.get_instance()
|
||||
self._setup_context()
|
||||
|
||||
def _update_context(self):
|
||||
# ensure DB entries are updated prior to updating the context which
|
||||
# will re-read the entries from the DB.
|
||||
|
||||
self.host.save(self.admin_context)
|
||||
super(NetworkingTestTestCaseControllerDualStackIPv6Primary, self)._update_context()
|
||||
|
||||
def create_ipv4_pools(self):
|
||||
|
||||
to_add = [
|
||||
(constants.NETWORK_TYPE_MGMT, (netaddr.IPNetwork('192.168.204.0/24'),
|
||||
'management-ipv4')),
|
||||
(constants.NETWORK_TYPE_OAM, (netaddr.IPNetwork('10.10.10.0/24'),
|
||||
'oam-ipv4')),
|
||||
(constants.NETWORK_TYPE_ADMIN, (netaddr.IPNetwork('10.10.30.0/24'),
|
||||
'admin-ipv4')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_HOST, (netaddr.IPNetwork('192.168.206.0/24'),
|
||||
'cluster-host-ipv4')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_POD, (netaddr.IPNetwork('172.16.0.0/16'),
|
||||
'cluster-pod-ipv4')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_SERVICE, (netaddr.IPNetwork('10.96.0.0/12'),
|
||||
'cluster-service-ipv4')),
|
||||
(constants.NETWORK_TYPE_STORAGE, (netaddr.IPNetwork('10.10.20.0/24'),
|
||||
'storage-ipv4'))
|
||||
]
|
||||
|
||||
hosts = [constants.CONTROLLER_HOSTNAME,
|
||||
constants.CONTROLLER_0_HOSTNAME,
|
||||
constants.CONTROLLER_1_HOSTNAME]
|
||||
|
||||
for cfgdata in to_add:
|
||||
net = self.dbapi.network_get_by_type(cfgdata[0])
|
||||
pool = self._create_test_address_pool(name=cfgdata[1][1],
|
||||
subnet=cfgdata[1][0])
|
||||
network_addrpool = dbutils.create_test_network_addrpool(address_pool_id=pool.id,
|
||||
network_id=net.id)
|
||||
self._create_test_addresses(hostnames=hosts, subnet=cfgdata[1][0],
|
||||
network_type=cfgdata[0], start=2)
|
||||
if cfgdata[0] in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_OAM]:
|
||||
self._create_test_addresses(hostnames=[constants.CONTROLLER_GATEWAY],
|
||||
subnet=cfgdata[1][0],
|
||||
network_type=cfgdata[0], start=1, stop=2)
|
||||
self.network_addrpools.append(network_addrpool)
|
||||
|
||||
def _setup_configuration(self):
|
||||
self.host = self._create_test_host(personality=constants.CONTROLLER)
|
||||
|
||||
_, c0_oam = self._create_ethernet_test("oam0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_OAM, self.host.id)
|
||||
|
||||
_, c0_mgmt = self._create_ethernet_test("mgmt0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_MGMT, self.host.id)
|
||||
|
||||
_, c0_clhost = self._create_ethernet_test("cluster0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, self.host.id)
|
||||
|
||||
_, c0_pxe = self._create_ethernet_test("pxe0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_PXEBOOT, self.host.id)
|
||||
|
||||
self.host_c1 = self._create_test_host(personality=constants.CONTROLLER,
|
||||
unit=1)
|
||||
|
||||
_, c1_oam = self._create_ethernet_test("oam0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_OAM, self.host_c1.id)
|
||||
|
||||
_, c1_mgmt = self._create_ethernet_test("mgmt0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_MGMT, self.host_c1.id)
|
||||
|
||||
_, c1_clhost = self._create_ethernet_test("cluster0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, self.host_c1.id)
|
||||
|
||||
_, c1_pxe = self._create_ethernet_test("pxe0",
|
||||
constants.INTERFACE_CLASS_PLATFORM,
|
||||
constants.NETWORK_TYPE_PXEBOOT, self.host_c1.id)
|
||||
|
||||
self.create_ipv4_pools()
|
||||
|
||||
# associate addresses with its interfaces
|
||||
addresses = self.dbapi.addresses_get_all()
|
||||
for addr in addresses:
|
||||
for hostname in [self.host.hostname, self.host_c1.hostname]:
|
||||
if addr.name == f"{hostname}-{constants.NETWORK_TYPE_OAM}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_oam.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_oam.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_MGMT}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_mgmt.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_mgmt.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_CLUSTER_HOST}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_clhost.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_clhost.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif addr.name == f"{hostname}-{constants.NETWORK_TYPE_PXEBOOT}":
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
values = {'interface_id': c0_pxe.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
elif hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
values = {'interface_id': c1_pxe.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
|
||||
# associate addresses with its pools
|
||||
for net_type in [constants.NETWORK_TYPE_OAM,
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT]:
|
||||
net = self.dbapi.network_get_by_type(net_type)
|
||||
net_pools = self.dbapi.network_addrpool_get_by_network_id(net.id)
|
||||
for net_pool in net_pools:
|
||||
address_pool = self.dbapi.address_pool_get(net_pool.address_pool_uuid)
|
||||
addresses = self.dbapi.addresses_get_all()
|
||||
for addr in addresses:
|
||||
if (addr.name.endswith(f"-{net_type}")) \
|
||||
and (addr.family == address_pool.family):
|
||||
values = {'address_pool_id': address_pool.id}
|
||||
self.dbapi.address_update(addr.uuid, values)
|
||||
|
||||
def test_generate_networking_system_config(self):
|
||||
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_system_config() # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv4', 'ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::{field}'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check the primary pool (no family indication) presence
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check if the the primary pool subnet_version is with the correct value
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertEqual(constants.IPV6_FAMILY, hiera_data[test_key])
|
||||
|
||||
def test_generate_networking_system_config_no_net_pool_object(self):
|
||||
"""This test aims to validate if a system can operate without network-addrpool
|
||||
objects since this can happen if an upgrade is executed and the data-migration
|
||||
for the diual-stack feature is not implemented yet;
|
||||
"""
|
||||
|
||||
net_pools = self.dbapi.network_addrpool_get_all()
|
||||
for net_pool in net_pools:
|
||||
self.dbapi.network_addrpool_destroy(net_pool.uuid)
|
||||
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_system_config() # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::{field}'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check the primary pool (no family indication) presence
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["controller0_address", "controller1_address", "controller_address",
|
||||
"controller_address_url", "subnet_end", "subnet_netmask", "subnet_network",
|
||||
"subnet_network_url", "subnet_prefixlen", "subnet_start", "subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# check if the the primary pool subnet_version is with the correct value
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_ADMIN,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_STORAGE, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["subnet_version"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertEqual(constants.IPV6_FAMILY, hiera_data[test_key])
|
||||
|
||||
def test_generate_networking_host_config(self):
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_host_config(self.host) # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv4', 'ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["interface_address"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::interface_address'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["interface_address", "interface_devices", "interface_name", "mtu"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# ipv6 is the primary, check the addresses match
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
self.assertEqual(hiera_data[f'platform::network::{type}::params::interface_address'],
|
||||
hiera_data[f'platform::network::{type}::ipv6::params::interface_address'])
|
||||
|
||||
def test_generate_networking_host_config_no_net_pool_objects(self):
|
||||
"""This test aims to validate if a system can operate without network-addrpool
|
||||
objects since this can happen if an upgrade is executed and the data-migration
|
||||
for the diual-stack feature is not implemented yet;
|
||||
"""
|
||||
|
||||
net_pools = self.dbapi.network_addrpool_get_all()
|
||||
for net_pool in net_pools:
|
||||
self.dbapi.network_addrpool_destroy(net_pool.uuid)
|
||||
|
||||
hieradata_directory = self._create_hieradata_directory()
|
||||
config_filename = self._get_config_filename(hieradata_directory)
|
||||
with open(config_filename, 'w') as config_file:
|
||||
config = self.operator.networking.get_host_config(self.host) # pylint: disable=no-member
|
||||
yaml.dump(config, config_file, default_flow_style=False)
|
||||
print(config_filename)
|
||||
|
||||
hiera_data = dict()
|
||||
with open(config_filename, 'r') as config_file:
|
||||
hiera_data = yaml.safe_load(config_file)
|
||||
|
||||
for family in ['ipv4', 'ipv6']:
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
type = net_type.replace('-', '_')
|
||||
for field in ["interface_address"]:
|
||||
test_key = f'platform::network::{type}::{family}::params::interface_address'
|
||||
if net_type == constants.NETWORK_TYPE_PXEBOOT and family == 'ipv6':
|
||||
# there are no ipv6 allocations for pxe
|
||||
self.assertNotIn(test_key, hiera_data.keys())
|
||||
else:
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
for field in ["interface_address", "interface_devices", "interface_name", "mtu"]:
|
||||
test_key = f'platform::network::{type}::params::{field}'
|
||||
self.assertIn(test_key, hiera_data.keys())
|
||||
|
||||
# ipv6 is the primary, check the addresses match
|
||||
for net_type in [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_PXEBOOT, constants.NETWORK_TYPE_OAM]:
|
||||
self.assertEqual(hiera_data[f'platform::network::{type}::params::interface_address'],
|
||||
hiera_data[f'platform::network::{type}::ipv6::params::interface_address'])
|
Loading…
Reference in New Issue