config/configutilities/configutilities/configutilities/common/configobjects.py
Teresa Ho 949bab37d7 Kubernetes Cluster Network Configuration
The Kubernetes cluster network is introduced and configurable.
The cluster-host interface can be configured on any interface of the
host and is defaulted to the management interface if it is not
specified.
The infrastructure network is no longer used in kubernetes config.
SM and MTCE are setup to monitor the cluster-host if kubernetes is
enabled.
Nova live migration ip is set to use the cluster-host ip.

Tests Performed:
Containerized setup:
AIO-SX: mgmt and cluster-host shared loopback interface
AIO-DX: mgmt and cluster-host shared an interface
AIO-DX: mgmt and cluster-host on different interface
Standard 2+2+2: mgmt and cluster-host shared an interface
Standard 2+2+2: mgmt and cluster-host on different interface
For each of the setup, launch VM and connect to VM console

Non-containerized deployments
AIO-SX sanity
AIO-DX sanity
Standard 2+2 sanity

Story: 2004273
Task: 27826

Change-Id: If6b918665131f01bc62687fbdc7978c5c103e3b7
Signed-off-by: Teresa Ho <teresa.ho@windriver.com>
2019-01-09 12:41:25 -05:00

374 lines
16 KiB
Python

"""
Copyright (c) 2015-2016 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
from netaddr import IPRange
from configutilities.common.exceptions import ConfigFail
from configutilities.common.exceptions import ValidateFail
from configutilities.common.utils import is_mtu_valid
from configutilities.common.utils import is_valid_vlan
from configutilities.common.utils import validate_network_str
from configutilities.common.utils import validate_address_str
DEFAULT_CONFIG = 0
REGION_CONFIG = 1
SUBCLOUD_CONFIG = 2
MGMT_TYPE = 0
INFRA_TYPE = 1
OAM_TYPE = 2
CLUSTER_TYPE = 3
NETWORK_PREFIX_NAMES = [
('MGMT', 'INFRA', 'OAM', 'CLUSTER'),
('CLM', 'BLS', 'CAN', 'CLUSTER')
]
# Additions to this list must be reflected in the hostfile
# generator tool (config->configutilities->hostfiletool.py)
HOST_XML_ATTRIBUTES = ['hostname', 'personality', 'subfunctions',
'mgmt_mac', 'mgmt_ip',
'bm_ip', 'bm_type', 'bm_username',
'bm_password', 'boot_device', 'rootfs_device',
'install_output', 'console', 'vsc_controllers',
'power_on', 'location']
# Network naming types
DEFAULT_NAMES = 0
HP_NAMES = 1
# well-known default domain name
DEFAULT_DOMAIN_NAME = 'Default'
class LogicalInterface(object):
""" Represents configuration for a logical interface.
"""
def __init__(self):
self.name = None
self.mtu = None
self.lag_interface = False
self.lag_mode = None
self.ports = None
def parse_config(self, system_config, logical_interface):
# Ensure logical interface config is present
if not system_config.has_section(logical_interface):
raise ConfigFail("Missing config for logical interface %s." %
logical_interface)
self.name = logical_interface
# Parse/validate the MTU
self.mtu = system_config.getint(logical_interface, 'INTERFACE_MTU')
if not is_mtu_valid(self.mtu):
raise ConfigFail("Invalid MTU value for %s. "
"Valid values: 576 - 9216" % logical_interface)
# Parse the ports
self.ports = [_f for _f in
[x.strip() for x in
system_config.get(logical_interface,
'INTERFACE_PORTS').split(',')]
if _f]
# Parse/validate the LAG config
lag_interface = system_config.get(logical_interface,
'LAG_INTERFACE')
if lag_interface.lower() == 'y':
self.lag_interface = True
if len(self.ports) != 2:
raise ConfigFail(
"Invalid number of ports (%d) supplied for LAG "
"interface %s" % (len(self.ports), logical_interface))
self.lag_mode = system_config.getint(logical_interface, 'LAG_MODE')
if self.lag_mode < 1 or self.lag_mode > 6:
raise ConfigFail(
"Invalid LAG_MODE value of %d for %s. Valid values: 1-6" %
(self.lag_mode, logical_interface))
elif lag_interface.lower() == 'n':
if len(self.ports) > 1:
raise ConfigFail(
"More than one interface supplied for non-LAG "
"interface %s" % logical_interface)
if len(self.ports) == 0:
raise ConfigFail(
"No interfaces supplied for non-LAG "
"interface %s" % logical_interface)
else:
raise ConfigFail(
"Invalid LAG_INTERFACE value of %s for %s. Valid values: "
"Y or N" % (lag_interface, logical_interface))
class Network(object):
""" Represents configuration for a network.
"""
def __init__(self):
self.vlan = None
self.cidr = None
self.multicast_cidr = None
self.start_address = None
self.end_address = None
self.start_end_in_config = False
self.floating_address = None
self.address_0 = None
self.address_1 = None
self.dynamic_allocation = False
self.gateway_address = None
self.logical_interface = None
def parse_config(self, system_config, config_type, network_type,
min_addresses=0, multicast_addresses=0, optional=False,
naming_type=DEFAULT_NAMES,
logical_interface_required=True):
network_prefix = NETWORK_PREFIX_NAMES[naming_type][network_type]
network_name = network_prefix + '_NETWORK'
if naming_type == HP_NAMES:
attr_prefix = network_prefix + '_'
else:
attr_prefix = ''
# Ensure network config is present
if not system_config.has_section(network_name):
if not optional:
raise ConfigFail("Missing config for network %s." %
network_name)
else:
# Optional interface - just return
return
# Parse/validate the VLAN
if system_config.has_option(network_name, attr_prefix + 'VLAN'):
self.vlan = system_config.getint(network_name,
attr_prefix + 'VLAN')
if self.vlan:
if not is_valid_vlan(self.vlan):
raise ConfigFail(
"Invalid %s value of %d for %s. Valid values: 1-4094" %
(attr_prefix + 'VLAN', self.vlan, network_name))
# Parse/validate the cidr
cidr_str = system_config.get(network_name, attr_prefix + 'CIDR')
try:
self.cidr = validate_network_str(
cidr_str, min_addresses)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'CIDR', cidr_str, network_name, e))
# Parse/validate the multicast subnet
if 0 < multicast_addresses and \
system_config.has_option(network_name,
attr_prefix + 'MULTICAST_CIDR'):
multicast_cidr_str = system_config.get(network_name, attr_prefix +
'MULTICAST_CIDR')
try:
self.multicast_cidr = validate_network_str(
multicast_cidr_str, multicast_addresses, multicast=True)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'MULTICAST_CIDR', multicast_cidr_str,
network_name, e))
if self.cidr.version != self.multicast_cidr.version:
raise ConfigFail(
"Invalid %s value of %s for %s. Multicast "
"subnet and network IP families must be the same." %
(attr_prefix + 'MULTICAST_CIDR', multicast_cidr_str,
network_name))
# Parse/validate the hardwired controller addresses
floating_address_str = None
address_0_str = None
address_1_str = None
if min_addresses == 1:
if (system_config.has_option(
network_name, attr_prefix + 'IP_FLOATING_ADDRESS') or
system_config.has_option(
network_name, attr_prefix + 'IP_UNIT_0_ADDRESS') or
system_config.has_option(
network_name, attr_prefix + 'IP_UNIT_1_ADDRESS') or
system_config.has_option(
network_name, attr_prefix + 'IP_START_ADDRESS') or
system_config.has_option(
network_name, attr_prefix + 'IP_END_ADDRESS')):
raise ConfigFail(
"Only one IP address is required for OAM "
"network, use 'IP_ADDRESS' to specify the OAM IP "
"address")
floating_address_str = system_config.get(
network_name, attr_prefix + 'IP_ADDRESS')
try:
self.floating_address = validate_address_str(
floating_address_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'IP_ADDRESS',
floating_address_str, network_name, e))
self.address_0 = self.floating_address
self.address_1 = self.floating_address
else:
if system_config.has_option(
network_name, attr_prefix + 'IP_FLOATING_ADDRESS'):
floating_address_str = system_config.get(
network_name, attr_prefix + 'IP_FLOATING_ADDRESS')
try:
self.floating_address = validate_address_str(
floating_address_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'IP_FLOATING_ADDRESS',
floating_address_str, network_name, e))
if system_config.has_option(
network_name, attr_prefix + 'IP_UNIT_0_ADDRESS'):
address_0_str = system_config.get(
network_name, attr_prefix + 'IP_UNIT_0_ADDRESS')
try:
self.address_0 = validate_address_str(
address_0_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'IP_UNIT_0_ADDRESS',
address_0_str, network_name, e))
if system_config.has_option(
network_name, attr_prefix + 'IP_UNIT_1_ADDRESS'):
address_1_str = system_config.get(
network_name, attr_prefix + 'IP_UNIT_1_ADDRESS')
try:
self.address_1 = validate_address_str(
address_1_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'IP_UNIT_1_ADDRESS',
address_1_str, network_name, e))
# Parse/validate the start/end addresses
start_address_str = None
end_address_str = None
if system_config.has_option(
network_name, attr_prefix + 'IP_START_ADDRESS'):
start_address_str = system_config.get(
network_name, attr_prefix + 'IP_START_ADDRESS')
try:
self.start_address = validate_address_str(
start_address_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'IP_START_ADDRESS',
start_address_str, network_name, e))
if system_config.has_option(
network_name, attr_prefix + 'IP_END_ADDRESS'):
end_address_str = system_config.get(
network_name, attr_prefix + 'IP_END_ADDRESS')
try:
self.end_address = validate_address_str(
end_address_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s " %
(attr_prefix + 'IP_END_ADDRESS',
end_address_str, network_name, e))
if start_address_str or end_address_str:
if not end_address_str:
raise ConfigFail("Missing attribute %s for %s_NETWORK" %
(attr_prefix + 'IP_END_ADDRESS',
network_name))
if not start_address_str:
raise ConfigFail("Missing attribute %s for %s_NETWORK" %
(attr_prefix + 'IP_START_ADDRESS',
network_name))
if not self.start_address < self.end_address:
raise ConfigFail(
"Start address %s not less than end address %s for %s."
% (str(self.start_address), str(self.end_address),
network_name))
if not IPRange(start_address_str, end_address_str).size >= \
min_addresses:
raise ConfigFail("Address range for %s must contain at "
"least %d addresses." %
(network_name, min_addresses))
self.start_end_in_config = True
if floating_address_str or address_0_str or address_1_str:
if not floating_address_str:
raise ConfigFail("Missing attribute %s for %s_NETWORK" %
(attr_prefix + 'IP_FLOATING_ADDRESS',
network_name))
if not address_0_str:
raise ConfigFail("Missing attribute %s for %s_NETWORK" %
(attr_prefix + 'IP_UNIT_0_ADDRESS',
network_name))
if not address_1_str:
raise ConfigFail("Missing attribute %s for %s_NETWORK" %
(attr_prefix + 'IP_UNIT_1_ADDRESS',
network_name))
if start_address_str and floating_address_str:
raise ConfigFail("Overspecified network: Can only set %s "
"and %s OR %s, %s, and %s for "
"%s_NETWORK" %
(attr_prefix + 'IP_START_ADDRESS',
attr_prefix + 'IP_END_ADDRESS',
attr_prefix + 'IP_FLOATING_ADDRESS',
attr_prefix + 'IP_UNIT_0_ADDRESS',
attr_prefix + 'IP_UNIT_1_ADDRESS',
network_name))
if config_type == DEFAULT_CONFIG:
if not self.start_address:
self.start_address = self.cidr[2]
if not self.end_address:
self.end_address = self.cidr[-2]
# Parse/validate the dynamic IP address allocation
if system_config.has_option(network_name,
'DYNAMIC_ALLOCATION'):
dynamic_allocation = system_config.get(network_name,
'DYNAMIC_ALLOCATION')
if dynamic_allocation.lower() == 'y':
self.dynamic_allocation = True
elif dynamic_allocation.lower() == 'n':
self.dynamic_allocation = False
else:
raise ConfigFail(
"Invalid DYNAMIC_ALLOCATION value of %s for %s. "
"Valid values: Y or N" %
(dynamic_allocation, network_name))
# Parse/validate the gateway (optional)
if system_config.has_option(network_name, attr_prefix + 'GATEWAY'):
gateway_address_str = system_config.get(
network_name, attr_prefix + 'GATEWAY')
try:
self.gateway_address = validate_address_str(
gateway_address_str, self.cidr)
except ValidateFail as e:
raise ConfigFail(
"Invalid %s value of %s for %s.\nReason: %s" %
(attr_prefix + 'GATEWAY',
gateway_address_str, network_name, e))
# Parse/validate the logical interface
if logical_interface_required or system_config.has_option(
network_name, attr_prefix + 'LOGICAL_INTERFACE'):
logical_interface_name = system_config.get(
network_name, attr_prefix + 'LOGICAL_INTERFACE')
self.logical_interface = LogicalInterface()
self.logical_interface.parse_config(system_config,
logical_interface_name)