Update network interface puppet resource gen to support dual-stack
This change updates the puppet resource generation logic for network interfaces to suport dual-stack. Change summary ============== - Aliases / labels Previously, each alias was associated to a specific network. Now, since more than one address can be associated to the same network, the aliases are also associated to addresses. The label name is now :<network_id>-<address_id>. The network_id is 0 if there's no network associated with the alias, that's the case for the base interface config or for the cases where the address is not associated to a network. The address_id is 0 if there's no address associated with the alias, which is the case for the base config and for when there's no static address associated to the network, i.e. the method is DHCP. - Static addresses Previously, interfaces with more than one static addresses not associated with pools would be assigned just the first one. Now, an alias config is generated for each address. - CentOS compatibility All the code related to CentOS was removed. - Duplex-direct mode Duplex-direct systems must have DAD disabled for management and cluster-host interfaces. The disable DAD command is now generated only in the base interface config for all types of interfaces. - Address pool names The change assumes a new standard for address pool names, they will be formed by the old names with the suffixes '-ipv4' or '-ipv6'. For example: management-ipv4, management-ipv6. Since other systems that rely on the previous standard are not yet upgraded to dual-stack, the constant DUAL_STACK_COMPATIBILITY_MODE was introduced to control resource generation and validation logic in a way that assures compatibility. The constant and the conditionals will be removed once the other modules are updated. The conditionals were implemented more as a way to highlight which parts of the code are affected and make the changes easier in the future. - Tests / DB Base The base class for tests was updated to generate more consistent database states. Mixins for dual-stack cases were also created. - Tests / Interface Most of the test functions in the class InterfaceTestCase caused unnecessary updates to the database and the context. The class was splitted in two, the first one containing the tests that only need the basic database setup (controller, one interface associated with the mgmt network), and the other one for the tests that need different setups. A new fixture was created to test multiple system configs (IPv4, IPv6, dual-stack), which inspects in detail the generated hieradata. The tests associated with the InterfaceHostV6TestCase were moved to the new fixture, and new ones were introduced. Test plan ========= Online setup tests ------------------ System: STANDARD (2 Controllers, 2 Storages, 1 Worker) Stack setups: - Single stack IPv4 - Single stack IPv6 - Dual stack, primary IPv4 - Dual stack, primary IPv6 [PASS] TC1 - Online setup, regular ethernet mgmt0 (Ethernet) -> PXEBOOT, MGMT, CLUSTER_HOST [PASS] TC2 - Online setup, VLAN over ethernet pxe0 (Ethernet) -> PXEBOOT mgmt0 (VLAN over pxe0) -> MGMT, CLUSTER_HOST [PASS] TC3 - Online setup, bondig mgmt0 (Bond) -> PXEBOOT, MGMT, CLUSTER_HOST [PASS] TC4 - Online setup, VLAN over bonding pxe0 (Bond) -> PXEBOOT mgmt0 (VLAN over pxe0) -> MGMT, CLUSTER_HOST Installation tests ------------------ Systems: - AIO-SX - AIO-DX - Standard (2 Controllers, 2 Storages, 1 Worker) [PASS] TC5 - Regular installation on VirtualBox, IPv4 [PASS] TC6 - Regular installation on VirtualBox, IPv6 Data interface tests -------------------- System: AIO-DX Setup: data0 -> Ethernet, ipv4_mode=static, ipv6_mode=static data1 -> VLAN on top of data0, ipv4_mode=static, ipv6_mode=static For both interfaces, the following was performed: [PASS] TC7 - Add static IPv4 address [PASS] TC8 - Add static IPv6 address [PASS] TC9 - Add IPv4 route [PASS] TC10 - Add IPv6 route [PASS] TC11 - Remove IPv4 route [PASS] TC12 - Remove IPv6 route [PASS] TC13 - Remove static IPv4 address [PASS] TC14 - Remove static IPv6 address Story: 2011027 Task: 49815 Change-Id: Ib9603cbd444b21aefbcd417780a12c079f3d0b0f Signed-off-by: Lucas Ratusznei Fonseca <lucas.ratuszneifonseca@windriver.com>
This commit is contained in:
parent
e4b32b7e16
commit
ff3a5d2341
|
@ -15,7 +15,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2015-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2015-2024 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
|
||||
|
@ -63,15 +63,26 @@ SUBCLOUD_WRITABLE_ADDRPOOLS = ['system-controller-subnet',
|
|||
# so we can't depend on the address pool having a static name.
|
||||
SUBCLOUD_WRITABLE_NETWORK_TYPES = ['admin']
|
||||
|
||||
# Address pool of oam and system controller oam are allowed to be of
|
||||
# Address pools of oam and system controller oam are allowed to be of
|
||||
# overlapped prefix in the subcloud.
|
||||
OAM_ADDRESS_POOL = 'oam'
|
||||
SYSTEM_CONTROLLER_OAM_ADDRESS_POOL = 'system-controller-oam-subnet'
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
OAM_ADDRESS_POOL_OVERLAP_INDEX = {'oam': 'system-controller-oam-subnet',
|
||||
'oam-ipv4': 'system-controller-oam-subnet-ipv4',
|
||||
'oam-ipv6': 'system-controller-oam-subnet-ipv6'}
|
||||
else:
|
||||
OAM_ADDRESS_POOL_OVERLAP_INDEX = {'oam-ipv4': 'system-controller-oam-subnet-ipv4',
|
||||
'oam-ipv6': 'system-controller-oam-subnet-ipv6'}
|
||||
|
||||
# Address pool for the management network in an AIO-SX installation
|
||||
# is allowed to be deleted/modified post install
|
||||
MANAGEMENT_ADDRESS_POOL = 'management'
|
||||
AIOSX_WRITABLE_ADDRPOOLS = [MANAGEMENT_ADDRESS_POOL]
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
MANAGEMENT_ADDRESS_POOL_NAMES = {None: 'management',
|
||||
constants.IPV4_FAMILY: 'management-ipv4',
|
||||
constants.IPV6_FAMILY: 'management-ipv6'}
|
||||
else:
|
||||
MANAGEMENT_ADDRESS_POOL_NAMES = {constants.IPV4_FAMILY: 'management-ipv4',
|
||||
constants.IPV6_FAMILY: 'management-ipv6'}
|
||||
AIOSX_WRITABLE_ADDRPOOLS = MANAGEMENT_ADDRESS_POOL_NAMES.values()
|
||||
|
||||
|
||||
class AddressPoolPatchType(types.JsonPatchType):
|
||||
|
@ -324,8 +335,8 @@ class AddressPoolController(rest.RestController):
|
|||
f"{addrpool['prefix']}"])
|
||||
pools = pecan.request.dbapi.address_pools_get_all()
|
||||
for pool in pools:
|
||||
if pool.name == OAM_ADDRESS_POOL and \
|
||||
addrpool['name'] == SYSTEM_CONTROLLER_OAM_ADDRESS_POOL:
|
||||
if pool.name in OAM_ADDRESS_POOL_OVERLAP_INDEX and \
|
||||
addrpool['name'] == OAM_ADDRESS_POOL_OVERLAP_INDEX[pool.name]:
|
||||
# we are ignoring overlap in this case as subcloud oam and
|
||||
# system-controller oam are sharable.
|
||||
continue
|
||||
|
@ -405,15 +416,15 @@ class AddressPoolController(rest.RestController):
|
|||
any(network.type == constants.NETWORK_TYPE_MGMT
|
||||
for network in networks):
|
||||
|
||||
if (new_name != MANAGEMENT_ADDRESS_POOL):
|
||||
if (new_name != addrpool.name):
|
||||
msg = _("Cannot complete the action because the "
|
||||
"address pool for mgmt network must be named as '{}'."
|
||||
.format(MANAGEMENT_ADDRESS_POOL))
|
||||
.format(addrpool.name))
|
||||
raise ValueError(msg)
|
||||
|
||||
def _check_aiosx_mgmt(self, addrpool):
|
||||
if (utils.get_system_mode() == constants.SYSTEM_MODE_SIMPLEX and
|
||||
addrpool['name'] == MANAGEMENT_ADDRESS_POOL):
|
||||
addrpool['name'] in MANAGEMENT_ADDRESS_POOL_NAMES.values()):
|
||||
if (utils.get_distributed_cloud_role() !=
|
||||
constants.DISTRIBUTED_CLOUD_ROLE_SUBCLOUD):
|
||||
if 'gateway_address' in addrpool and \
|
||||
|
@ -750,7 +761,7 @@ class AddressPoolController(rest.RestController):
|
|||
# if proxy is being used, remove the old management network IPs
|
||||
# from the no_proxy list
|
||||
if cutils.is_initial_config_complete() and \
|
||||
addrpool.name == MANAGEMENT_ADDRESS_POOL:
|
||||
addrpool.name in MANAGEMENT_ADDRESS_POOL_NAMES.values():
|
||||
self._remove_mgmt_ips_from_no_proxy_list(addresses)
|
||||
|
||||
# Delete the address pool, which will also delete any associated
|
||||
|
|
|
@ -181,9 +181,13 @@ class NetworkController(rest.RestController):
|
|||
# the use of addrpool named 'management'.
|
||||
if pool_uuid:
|
||||
pool = pecan.request.dbapi.address_pool_get(pool_uuid)
|
||||
if pool['name'] != "management":
|
||||
msg = _("Network of type {} must use the addrpool named '{}'."
|
||||
.format(networktype, address_pool.MANAGEMENT_ADDRESS_POOL))
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
pool_name = address_pool.MANAGEMENT_ADDRESS_POOL_NAMES[None]
|
||||
else:
|
||||
pool_name = address_pool.MANAGEMENT_ADDRESS_POOL_NAMES[pool.family]
|
||||
if pool['name'] != pool_name:
|
||||
msg = _("Network of type {} must use the addrpool named '{}' for {}."
|
||||
.format(networktype, pool_name, constants.IP_FAMILIES[pool.family]))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _check_network_pool(self, pool):
|
||||
|
|
|
@ -2502,3 +2502,7 @@ LUKS_VAULT_TYPE_NAME = "luks_encrypted_vault"
|
|||
MGMT_IPSEC_ENABLING = 'enabling'
|
||||
MGMT_IPSEC_ENABLED = 'enabled'
|
||||
MGMT_IPSEC_DISABLED = 'disabled'
|
||||
|
||||
# If True, makes outputs compatible with single stack versions of ansible-playbooks and stx-puppet.
|
||||
# Shall be removed when the other projects are updated.
|
||||
DUAL_STACK_COMPATIBILITY_MODE = True
|
||||
|
|
|
@ -732,6 +732,10 @@ class AddressNotFound(NotFound):
|
|||
message = _("Address %(address_uuid)s could not be found.")
|
||||
|
||||
|
||||
class AddressNotFoundById(NotFound):
|
||||
message = _("Address %(address_id)s could not be found.")
|
||||
|
||||
|
||||
class AddressNotFoundByAddress(NotFound):
|
||||
message = _("Address %(address)s could not be found.")
|
||||
|
||||
|
|
|
@ -5141,7 +5141,9 @@ class Connection(api.Connection):
|
|||
def networks_get_by_pool(self, pool_id, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
query = model_query(models.Networks)
|
||||
query = query.filter_by(address_pool_id=pool_id)
|
||||
query = (query.join(models.NetworkAddressPools,
|
||||
models.NetworkAddressPools.network_id == models.Networks.id))
|
||||
query = query.filter(models.NetworkAddressPools.address_pool_id == pool_id)
|
||||
return _paginate_query(models.Networks, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
|
@ -5384,6 +5386,16 @@ class Connection(api.Connection):
|
|||
raise exception.AddressNotFound(address_uuid=address_uuid)
|
||||
return result
|
||||
|
||||
def _address_get_by_id(self, address_id):
|
||||
query = model_query(models.Addresses)
|
||||
query = (query.
|
||||
filter(models.Addresses.id == address_id))
|
||||
try:
|
||||
result = query.one()
|
||||
except NoResultFound:
|
||||
raise exception.AddressNotFoundById(address_id=address_id)
|
||||
return result
|
||||
|
||||
def _address_query(self, values):
|
||||
query = model_query(models.Addresses)
|
||||
query = (query.
|
||||
|
@ -5412,6 +5424,10 @@ class Connection(api.Connection):
|
|||
def address_get(self, address_uuid):
|
||||
return self._address_get(address_uuid)
|
||||
|
||||
@db_objects.objectify(objects.address)
|
||||
def address_get_by_id(self, address_id):
|
||||
return self._address_get_by_id(address_id)
|
||||
|
||||
@db_objects.objectify(objects.address)
|
||||
def address_get_by_name(self, name, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import collections
|
||||
import copy
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
|
||||
|
@ -129,6 +128,10 @@ class InterfacePuppet(base.BasePuppet):
|
|||
|
||||
def _create_interface_context(self, host):
|
||||
host_interfaces = self.dbapi.iinterface_get_by_ihost(host.uuid)
|
||||
networks = self._get_network_type_index()
|
||||
address_pools = self._get_address_pool_index()
|
||||
network_address_pools = self._get_network_addresspool_index()
|
||||
addresses = self._get_address_interface_name_index(host)
|
||||
context = {
|
||||
'hostname': host.hostname,
|
||||
'personality': host.personality,
|
||||
|
@ -137,14 +140,17 @@ class InterfacePuppet(base.BasePuppet):
|
|||
'system_mode': self._get_system().system_mode,
|
||||
'ports': self._get_port_interface_id_index(host),
|
||||
'interfaces': self._get_interface_name_index(host_interfaces),
|
||||
'interface_networks': self._get_interface_network_index(
|
||||
host_interfaces, addresses, networks, address_pools, network_address_pools),
|
||||
'interfaces_datanets': self._get_interface_name_datanets(
|
||||
host.hostname, host_interfaces),
|
||||
'devices': self._get_port_pciaddr_index(host),
|
||||
'addresses': self._get_address_interface_name_index(host),
|
||||
'addresses': addresses,
|
||||
'routes': self._get_routes_interface_name_index(host),
|
||||
'networks': self._get_network_type_index(),
|
||||
'gateways': self._get_gateway_index(),
|
||||
'floatingips': self._get_floating_ip_index(),
|
||||
'networks': networks,
|
||||
'address_pools': address_pools,
|
||||
'floatingips': self._get_floating_ip_index(networks, address_pools,
|
||||
network_address_pools),
|
||||
'datanets': self._get_datanetworks(host),
|
||||
'vswitchtype': self._vswitch_type(),
|
||||
}
|
||||
|
@ -196,6 +202,61 @@ class InterfacePuppet(base.BasePuppet):
|
|||
"""
|
||||
return interface._get_address_interface_name_index(self.dbapi, host)
|
||||
|
||||
def _get_interface_network_index(self, host_interfaces, address_index, network_type_index,
|
||||
addrpool_index, network_addrpool_index):
|
||||
"""
|
||||
Builds a dictionary that associates interfaces with networks and addresses.
|
||||
Format:
|
||||
{
|
||||
<interface_name>: {
|
||||
<network_id or None>: {
|
||||
'network': <network_object or None>,
|
||||
'addresses': [ <address 1>, <address 2>, ... ]
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
network_id_index = {}
|
||||
for network in network_type_index.values():
|
||||
network_id_index[network.id] = network
|
||||
|
||||
interface_index = {}
|
||||
for iface in host_interfaces:
|
||||
interface_dict = {None: {'network': None, 'addresses': []}}
|
||||
for networktype in iface.networktypelist:
|
||||
network = network_type_index[networktype]
|
||||
interface_dict[network.id] = {'network': network, 'addresses': []}
|
||||
interface_index[iface.ifname] = interface_dict
|
||||
|
||||
for address_list in address_index.values():
|
||||
for address in address_list:
|
||||
addrpool = addrpool_index.get(address.pool_uuid, None)
|
||||
network_addrpool = network_addrpool_index.get(address.pool_uuid, None)
|
||||
|
||||
network = None
|
||||
if addrpool and network_addrpool:
|
||||
network = network_id_index[network_addrpool.network_id]
|
||||
|
||||
network_id = network.id if network else None
|
||||
|
||||
interface_entry = interface_index.get(address.ifname, None)
|
||||
if not interface_entry:
|
||||
continue
|
||||
|
||||
network_entry = interface_entry.get(network_id, None)
|
||||
|
||||
if not network_entry:
|
||||
network_entry = {
|
||||
'network': network,
|
||||
'addresses': []
|
||||
}
|
||||
interface_entry[network_id] = network_entry
|
||||
|
||||
network_entry['addresses'].append(address)
|
||||
|
||||
return interface_index
|
||||
|
||||
def _get_routes_interface_name_index(self, host):
|
||||
"""
|
||||
Builds a dictionary of route lists indexed by interface name.
|
||||
|
@ -216,118 +277,55 @@ class InterfacePuppet(base.BasePuppet):
|
|||
networks[network['type']] = network
|
||||
return networks
|
||||
|
||||
def _get_gateway_index(self):
|
||||
"""
|
||||
Builds a dictionary of gateway IP addresses indexed by network type.
|
||||
"""
|
||||
gateways = {}
|
||||
try:
|
||||
mgmt_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_GATEWAY, constants.NETWORK_TYPE_MGMT)
|
||||
gateways.update({
|
||||
constants.NETWORK_TYPE_MGMT: mgmt_address.address})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
def _get_address_pool_index(self):
|
||||
addrpool_index = {}
|
||||
addrpools = self.dbapi.address_pools_get_all()
|
||||
for addrpool in addrpools:
|
||||
addrpool_index[addrpool.uuid] = addrpool
|
||||
return addrpool_index
|
||||
|
||||
try:
|
||||
oam_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_GATEWAY, constants.NETWORK_TYPE_OAM)
|
||||
gateways.update({
|
||||
constants.NETWORK_TYPE_OAM: oam_address.address})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
def _get_network_addresspool_index(self):
|
||||
network_addrpool_index = {}
|
||||
network_addrpools = self.dbapi.network_addrpool_get_all()
|
||||
for network_addrpool in network_addrpools:
|
||||
network_addrpool_index[network_addrpool.address_pool_uuid] = network_addrpool
|
||||
return network_addrpool_index
|
||||
|
||||
return gateways
|
||||
|
||||
def _get_floating_ip_index(self):
|
||||
def _get_floating_ip_index(self, networks, address_pools, network_address_pools):
|
||||
"""
|
||||
Builds a dictionary of floating ip addresses indexed by network type.
|
||||
"""
|
||||
mgmt_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
mgmt_floating_ip = (str(mgmt_address.address) + '/' +
|
||||
str(mgmt_address.prefix))
|
||||
|
||||
floating_ips = {
|
||||
constants.NETWORK_TYPE_MGMT: mgmt_floating_ip
|
||||
}
|
||||
|
||||
try:
|
||||
pxeboot_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_PXEBOOT)
|
||||
|
||||
pxeboot_floating_ip = (str(pxeboot_address.address) + '/' +
|
||||
str(pxeboot_address.prefix))
|
||||
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_PXEBOOT: pxeboot_floating_ip,
|
||||
})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
networktypes = [
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_PXEBOOT,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
constants.NETWORK_TYPE_IRONIC,
|
||||
constants.NETWORK_TYPE_STORAGE,
|
||||
constants.NETWORK_TYPE_ADMIN
|
||||
]
|
||||
|
||||
system = self._get_system()
|
||||
if system.system_mode != constants.SYSTEM_MODE_SIMPLEX:
|
||||
oam_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_OAM)
|
||||
networktypes.append(constants.NETWORK_TYPE_OAM)
|
||||
|
||||
oam_floating_ip = (str(oam_address.address) + '/' +
|
||||
str(oam_address.prefix))
|
||||
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_OAM: oam_floating_ip
|
||||
})
|
||||
network_index = {}
|
||||
for network in networks.values():
|
||||
if network.type in networktypes:
|
||||
network_index[network.id] = network
|
||||
|
||||
floating_ips = collections.defaultdict(list)
|
||||
for network_address_pool in network_address_pools.values():
|
||||
network = network_index.get(network_address_pool.network_id, None)
|
||||
if not network:
|
||||
continue
|
||||
address_pool = address_pools[network_address_pool.address_pool_uuid]
|
||||
if not address_pool.floating_address_id:
|
||||
continue
|
||||
try:
|
||||
cluster_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
if cluster_address:
|
||||
cluster_floating_ip = (str(cluster_address.address) + '/' +
|
||||
str(cluster_address.prefix))
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST: cluster_floating_ip
|
||||
})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
|
||||
try:
|
||||
ironic_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_IRONIC)
|
||||
|
||||
ironic_floating_ip = (str(ironic_address.address) + '/' +
|
||||
str(ironic_address.prefix))
|
||||
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_IRONIC: ironic_floating_ip,
|
||||
})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
|
||||
try:
|
||||
storage_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_STORAGE)
|
||||
|
||||
storage_floating_ip = (str(storage_address.address) + '/' +
|
||||
str(storage_address.prefix))
|
||||
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_STORAGE: storage_floating_ip,
|
||||
})
|
||||
except exception.AddressNotFoundByName:
|
||||
pass
|
||||
|
||||
try:
|
||||
admin_address = self._get_address_by_name(
|
||||
constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_ADMIN)
|
||||
|
||||
admin_floating_ip = (str(admin_address.address) + '/' +
|
||||
str(admin_address.prefix))
|
||||
|
||||
floating_ips.update({
|
||||
constants.NETWORK_TYPE_ADMIN: admin_floating_ip,
|
||||
})
|
||||
except exception.AddressNotFoundByName:
|
||||
address = self.dbapi.address_get_by_id(address_pool.floating_address_id)
|
||||
floating_ips[network.type].append(address)
|
||||
except exception.AddressNotFoundById:
|
||||
pass
|
||||
|
||||
return floating_ips
|
||||
|
@ -666,82 +664,46 @@ def _set_address_netmask(address):
|
|||
return address
|
||||
|
||||
|
||||
def get_interface_primary_address(context, iface, network_id=None):
|
||||
def get_gateway_address(context, network, address):
|
||||
"""
|
||||
Determine the primary IP address on an interface (if any). If multiple
|
||||
addresses exist then the first address is returned.
|
||||
Gets the corresponding gateway for the provided address
|
||||
"""
|
||||
addresses = context['addresses'].get(iface['ifname'], [])
|
||||
if len(addresses) > 0 and network_id is None:
|
||||
return _set_address_netmask(addresses[0])
|
||||
elif network_id:
|
||||
for address in addresses:
|
||||
net = find_network_by_pool_uuid(context,
|
||||
address.pool_uuid)
|
||||
if net and network_id == net.id:
|
||||
return _set_address_netmask(address)
|
||||
|
||||
addrpool = context['address_pools'].get(address.pool_uuid, None)
|
||||
|
||||
def get_interface_address_family(context, iface, network_id=None):
|
||||
"""
|
||||
Determine the IP family/version of the interface primary address. If there
|
||||
is no address then the IPv4 family identifier is returned so that an
|
||||
appropriate default is always present in interface configurations.
|
||||
"""
|
||||
address = get_interface_primary_address(context, iface, network_id)
|
||||
if not address:
|
||||
return 'inet' # default to ipv4
|
||||
elif IPAddress(address['address']).version == 4:
|
||||
return 'inet'
|
||||
elif IPAddress(address['address']).version == 6:
|
||||
return 'inet6'
|
||||
|
||||
|
||||
def get_interface_gateway_address(context, networktype):
|
||||
"""
|
||||
Determine if the interface has a default gateway.
|
||||
"""
|
||||
if (networktype == constants.NETWORK_TYPE_MGMT and
|
||||
context['personality'] in [constants.WORKER, constants.STORAGE]):
|
||||
address = context['floatingips'].get(networktype, None)
|
||||
if address is None:
|
||||
if not addrpool:
|
||||
return None
|
||||
return address.split('/')[0]
|
||||
return context['gateways'].get(networktype, None)
|
||||
|
||||
if (network and network.type == constants.NETWORK_TYPE_MGMT and
|
||||
context['personality'] in [constants.WORKER, constants.STORAGE]):
|
||||
gateway_address = addrpool.floating_address
|
||||
else:
|
||||
gateway_address = addrpool.gateway_address
|
||||
|
||||
return gateway_address
|
||||
|
||||
|
||||
def get_interface_address_method(context, iface, network_id=None):
|
||||
"""
|
||||
Determine what type of interface to configure for each network type.
|
||||
"""
|
||||
networktype = find_networktype_by_network_id(context, network_id)
|
||||
def get_interface_address_method(context, iface, network=None, address=None):
|
||||
networktype = network.type if network else None
|
||||
|
||||
has_static_addr = False
|
||||
if (iface.ipv4_mode == constants.IPV4_STATIC or iface.ipv6_mode == constants.IPV6_STATIC):
|
||||
if address:
|
||||
if address.family == constants.IPV4_FAMILY and iface.ipv4_mode == constants.IPV4_STATIC:
|
||||
has_static_addr = True
|
||||
elif address.family == constants.IPV6_FAMILY and iface.ipv6_mode == constants.IPV6_STATIC:
|
||||
has_static_addr = True
|
||||
|
||||
if iface.ifclass == constants.INTERFACE_CLASS_DATA:
|
||||
if is_syscfg_network():
|
||||
if is_vswitch_type_unaccelerated(context):
|
||||
return STATIC_METHOD
|
||||
else:
|
||||
if has_static_addr:
|
||||
return STATIC_METHOD
|
||||
# All data interfaces configured in the kernel because they are not
|
||||
# natively supported in vswitch or need to be shared with the kernel
|
||||
# because of a platform VLAN should be left as manual config
|
||||
return MANUAL_METHOD
|
||||
elif (iface.ifclass == constants.INTERFACE_CLASS_PLATFORM and
|
||||
networktype is None and has_static_addr):
|
||||
|
||||
# On Debian, interfaces of networktype:None with alias should be
|
||||
# manual method (i.e: lo) and alias will be Static method (i.e: lo:1)
|
||||
if not is_syscfg_network() and len(iface.networktypelist) > 1:
|
||||
return MANUAL_METHOD
|
||||
|
||||
# Allow platform-class interface with ipv4 mode set to static to
|
||||
# have static ip address
|
||||
elif (iface.ifclass == constants.INTERFACE_CLASS_PLATFORM and networktype is None):
|
||||
if has_static_addr:
|
||||
return STATIC_METHOD
|
||||
return MANUAL_METHOD
|
||||
elif not iface.ifclass or iface.ifclass == constants.INTERFACE_CLASS_NONE \
|
||||
or not networktype:
|
||||
# Interfaces that are configured purely as a dependency from other
|
||||
|
@ -871,42 +833,21 @@ def get_basic_network_config(ifname, ensure='present',
|
|||
'onboot': onboot,
|
||||
'options': {}}
|
||||
if mtu:
|
||||
if is_syscfg_network():
|
||||
config['mtu'] = str(mtu)
|
||||
else:
|
||||
config['options']['mtu'] = str(mtu)
|
||||
return config
|
||||
|
||||
|
||||
def get_bridge_network_config(context, iface):
|
||||
def is_disable_dad_required(iface, network=None):
|
||||
"""
|
||||
Builds a network config dictionary for bridge interface resource.
|
||||
Disable DAD command is included in the base interface config, only for interfaces associated
|
||||
with management and cluster-host networks.
|
||||
"""
|
||||
os_ifname = get_interface_os_ifname(context, iface)
|
||||
os_ifname = 'br-' + os_ifname
|
||||
method = get_interface_address_method(context, iface)
|
||||
family = get_interface_address_family(context, iface)
|
||||
config = get_basic_network_config(
|
||||
os_ifname, method=method, family=family)
|
||||
config['options']['TYPE'] = 'Bridge'
|
||||
return config
|
||||
|
||||
|
||||
def is_disable_dad_required(context, iface, config, network_id=None):
|
||||
"""
|
||||
Determine whether DAD is required to be disabled.
|
||||
If mgmt and cluster-host are separate vlans, the vlan has DAD disabled.
|
||||
If the vlans are shared between networks, the DAD is disabled
|
||||
on the parent vlan interface, not the alias interfaces.
|
||||
If mgmt and cluster-host are not vlan, the interfaces have DAD disabled.
|
||||
"""
|
||||
networktype = find_networktype_by_network_id(context, network_id)
|
||||
if len(iface.networktypelist) > 1:
|
||||
if (iface['iftype'] == constants.INTERFACE_TYPE_VLAN and
|
||||
network_id is None):
|
||||
return True
|
||||
elif (networktype and networktype in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST]):
|
||||
if network:
|
||||
return False
|
||||
networks = [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST]
|
||||
for networktype in iface.networktypelist:
|
||||
if networktype in networks:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -922,21 +863,18 @@ def get_interface_sysctl_ifname(context, iface):
|
|||
return os_ifname
|
||||
|
||||
|
||||
def get_duplex_direct_network_config(context, iface, config, network_id):
|
||||
def get_duplex_direct_network_config(context, iface, config, network):
|
||||
"""
|
||||
Disable dad on the specified interface for duplex-direct config
|
||||
"""
|
||||
if iface['iftype'] == constants.INTERFACE_TYPE_AE:
|
||||
networktype = find_networktype_by_network_id(context, network_id)
|
||||
if (networktype and networktype in [constants.NETWORK_TYPE_MGMT,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST]):
|
||||
command = ("/sbin/modprobe bonding; "
|
||||
"grep %s /sys/class/net/bonding_masters || "
|
||||
"echo +%s > /sys/class/net/bonding_masters" % (
|
||||
iface['ifname'], iface['ifname']))
|
||||
fill_interface_config_option_operation(config['options'], IFACE_PRE_UP_OP, command)
|
||||
|
||||
if not is_syscfg_network() and iface['iftype'] == constants.INTERFACE_TYPE_VLAN:
|
||||
if iface['iftype'] == constants.INTERFACE_TYPE_VLAN:
|
||||
add_vlan_interface_creation_command(context, iface, config['options'])
|
||||
|
||||
sysctl_ifname = get_interface_sysctl_ifname(context, iface)
|
||||
|
@ -951,9 +889,6 @@ def get_vlan_network_config(context, iface, config):
|
|||
interface.
|
||||
"""
|
||||
lower_os_ifname = get_lower_interface_os_ifname(context, iface)
|
||||
if is_syscfg_network():
|
||||
options = {'VLAN': 'yes', 'PHYSDEV': lower_os_ifname}
|
||||
else:
|
||||
options = {'vlan-raw-device': lower_os_ifname}
|
||||
fill_interface_config_option_operation(options, IFACE_PRE_UP_OP,
|
||||
'/sbin/modprobe -q 8021q')
|
||||
|
@ -976,28 +911,6 @@ def add_vlan_interface_creation_command(context, iface, options):
|
|||
'ip link del %s' % (os_ifname))
|
||||
|
||||
|
||||
def get_bond_interface_options_sysconfig(iface, primary_iface):
|
||||
"""
|
||||
Get the interface config attribute for bonding options
|
||||
"""
|
||||
ae_mode = iface['aemode']
|
||||
tx_hash_policy = iface['txhashpolicy']
|
||||
options = None
|
||||
if ae_mode in ACTIVE_STANDBY_AE_MODES:
|
||||
# Requires the active device in an active_standby LAG
|
||||
# configuration to be determined based on the lowest MAC address
|
||||
options = 'mode=active-backup miimon=100 primary={}'.format(primary_iface['ifname'])
|
||||
if iface['primary_reselect']:
|
||||
options += ' primary_reselect=%s' % iface['primary_reselect']
|
||||
else:
|
||||
options = 'xmit_hash_policy=%s miimon=100' % tx_hash_policy
|
||||
if ae_mode in BALANCED_AE_MODES:
|
||||
options = 'mode=balance-xor ' + options
|
||||
elif ae_mode in LACP_AE_MODES:
|
||||
options = 'mode=802.3ad lacp_rate=fast ' + options
|
||||
return options
|
||||
|
||||
|
||||
def get_bond_interface_options_ifupdown(iface, primary_iface):
|
||||
"""
|
||||
Get the interface config attribute for bonding options
|
||||
|
@ -1028,7 +941,7 @@ def get_bond_interface_options_ifupdown(iface, primary_iface):
|
|||
return options
|
||||
|
||||
|
||||
def get_bond_network_config(context, iface, config, network_id):
|
||||
def get_bond_network_config(context, iface, config):
|
||||
"""
|
||||
Augments a basic config dictionary with the attributes specific to a bond
|
||||
interface.
|
||||
|
@ -1038,12 +951,6 @@ def get_bond_network_config(context, iface, config, network_id):
|
|||
bonding_options = None
|
||||
iface_mac = iface['imac'].rstrip()
|
||||
|
||||
if is_syscfg_network():
|
||||
options['MACADDR'] = iface_mac
|
||||
bonding_options = get_bond_interface_options_sysconfig(iface, primary_iface)
|
||||
if bonding_options:
|
||||
options['BONDING_OPTS'] = bonding_options
|
||||
else:
|
||||
options['hwaddress'] = iface_mac
|
||||
bonding_options = get_bond_interface_options_ifupdown(iface, primary_iface)
|
||||
if bonding_options:
|
||||
|
@ -1092,14 +999,9 @@ def get_ethernet_network_config(context, iface, config):
|
|||
"""
|
||||
interface_class = iface['ifclass']
|
||||
options = {}
|
||||
# Increased to accommodate devices that require more time to
|
||||
# complete link auto-negotiation
|
||||
if is_syscfg_network():
|
||||
options['LINKDELAY'] = '20'
|
||||
|
||||
if is_bridged_interface(context, iface):
|
||||
if is_syscfg_network():
|
||||
options['BRIDGE'] = get_bridge_interface_name(context, iface)
|
||||
pass
|
||||
elif is_slave_interface(context, iface):
|
||||
if not is_data_interface(context, iface):
|
||||
# Data interfaces that require a network configuration are not
|
||||
|
@ -1107,11 +1009,6 @@ def get_ethernet_network_config(context, iface, config):
|
|||
# rely on the Linux device driver to setup some or all functions
|
||||
# on the device (e.g., the Mellanox DPDK driver relies on the
|
||||
# Linux driver to set the proper MTU value).
|
||||
if is_syscfg_network():
|
||||
options['SLAVE'] = 'yes'
|
||||
options['MASTER'] = get_master_interface(context, iface)
|
||||
options['PROMISC'] = 'yes'
|
||||
else:
|
||||
master = get_master_interface(context, iface)
|
||||
options['bond-master'] = master
|
||||
osname = get_interface_os_ifname(context, iface)
|
||||
|
@ -1346,13 +1243,11 @@ def get_fpga_config(context, iface):
|
|||
return config
|
||||
|
||||
|
||||
def get_common_network_config(context, iface, config, network_id=None):
|
||||
def get_common_network_config(context, iface, config, network=None, address=None):
|
||||
"""
|
||||
Augments a basic config dictionary with the attributes specific to an upper
|
||||
layer interface (i.e., an interface that is used to terminate IP traffic).
|
||||
"""
|
||||
LOG.debug("get_common_network_config %s %s network_id=%s" %
|
||||
(iface.ifname, iface.networktypelist, network_id))
|
||||
|
||||
os_ifname = get_interface_os_ifname(context, iface)
|
||||
if os_ifname == config['ifname']:
|
||||
|
@ -1362,55 +1257,53 @@ def get_common_network_config(context, iface, config, network_id=None):
|
|||
fill_interface_config_option_operation(config['options'], IFACE_POST_UP_OP,
|
||||
traffic_classifier)
|
||||
|
||||
method = get_interface_address_method(context, iface, network_id)
|
||||
method = get_interface_address_method(context, iface, network, address)
|
||||
if method == STATIC_METHOD:
|
||||
address = get_interface_primary_address(context, iface, network_id)
|
||||
if address:
|
||||
_set_address_netmask(address)
|
||||
|
||||
config['ipaddress'] = address['address']
|
||||
config['netmask'] = address['netmask']
|
||||
else:
|
||||
LOG.info("Interface %s has no primary address" % iface['ifname'])
|
||||
|
||||
networktype = find_networktype_by_network_id(context, network_id)
|
||||
gateway = get_interface_gateway_address(context, networktype)
|
||||
gateway = get_gateway_address(context, network, address)
|
||||
if gateway:
|
||||
if is_syscfg_network():
|
||||
config['gateway'] = gateway
|
||||
else:
|
||||
config['options']['gateway'] = gateway
|
||||
return config
|
||||
|
||||
|
||||
def get_final_network_config(context, iface, config, network_id=None):
|
||||
def get_final_network_config(context, iface, config, network=None):
|
||||
"""
|
||||
Augments a basic config dictionary with the attribute that must be
|
||||
appended to an attribute that is already configured (e.g. pre_up)
|
||||
"""
|
||||
# add duplex_direct specific network config
|
||||
if context['system_mode'] == constants.SYSTEM_MODE_DUPLEX_DIRECT:
|
||||
if is_disable_dad_required(context, iface, config, network_id):
|
||||
config = get_duplex_direct_network_config(context, iface, config,
|
||||
network_id)
|
||||
if is_disable_dad_required(iface, network):
|
||||
config = get_duplex_direct_network_config(context, iface, config, network)
|
||||
return config
|
||||
|
||||
|
||||
def get_interface_network_config(context, iface, network_id=None):
|
||||
def get_interface_network_config(context, iface, network=None, address=None):
|
||||
"""
|
||||
Builds a network_config resource dictionary for a given interface
|
||||
"""
|
||||
if iface['iftype'] == constants.INTERFACE_TYPE_VF:
|
||||
# Only the parent SR-IOV interface needs a network config
|
||||
|
||||
method = get_interface_address_method(context, iface, network, address)
|
||||
|
||||
# if and address is present but the address mode is not static, there's
|
||||
# no need to generate a labeled config for the interface
|
||||
if address is not None and method == MANUAL_METHOD:
|
||||
return {}
|
||||
|
||||
# Create a basic network config resource
|
||||
os_ifname = get_interface_os_ifname(context, iface)
|
||||
method = get_interface_address_method(context, iface, network_id)
|
||||
family = get_interface_address_family(context, iface, network_id)
|
||||
family = get_address_family(address)
|
||||
|
||||
# for now label all interfaces that have network_id, later we will
|
||||
# set the definitive values
|
||||
if network_id:
|
||||
ifname = "%s:%d" % (os_ifname, network_id)
|
||||
if network or address:
|
||||
net_num = network.id if network else 0
|
||||
addr_num = address.id if address else 0
|
||||
ifname = "%s:%d-%d" % (os_ifname, net_num, addr_num)
|
||||
else:
|
||||
ifname = os_ifname
|
||||
|
||||
|
@ -1419,13 +1312,10 @@ def get_interface_network_config(context, iface, network_id=None):
|
|||
ifname, method=method, family=family, mtu=mtu)
|
||||
|
||||
# Add options common to all top level interfaces
|
||||
config = get_common_network_config(context, iface, config, network_id)
|
||||
config = get_common_network_config(context, iface, config, network, address)
|
||||
|
||||
# ensure addresses have host scope when configured against the loopback
|
||||
if os_ifname == LOOPBACK_IFNAME:
|
||||
if is_syscfg_network():
|
||||
options = {'SCOPE': 'scope host'}
|
||||
else:
|
||||
options = {'scope': 'host'}
|
||||
config['options'].update(options)
|
||||
|
||||
|
@ -1433,14 +1323,13 @@ def get_interface_network_config(context, iface, network_id=None):
|
|||
if iface['iftype'] == constants.INTERFACE_TYPE_VLAN:
|
||||
config = get_vlan_network_config(context, iface, config)
|
||||
elif iface['iftype'] == constants.INTERFACE_TYPE_AE:
|
||||
config = get_bond_network_config(context, iface, config, network_id)
|
||||
config = get_bond_network_config(context, iface, config)
|
||||
else:
|
||||
config = get_ethernet_network_config(context, iface, config)
|
||||
|
||||
# Add final options
|
||||
config = get_final_network_config(context, iface, config, network_id)
|
||||
config = get_final_network_config(context, iface, config, network)
|
||||
|
||||
if not is_syscfg_network():
|
||||
if iface['iftype'] == constants.INTERFACE_TYPE_VLAN:
|
||||
# When configuring a static IPv6 interface, CentOS' ifup tool uses 'ip link'
|
||||
# command to set both IPv4 and IPv6 MTU.
|
||||
|
@ -1453,9 +1342,6 @@ def get_interface_network_config(context, iface, network_id=None):
|
|||
fill_interface_config_option_operation(config['options'], IFACE_POST_UP_OP, set_mtu)
|
||||
|
||||
# disable ipv6 autoconfig
|
||||
if is_syscfg_network():
|
||||
config['options'].update({'IPV6_AUTOCONF': 'no'})
|
||||
else:
|
||||
interface_op = IFACE_POST_UP_OP
|
||||
if is_slave_interface(context, iface):
|
||||
# ifupdown's ifup only runs pre-up for slave interfaces
|
||||
|
@ -1468,14 +1354,56 @@ def get_interface_network_config(context, iface, network_id=None):
|
|||
accept_redir_off = 'echo 0 > /proc/sys/net/ipv6/conf/{}/accept_redirects'.format(os_ifname)
|
||||
fill_interface_config_option_operation(config['options'], interface_op, accept_redir_off)
|
||||
|
||||
network_type = network.type if network else None
|
||||
|
||||
# add the description field with the database ifname and networktype if available
|
||||
if not is_syscfg_network():
|
||||
networktype = find_networktype_by_network_id(context, network_id)
|
||||
config['options']['stx-description'] = f"ifname:{iface['ifname']},net:{networktype}"
|
||||
config['options']['stx-description'] = f"ifname:{iface['ifname']},net:{network_type}"
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def _append_interface_config(iface_configs, iface_config):
|
||||
if len(iface_config) > 0:
|
||||
iface_configs.append(iface_config)
|
||||
|
||||
|
||||
def get_interface_network_configs(context, iface, network=None):
|
||||
"""
|
||||
Builds a list of network_config resource dictionaries for a given interface,
|
||||
each corresponding to an associated address, plus the base unlabeled config
|
||||
"""
|
||||
|
||||
if iface['iftype'] == constants.INTERFACE_TYPE_VF:
|
||||
# Only the parent SR-IOV interface needs a network config
|
||||
return []
|
||||
|
||||
iface_configs = []
|
||||
|
||||
network_id = network.id if network else None
|
||||
network_dict = context['interface_networks'][iface.ifname][network_id]
|
||||
|
||||
if network:
|
||||
if len(network_dict['addresses']) == 0:
|
||||
iface_config = get_interface_network_config(context, iface, network)
|
||||
_append_interface_config(iface_configs, iface_config)
|
||||
else:
|
||||
# Most basic interface config, no network no address
|
||||
iface_config = get_interface_network_config(context, iface)
|
||||
_append_interface_config(iface_configs, iface_config)
|
||||
|
||||
for address in network_dict['addresses']:
|
||||
iface_config = get_interface_network_config(context, iface, network, address)
|
||||
_append_interface_config(iface_configs, iface_config)
|
||||
|
||||
return iface_configs
|
||||
|
||||
|
||||
def get_address_family(address):
|
||||
if address and IPAddress(address['address']).version == 6:
|
||||
return 'inet6'
|
||||
return 'inet'
|
||||
|
||||
|
||||
def generate_network_config(context, hiera_config, iface):
|
||||
"""
|
||||
Produce the puppet network config resources necessary to configure the
|
||||
|
@ -1483,24 +1411,18 @@ def generate_network_config(context, hiera_config, iface):
|
|||
resource, while in other cases it will emit multiple resources to create a
|
||||
bridge, or to add additional route resources.
|
||||
"""
|
||||
|
||||
os_ifname = get_interface_os_ifname(context, iface)
|
||||
|
||||
# Setup the default device configuration for the interface. This will be
|
||||
# overridden if there is a specific network type configuration, otherwise
|
||||
# it will act as the parent device for the aliases
|
||||
net_config = get_interface_network_config(context, iface)
|
||||
if net_config:
|
||||
hiera_config[NETWORK_CONFIG_RESOURCE].update({
|
||||
net_config['ifname']: format_network_config(net_config)
|
||||
})
|
||||
|
||||
for net_type in iface.networktypelist:
|
||||
net_id = find_network_id_by_networktype(context, net_type)
|
||||
net_config = get_interface_network_config(context, iface, net_id)
|
||||
if net_config:
|
||||
hiera_config[NETWORK_CONFIG_RESOURCE].update({
|
||||
net_config['ifname']: format_network_config(net_config)
|
||||
})
|
||||
networks = context['interface_networks'][iface.ifname]
|
||||
for network_dict in networks.values():
|
||||
net_configs = get_interface_network_configs(context, iface, network_dict['network'])
|
||||
for net_config in net_configs:
|
||||
hiera_config[NETWORK_CONFIG_RESOURCE][net_config['ifname']] = \
|
||||
format_network_config(net_config)
|
||||
|
||||
# Add complementary puppet resource definitions (if needed)
|
||||
for route in get_interface_routes(context, iface):
|
||||
|
@ -1524,23 +1446,11 @@ def generate_network_config(context, hiera_config, iface):
|
|||
})
|
||||
|
||||
|
||||
def find_network_by_pool_uuid(context, pool_uuid):
|
||||
for networktype, network in six.iteritems(context['networks']):
|
||||
if network.pool_uuid == pool_uuid:
|
||||
return network
|
||||
return None
|
||||
|
||||
|
||||
def find_network_id_by_networktype(context, networktype):
|
||||
for net_type, network in six.iteritems(context['networks']):
|
||||
if networktype == net_type:
|
||||
network = context['networks'].get(networktype, None)
|
||||
if network:
|
||||
return network.id
|
||||
|
||||
|
||||
def find_networktype_by_network_id(context, network_id):
|
||||
for networktype, network in six.iteritems(context['networks']):
|
||||
if network.id == network_id:
|
||||
return networktype
|
||||
return None
|
||||
|
||||
|
||||
def find_interface_by_type(context, networktype):
|
||||
|
@ -1555,20 +1465,6 @@ def find_interface_by_type(context, networktype):
|
|||
return iface
|
||||
|
||||
|
||||
def find_address_by_type(context, networktype):
|
||||
"""
|
||||
Lookup an address based on networktype. This is only intended for for
|
||||
types that only have 1 such address per node. For example, for SDN we
|
||||
only expect/support a single data IP address per node because the SDN
|
||||
controller cannot support more than 1.
|
||||
"""
|
||||
for ifname, addresses in six.iteritems(context['addresses']):
|
||||
for address in addresses:
|
||||
if address['networktype'] == networktype:
|
||||
return address['address'], address['prefix']
|
||||
return None, None
|
||||
|
||||
|
||||
def find_sriov_interfaces_by_driver(context, driver):
|
||||
"""
|
||||
Lookup all interfaces based on port driver.
|
||||
|
@ -1641,8 +1537,7 @@ def process_interface_labels(config, context):
|
|||
Adjust interface labeling according to ifupdown package rules and StarlingX
|
||||
requirements
|
||||
"""
|
||||
# This rules are a result of using Debian's ifupdown package,
|
||||
# StarlingX do not support dual-stack for now
|
||||
# This rules are a result of using Debian's ifupdown package
|
||||
#
|
||||
# Rules for label adjustment:
|
||||
# 1) if the interface have just one label:
|
||||
|
@ -1700,7 +1595,7 @@ def process_interface_labels(config, context):
|
|||
networktypelist = context['interfaces'][ifname].networktypelist
|
||||
undeprecate = "ip -6 addr replace" + \
|
||||
f" {intf_data['ipaddress']}/{intf_data['netmask']}" + \
|
||||
f" dev {intf} preferred_lft forever;"
|
||||
f" dev {intf} preferred_lft forever"
|
||||
if constants.NETWORK_TYPE_MGMT in networktypelist:
|
||||
fill_interface_config_option_operation(intf_data['options'],
|
||||
IFACE_POST_UP_OP, undeprecate)
|
||||
|
@ -1794,13 +1689,11 @@ def generate_unassigned_pxeboot_intf_config(context, config, db_api,
|
|||
if not is_pxeboot_present and is_mgmt_present:
|
||||
if mgmt_intf:
|
||||
LOG.info(f"add pxeboot network config in {mgmt_intf.ifname} ")
|
||||
net_id = find_network_id_by_networktype(context,
|
||||
constants.NETWORK_TYPE_PXEBOOT)
|
||||
network = context['networks'][constants.NETWORK_TYPE_PXEBOOT]
|
||||
# Setup the default device configuration for the interface. This will be
|
||||
# overridden if there is a specific network type configuration, otherwise
|
||||
# it will act as the parent device for the aliases
|
||||
mgmt_intf.networktypelist.append(constants.NETWORK_TYPE_PXEBOOT)
|
||||
net_config = get_interface_network_config(context, mgmt_intf, net_id)
|
||||
address_name = None
|
||||
if context['hostname'] == constants.CONTROLLER_0_HOSTNAME:
|
||||
address_name = utils.format_address_name(constants.CONTROLLER_0_HOSTNAME,
|
||||
|
@ -1808,15 +1701,12 @@ def generate_unassigned_pxeboot_intf_config(context, config, db_api,
|
|||
elif context['hostname'] == constants.CONTROLLER_1_HOSTNAME:
|
||||
address_name = utils.format_address_name(constants.CONTROLLER_1_HOSTNAME,
|
||||
constants.NETWORK_TYPE_PXEBOOT)
|
||||
if address_name:
|
||||
address = None
|
||||
if address_name:
|
||||
address = utils.get_primary_address_by_name(db_api, address_name,
|
||||
constants.NETWORK_TYPE_PXEBOOT)
|
||||
if (address and net_config['method'] == 'static'):
|
||||
addr_data = _set_address_netmask({'address': address.address,
|
||||
'prefix': address.prefix})
|
||||
net_config['ipaddress'] = addr_data['address']
|
||||
net_config['netmask'] = addr_data['netmask']
|
||||
|
||||
net_config = get_interface_network_config(context, mgmt_intf, network, address)
|
||||
|
||||
if net_config:
|
||||
config[NETWORK_CONFIG_RESOURCE].update({
|
||||
|
@ -1824,11 +1714,22 @@ def generate_unassigned_pxeboot_intf_config(context, config, db_api,
|
|||
})
|
||||
|
||||
|
||||
def get_address_config(context, iface, address):
|
||||
def get_address_config(context, iface, addresses):
|
||||
ifname = get_interface_os_ifname(context, iface)
|
||||
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
address = addresses[0]
|
||||
return {
|
||||
'ifname': ifname,
|
||||
'address': address,
|
||||
'address': str(address.address) + '/' + str(address.prefix)
|
||||
}
|
||||
else:
|
||||
address_list = []
|
||||
for address in addresses:
|
||||
address_list.append(str(address.address) + '/' + str(address.prefix))
|
||||
return {
|
||||
'ifname': ifname,
|
||||
'addresses': address_list,
|
||||
}
|
||||
|
||||
|
||||
|
@ -1836,10 +1737,10 @@ def generate_address_configs(context, config):
|
|||
"""
|
||||
Generate the puppet resource for each of the floating IP addresses
|
||||
"""
|
||||
for networktype, address in six.iteritems(context['floatingips']):
|
||||
for networktype, addresses in six.iteritems(context['floatingips']):
|
||||
iface = find_interface_by_type(context, networktype)
|
||||
if iface:
|
||||
address_config = get_address_config(context, iface, address)
|
||||
address_config = get_address_config(context, iface, addresses)
|
||||
config[ADDRESS_CONFIG_RESOURCE].update({
|
||||
networktype: address_config
|
||||
})
|
||||
|
@ -1848,7 +1749,7 @@ def generate_address_configs(context, config):
|
|||
iface = find_interface_by_type(context,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
if iface:
|
||||
address_config = get_address_config(context, iface, address)
|
||||
address_config = get_address_config(context, iface, addresses)
|
||||
config[ADDRESS_CONFIG_RESOURCE].update({
|
||||
networktype: address_config
|
||||
})
|
||||
|
@ -1857,7 +1758,7 @@ def generate_address_configs(context, config):
|
|||
iface = find_interface_by_type(context,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
if iface:
|
||||
address_config = get_address_config(context, iface, address)
|
||||
address_config = get_address_config(context, iface, addresses)
|
||||
config[ADDRESS_CONFIG_RESOURCE].update({
|
||||
networktype: address_config
|
||||
})
|
||||
|
@ -1919,13 +1820,12 @@ def fill_interface_config_option_operation(options, operation, command):
|
|||
"""
|
||||
Join new command to previous commands on the same operation
|
||||
"""
|
||||
if_op = {IFACE_UP_OP: 'up', IFACE_PRE_UP_OP: 'pre_up', IFACE_POST_UP_OP: 'post_up',
|
||||
IFACE_DOWN_OP: 'down', IFACE_PRE_DOWN_OP: 'pre_down', IFACE_POST_DOWN_OP: 'post_down'}
|
||||
if not is_syscfg_network():
|
||||
if_op[IFACE_PRE_UP_OP] = 'pre-up'
|
||||
if_op[IFACE_POST_UP_OP] = 'post-up'
|
||||
if_op[IFACE_PRE_DOWN_OP] = 'pre-down'
|
||||
if_op[IFACE_POST_DOWN_OP] = 'post-down'
|
||||
if_op = {IFACE_UP_OP: 'up',
|
||||
IFACE_PRE_UP_OP: 'pre-up',
|
||||
IFACE_POST_UP_OP: 'post-up',
|
||||
IFACE_DOWN_OP: 'down',
|
||||
IFACE_PRE_DOWN_OP: 'pre-down',
|
||||
IFACE_POST_DOWN_OP: 'post-down'}
|
||||
|
||||
if operation in if_op.keys():
|
||||
if if_op[operation] in options.keys():
|
||||
|
@ -1937,21 +1837,11 @@ def fill_interface_config_option_operation(options, operation, command):
|
|||
|
||||
|
||||
def get_intf_op_name(operation):
|
||||
if_op = {IFACE_UP_OP: 'up', IFACE_PRE_UP_OP: 'pre_up', IFACE_POST_UP_OP: 'post_up',
|
||||
IFACE_DOWN_OP: 'down', IFACE_PRE_DOWN_OP: 'pre_down', IFACE_POST_DOWN_OP: 'post_down'}
|
||||
if not is_syscfg_network():
|
||||
if_op[IFACE_PRE_UP_OP] = 'pre-up'
|
||||
if_op[IFACE_POST_UP_OP] = 'post-up'
|
||||
if_op[IFACE_PRE_DOWN_OP] = 'pre-down'
|
||||
if_op[IFACE_POST_DOWN_OP] = 'post-down'
|
||||
if_op = {IFACE_UP_OP: 'up',
|
||||
IFACE_PRE_UP_OP: 'pre-up',
|
||||
IFACE_POST_UP_OP: 'post-up',
|
||||
IFACE_DOWN_OP: 'down',
|
||||
IFACE_PRE_DOWN_OP: 'pre-down',
|
||||
IFACE_POST_DOWN_OP: 'post-down'}
|
||||
|
||||
return if_op[operation]
|
||||
|
||||
|
||||
def is_syscfg_network():
|
||||
"""
|
||||
Detect if the system is using sysconfig network interface file format
|
||||
"""
|
||||
if not os.path.isdir("/etc/sysconfig/network-scripts/"):
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
# Copyright (c) 2023-2024 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -88,7 +88,7 @@ class AddressPoolTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
|
|||
def _delete_management_pool(self):
|
||||
current_pools = self.get_json(self.API_PREFIX)
|
||||
for addrpool in current_pools[self.RESULT_KEY]:
|
||||
if addrpool['name'] == 'management':
|
||||
if addrpool['name'].startswith('management'):
|
||||
uuid = addrpool['uuid']
|
||||
self.delete(self.get_single_url(uuid),
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -178,12 +178,14 @@ class TestPostMixin(AddressPoolTestCase):
|
|||
f"with {name_1} address pool.",
|
||||
response.json['error_message'])
|
||||
|
||||
def _test_create_address_pool_pass_overlap_with_oam(self, network,
|
||||
prefix):
|
||||
name = "system-controller-oam-subnet"
|
||||
def _test_create_address_pool_pass_overlap_with_oam(self, network, prefix):
|
||||
|
||||
oam_pool_name = self._format_pool_name("oam", self.oam_subnet)
|
||||
sysctl_oam_pool_name = self._format_pool_name("system-controller-oam-subnet",
|
||||
self.oam_subnet)
|
||||
|
||||
# First test with different name, which should fail
|
||||
name_1 = f"{name}_1"
|
||||
name_1 = f"{sysctl_oam_pool_name}_1"
|
||||
ndict_1 = self.get_post_object(name_1, network, prefix)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict_1,
|
||||
|
@ -194,11 +196,11 @@ class TestPostMixin(AddressPoolTestCase):
|
|||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(response.status_code, http_client.CONFLICT)
|
||||
self.assertIn(f"Address pool {network}/{prefix} overlaps "
|
||||
f"with oam address pool.",
|
||||
f"with {oam_pool_name} address pool.",
|
||||
response.json['error_message'])
|
||||
|
||||
# Now check with the name: system-controller-oam-subnet
|
||||
ndict_2 = self.get_post_object(name, network, prefix)
|
||||
ndict_2 = self.get_post_object(sysctl_oam_pool_name, network, prefix)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict_2,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -422,7 +424,11 @@ class TestPostMixin(AddressPoolTestCase):
|
|||
network = str(self.mgmt_subnet.network)
|
||||
prefix = self.mgmt_subnet.prefixlen
|
||||
|
||||
ndict = self.get_post_object('management', network, prefix)
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
name = "management"
|
||||
else:
|
||||
name = self._format_pool_name("management", self.mgmt_subnet)
|
||||
ndict = self.get_post_object(name, network, prefix)
|
||||
ndict['gateway_address'] = str(self.mgmt_subnet[1])
|
||||
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2013-2023 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2024 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -556,11 +556,6 @@ class InterfaceTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
|
|||
if key in second:
|
||||
self.assertEqual(first[key], second[key])
|
||||
|
||||
def _find_network_by_type(self, networktype):
|
||||
for network in self.networks:
|
||||
if network['type'] == networktype:
|
||||
return network
|
||||
|
||||
def _find_address_pool_by_uuid(self, pool_uuid):
|
||||
for pool in self.address_pools:
|
||||
if pool['uuid'] == pool_uuid:
|
||||
|
|
|
@ -82,7 +82,7 @@ class NetworkTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
|
|||
return self._create_test_network(
|
||||
name=network_type,
|
||||
network_type=network_type,
|
||||
subnet=self.mgmt_subnet,
|
||||
subnets=self.mgmt_subnets,
|
||||
)
|
||||
|
||||
# Don't create default test networks
|
||||
|
@ -103,31 +103,31 @@ class NetworkTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
|
|||
|
||||
self._create_test_addresses(
|
||||
hostnames,
|
||||
self.mgmt_subnet,
|
||||
self.mgmt_subnets,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.oam_subnet,
|
||||
hostnames, self.oam_subnets,
|
||||
constants.NETWORK_TYPE_OAM)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.cluster_host_subnet,
|
||||
hostnames, self.cluster_host_subnets,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.storage_subnet,
|
||||
hostnames, self.storage_subnets,
|
||||
constants.NETWORK_TYPE_STORAGE)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.admin_subnet,
|
||||
hostnames, self.admin_subnets,
|
||||
constants.NETWORK_TYPE_ADMIN)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.system_controller_subnet,
|
||||
hostnames, self.system_controller_subnets,
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.system_controller_oam_subnet,
|
||||
hostnames, self.system_controller_oam_subnets,
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM)
|
||||
|
||||
|
||||
|
@ -245,9 +245,16 @@ class TestPostMixin(NetworkTestCase):
|
|||
constants.NETWORK_TYPE_PXEBOOT,
|
||||
self.pxeboot_subnet)
|
||||
|
||||
def _get_mgmt_addrpool_name(self):
|
||||
if constants.DUAL_STACK_COMPATIBILITY_MODE:
|
||||
return 'management'
|
||||
if self.primary_address_family == constants.IPV6_FAMILY:
|
||||
return 'management-ipv6'
|
||||
return 'management-ipv4'
|
||||
|
||||
def test_create_success_management(self):
|
||||
self._test_create_network_success(
|
||||
'management',
|
||||
self._get_mgmt_addrpool_name(),
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
self.mgmt_subnet)
|
||||
|
||||
|
@ -321,7 +328,7 @@ class TestPostMixin(NetworkTestCase):
|
|||
|
||||
def test_create_fail_duplicate_management(self):
|
||||
self._test_create_network_fail_duplicate(
|
||||
'management',
|
||||
self._get_mgmt_addrpool_name(),
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
self.mgmt_subnet)
|
||||
|
||||
|
|
|
@ -111,8 +111,6 @@ class NetworkAddrpoolTestCase(base.FunctionalTest, dbbase.BaseHostTestCase):
|
|||
return network
|
||||
|
||||
def _setup_context(self):
|
||||
print("_setup_context")
|
||||
|
||||
self.host0 = self._create_test_host(personality=constants.CONTROLLER, unit=0,
|
||||
id=1, mgmt_ip="1.1.1.1")
|
||||
self.c0_oam_if = dbutils.create_test_interface(ifname='enp0s3', forihostid=self.host0.id)
|
||||
|
@ -151,7 +149,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# Test creation of object
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['management'].uuid)
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -159,9 +157,12 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
# Check that an expected field matches.
|
||||
self.assertEqual(response.json['address_pool_name'], self.address_pools['management'].name)
|
||||
self.assertEqual(response.json['address_pool_id'], self.address_pools['management'].id)
|
||||
self.assertEqual(response.json['address_pool_uuid'], self.address_pools['management'].uuid)
|
||||
self.assertEqual(response.json['address_pool_name'],
|
||||
self.address_pools['management-ipv4'].name)
|
||||
self.assertEqual(response.json['address_pool_id'],
|
||||
self.address_pools['management-ipv4'].id)
|
||||
self.assertEqual(response.json['address_pool_uuid'],
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
self.assertEqual(response.json['network_name'], self.networks[net_type].name)
|
||||
self.assertEqual(response.json['network_id'], self.networks[net_type].id)
|
||||
self.assertEqual(response.json['network_uuid'], self.networks[net_type].uuid)
|
||||
|
@ -169,9 +170,9 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
uuid = response.json['uuid']
|
||||
# Verify that the object was created and some basic attribute matches
|
||||
response = self.get_json(self.get_single_url(uuid))
|
||||
self.assertEqual(response['address_pool_name'], self.address_pools['management'].name)
|
||||
self.assertEqual(response['address_pool_id'], self.address_pools['management'].id)
|
||||
self.assertEqual(response['address_pool_uuid'], self.address_pools['management'].uuid)
|
||||
self.assertEqual(response['address_pool_name'], self.address_pools['management-ipv4'].name)
|
||||
self.assertEqual(response['address_pool_id'], self.address_pools['management-ipv4'].id)
|
||||
self.assertEqual(response['address_pool_uuid'], self.address_pools['management-ipv4'].uuid)
|
||||
self.assertEqual(response['network_name'], self.networks[net_type].name)
|
||||
self.assertEqual(response['network_id'], self.networks[net_type].id)
|
||||
self.assertEqual(response['network_uuid'], self.networks[net_type].uuid)
|
||||
|
@ -195,7 +196,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# add primary
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['management'].uuid)
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -252,7 +253,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# add primary
|
||||
net_type = constants.NETWORK_TYPE_OAM
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['oam'].uuid)
|
||||
self.address_pools['oam-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -367,7 +368,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# add primary
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['management'].uuid)
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -377,7 +378,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
|
||||
# add secondary
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['oam'].uuid)
|
||||
self.address_pools['oam-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS,
|
||||
|
@ -390,7 +391,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# add primary
|
||||
net_type = constants.NETWORK_TYPE_PXEBOOT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['pxeboot'].uuid)
|
||||
self.address_pools['pxeboot-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -413,7 +414,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
# add primary
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['management'].uuid)
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -445,7 +446,7 @@ class TestPostMixin(NetworkAddrpoolTestCase):
|
|||
def test_error_create_network_addrpool_primary_duplicate(self):
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
ndict = self.get_post_object(self.networks[net_type].uuid,
|
||||
self.address_pools['management'].uuid)
|
||||
self.address_pools['management-ipv4'].uuid)
|
||||
response = self.post_json(self.API_PREFIX,
|
||||
ndict,
|
||||
headers=self.API_HEADERS)
|
||||
|
@ -486,7 +487,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['management'].id,
|
||||
address_pool_id=self.address_pools['management-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -507,7 +508,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['management'].id,
|
||||
address_pool_id=self.address_pools['management-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -528,7 +529,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_MGMT
|
||||
net_pool_1 = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['management'].id,
|
||||
address_pool_id=self.address_pools['management-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
net_pool_2 = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['management-ipv6'].id,
|
||||
|
@ -550,7 +551,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
# check that pool_uuid is filled since it was the secondary pool
|
||||
response = self.get_json(self.get_single_network_url(self.networks[net_type].uuid))
|
||||
self.assertEqual(response['pool_uuid'], self.address_pools['management'].uuid)
|
||||
self.assertEqual(response['pool_uuid'], self.address_pools['management-ipv4'].uuid)
|
||||
self.assertEqual(response['type'], self.networks[net_type].type)
|
||||
self.assertEqual(response['primary_pool_family'],
|
||||
self.networks[net_type].primary_pool_family)
|
||||
|
@ -568,7 +569,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_OAM
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['oam'].id,
|
||||
address_pool_id=self.address_pools['oam-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -589,7 +590,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_PXEBOOT
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['pxeboot'].id,
|
||||
address_pool_id=self.address_pools['pxeboot-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -610,7 +611,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_CLUSTER_HOST
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['cluster-host'].id,
|
||||
address_pool_id=self.address_pools['cluster-host-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -631,7 +632,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_CLUSTER_HOST
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['cluster-pod'].id,
|
||||
address_pool_id=self.address_pools['cluster-pod-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -652,7 +653,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_CLUSTER_SERVICE
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['cluster-service'].id,
|
||||
address_pool_id=self.address_pools['cluster-service-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
@ -673,7 +674,7 @@ class TestDelete(NetworkAddrpoolTestCase):
|
|||
|
||||
net_type = constants.NETWORK_TYPE_STORAGE
|
||||
net_pool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=self.address_pools['storage'].id,
|
||||
address_pool_id=self.address_pools['storage-ipv4'].id,
|
||||
network_id=self.networks[net_type].id)
|
||||
|
||||
response = self.delete(self.get_single_url(net_pool.uuid),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2024 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -204,6 +204,15 @@ class TestPatchMixin(OAMNetworkTestCase):
|
|||
self._test_patch_success(patch_obj)
|
||||
|
||||
def test_patch_incomplete(self):
|
||||
fields = {'floating_address_id': None, 'controller0_address_id': None,
|
||||
'controller1_address_id': None, 'gateway_address_id': None}
|
||||
network = self._find_network_by_type(constants.NETWORK_TYPE_OAM)
|
||||
addrpools = self._find_network_address_pools(network.id)
|
||||
for addrpool in addrpools:
|
||||
addresses = self.dbapi.addresses_get_by_pool(addrpool.id)
|
||||
for address in addresses:
|
||||
self.dbapi.address_update(address.uuid, {'address_pool_id': None})
|
||||
self.dbapi.address_pool_update(addrpool.uuid, fields)
|
||||
oam_floating_ip = self.oam_subnet[2] + 100
|
||||
patch_obj = {
|
||||
'oam_floating_ip': str(oam_floating_ip),
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2013-2023 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2024 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
"""Test class for Sysinv ManagerService."""
|
||||
|
@ -5910,13 +5910,15 @@ class ManagerTestCaseInternal(base.BaseHostTestCase):
|
|||
|
||||
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)
|
||||
pool_mgmt4 = self.dbapi.address_pool_query({"name": "management-ipv4"})
|
||||
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)
|
||||
pool_clhost4 = self.dbapi.address_pool_query({"name": "cluster-host-ipv4"})
|
||||
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'
|
||||
|
@ -5972,8 +5974,8 @@ class ManagerTestCaseInternal(base.BaseHostTestCase):
|
|||
|
||||
self.create_ipv6_pools()
|
||||
|
||||
pool_mgmt4 = self.dbapi.address_pool_query({"name": "management"})
|
||||
pool_clhost4 = self.dbapi.address_pool_query({"name": "cluster-host"})
|
||||
pool_mgmt4 = self.dbapi.address_pool_query({"name": "management-ipv4"})
|
||||
pool_clhost4 = self.dbapi.address_pool_query({"name": "cluster-host-ipv4"})
|
||||
net_pools = self.dbapi.network_addrpool_get_all()
|
||||
for net_pool in net_pools:
|
||||
self.dbapi.network_addrpool_destroy(net_pool.uuid)
|
||||
|
|
|
@ -39,6 +39,33 @@ from sysinv.tests import base
|
|||
from sysinv.tests.db import utils as dbutils
|
||||
|
||||
|
||||
PXEBOOT_SUBNET = netaddr.IPNetwork('192.168.202.0/24')
|
||||
|
||||
MGMT_SUBNET_IPV4 = netaddr.IPNetwork('192.168.204.0/24')
|
||||
OAM_SUBNET_IPV4 = netaddr.IPNetwork('10.10.10.0/24')
|
||||
CLUSTER_HOST_SUBNET_IPV4 = netaddr.IPNetwork('192.168.206.0/24')
|
||||
CLUSTER_POD_SUBNET_IPV4 = netaddr.IPNetwork('172.16.0.0/16')
|
||||
CLUSTER_SERVICE_SUBNET_IPV4 = netaddr.IPNetwork('10.96.0.0/12')
|
||||
MULTICAST_SUBNET_IPV4 = netaddr.IPNetwork('239.1.1.0/28')
|
||||
STORAGE_SUBNET_IPV4 = netaddr.IPNetwork('10.10.20.0/24')
|
||||
ADMIN_SUBNET_IPV4 = netaddr.IPNetwork('10.10.30.0/24')
|
||||
SYSTEM_CONTROLLER_SUBNET_IPV4 = netaddr.IPNetwork('192.168.104.0/24')
|
||||
SYSTEM_CONTROLLER_OAM_SUBNET_IPV4 = netaddr.IPNetwork('10.10.50.0/24')
|
||||
NAMESERVERS_IPV4 = ['8.8.8.8', '8.8.4.4']
|
||||
|
||||
MGMT_SUBNET_IPV6 = netaddr.IPNetwork('fd01::/64')
|
||||
OAM_SUBNET_IPV6 = netaddr.IPNetwork('fd00::/64')
|
||||
CLUSTER_HOST_SUBNET_IPV6 = netaddr.IPNetwork('fd02::/64')
|
||||
CLUSTER_POD_SUBNET_IPV6 = netaddr.IPNetwork('fd03::/64')
|
||||
CLUSTER_SERVICE_SUBNET_IPV6 = netaddr.IPNetwork('fd04::/112')
|
||||
MULTICAST_SUBNET_IPV6 = netaddr.IPNetwork('ff08::1:1:0/124')
|
||||
STORAGE_SUBNET_IPV6 = netaddr.IPNetwork('fd05::/64')
|
||||
ADMIN_SUBNET_IPV6 = netaddr.IPNetwork('fd09::/64')
|
||||
SYSTEM_CONTROLLER_SUBNET_IPV6 = netaddr.IPNetwork('fd07::/64')
|
||||
SYSTEM_CONTROLLER_OAM_SUBNET_IPV6 = netaddr.IPNetwork('fd06::/64')
|
||||
NAMESERVERS_IPV6 = ['2001:4860:4860::8888', '2001:4860:4860::8844']
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class DbTestCase(base.TestCase):
|
||||
|
||||
|
@ -49,19 +76,34 @@ class DbTestCase(base.TestCase):
|
|||
|
||||
class BaseIPv4Mixin(object):
|
||||
|
||||
pxeboot_subnet = netaddr.IPNetwork('192.168.202.0/24')
|
||||
mgmt_subnet = netaddr.IPNetwork('192.168.204.0/24')
|
||||
oam_subnet = netaddr.IPNetwork('10.10.10.0/24')
|
||||
cluster_host_subnet = netaddr.IPNetwork('192.168.206.0/24')
|
||||
cluster_pod_subnet = netaddr.IPNetwork('172.16.0.0/16')
|
||||
cluster_service_subnet = netaddr.IPNetwork('10.96.0.0/12')
|
||||
multicast_subnet = netaddr.IPNetwork('239.1.1.0/28')
|
||||
storage_subnet = netaddr.IPNetwork('10.10.20.0/24')
|
||||
admin_subnet = netaddr.IPNetwork('10.10.30.0/24')
|
||||
system_controller_subnet = netaddr.IPNetwork('192.168.104.0/24')
|
||||
system_controller_oam_subnet = netaddr.IPNetwork('10.10.50.0/24')
|
||||
primary_address_family = constants.IPV4_FAMILY
|
||||
secondary_address_family = None
|
||||
|
||||
nameservers = ['8.8.8.8', '8.8.4.4']
|
||||
pxeboot_subnet = PXEBOOT_SUBNET
|
||||
mgmt_subnet = MGMT_SUBNET_IPV4
|
||||
oam_subnet = OAM_SUBNET_IPV4
|
||||
cluster_host_subnet = CLUSTER_HOST_SUBNET_IPV4
|
||||
cluster_pod_subnet = CLUSTER_POD_SUBNET_IPV4
|
||||
cluster_service_subnet = CLUSTER_SERVICE_SUBNET_IPV4
|
||||
multicast_subnet = MULTICAST_SUBNET_IPV4
|
||||
storage_subnet = STORAGE_SUBNET_IPV4
|
||||
admin_subnet = ADMIN_SUBNET_IPV4
|
||||
system_controller_subnet = SYSTEM_CONTROLLER_SUBNET_IPV4
|
||||
system_controller_oam_subnet = SYSTEM_CONTROLLER_OAM_SUBNET_IPV4
|
||||
|
||||
pxeboot_subnets = [PXEBOOT_SUBNET]
|
||||
mgmt_subnets = [MGMT_SUBNET_IPV4]
|
||||
oam_subnets = [OAM_SUBNET_IPV4]
|
||||
cluster_host_subnets = [CLUSTER_HOST_SUBNET_IPV4]
|
||||
cluster_pod_subnets = [CLUSTER_POD_SUBNET_IPV4]
|
||||
cluster_service_subnets = [CLUSTER_SERVICE_SUBNET_IPV4]
|
||||
multicast_subnets = [MULTICAST_SUBNET_IPV4]
|
||||
storage_subnets = [STORAGE_SUBNET_IPV4]
|
||||
admin_subnets = [ADMIN_SUBNET_IPV4]
|
||||
system_controller_subnets = [SYSTEM_CONTROLLER_SUBNET_IPV4]
|
||||
system_controller_oam_subnets = [SYSTEM_CONTROLLER_OAM_SUBNET_IPV4]
|
||||
|
||||
nameservers = NAMESERVERS_IPV4
|
||||
|
||||
# Used to test changing oam from ipv4 to ipv6
|
||||
change_family_oam_subnet = netaddr.IPNetwork('fd00::/64')
|
||||
|
@ -69,24 +111,77 @@ class BaseIPv4Mixin(object):
|
|||
|
||||
class BaseIPv6Mixin(object):
|
||||
|
||||
pxeboot_subnet = netaddr.IPNetwork('192.168.202.0/24')
|
||||
mgmt_subnet = netaddr.IPNetwork('fd01::/64')
|
||||
oam_subnet = netaddr.IPNetwork('fd00::/64')
|
||||
cluster_host_subnet = netaddr.IPNetwork('fd02::/64')
|
||||
cluster_pod_subnet = netaddr.IPNetwork('fd03::/64')
|
||||
cluster_service_subnet = netaddr.IPNetwork('fd04::/112')
|
||||
multicast_subnet = netaddr.IPNetwork('ff08::1:1:0/124')
|
||||
storage_subnet = netaddr.IPNetwork('fd05::/64')
|
||||
admin_subnet = netaddr.IPNetwork('fd09::/64')
|
||||
system_controller_subnet = netaddr.IPNetwork('fd07::/64')
|
||||
system_controller_oam_subnet = netaddr.IPNetwork('fd06::/64')
|
||||
primary_address_family = constants.IPV6_FAMILY
|
||||
secondary_address_family = None
|
||||
|
||||
nameservers = ['2001:4860:4860::8888', '2001:4860:4860::8844']
|
||||
pxeboot_subnet = PXEBOOT_SUBNET
|
||||
mgmt_subnet = MGMT_SUBNET_IPV6
|
||||
oam_subnet = OAM_SUBNET_IPV6
|
||||
cluster_host_subnet = CLUSTER_HOST_SUBNET_IPV6
|
||||
cluster_pod_subnet = CLUSTER_POD_SUBNET_IPV6
|
||||
cluster_service_subnet = CLUSTER_SERVICE_SUBNET_IPV6
|
||||
multicast_subnet = MULTICAST_SUBNET_IPV6
|
||||
storage_subnet = STORAGE_SUBNET_IPV6
|
||||
admin_subnet = ADMIN_SUBNET_IPV6
|
||||
system_controller_subnet = SYSTEM_CONTROLLER_SUBNET_IPV6
|
||||
system_controller_oam_subnet = SYSTEM_CONTROLLER_OAM_SUBNET_IPV6
|
||||
|
||||
pxeboot_subnets = [PXEBOOT_SUBNET]
|
||||
mgmt_subnets = [MGMT_SUBNET_IPV6]
|
||||
oam_subnets = [OAM_SUBNET_IPV6]
|
||||
cluster_host_subnets = [CLUSTER_HOST_SUBNET_IPV6]
|
||||
cluster_pod_subnets = [CLUSTER_POD_SUBNET_IPV6]
|
||||
cluster_service_subnets = [CLUSTER_SERVICE_SUBNET_IPV6]
|
||||
multicast_subnets = [MULTICAST_SUBNET_IPV6]
|
||||
storage_subnets = [STORAGE_SUBNET_IPV6]
|
||||
admin_subnets = [ADMIN_SUBNET_IPV6]
|
||||
system_controller_subnets = [SYSTEM_CONTROLLER_SUBNET_IPV6]
|
||||
system_controller_oam_subnets = [SYSTEM_CONTROLLER_OAM_SUBNET_IPV6]
|
||||
|
||||
nameservers = NAMESERVERS_IPV6
|
||||
|
||||
# Used to test changing oam from ipv6 to ipv4
|
||||
change_family_oam_subnet = netaddr.IPNetwork('10.10.10.0/24')
|
||||
|
||||
|
||||
class BaseDualStackPrimaryIPv4Mixin(BaseIPv4Mixin):
|
||||
|
||||
secondary_address_family = constants.IPV6_FAMILY
|
||||
|
||||
mgmt_subnets = [MGMT_SUBNET_IPV4, MGMT_SUBNET_IPV6]
|
||||
oam_subnets = [OAM_SUBNET_IPV4, OAM_SUBNET_IPV6]
|
||||
cluster_host_subnets = [CLUSTER_HOST_SUBNET_IPV4, CLUSTER_HOST_SUBNET_IPV6]
|
||||
cluster_pod_subnets = [CLUSTER_POD_SUBNET_IPV4, CLUSTER_POD_SUBNET_IPV6]
|
||||
cluster_service_subnets = [CLUSTER_SERVICE_SUBNET_IPV4, CLUSTER_SERVICE_SUBNET_IPV6]
|
||||
multicast_subnets = [MULTICAST_SUBNET_IPV4, MULTICAST_SUBNET_IPV6]
|
||||
storage_subnets = [STORAGE_SUBNET_IPV4, STORAGE_SUBNET_IPV6]
|
||||
admin_subnets = [ADMIN_SUBNET_IPV4, ADMIN_SUBNET_IPV6]
|
||||
system_controller_subnets = [SYSTEM_CONTROLLER_SUBNET_IPV4, SYSTEM_CONTROLLER_SUBNET_IPV6]
|
||||
system_controller_oam_subnets = [SYSTEM_CONTROLLER_OAM_SUBNET_IPV4,
|
||||
SYSTEM_CONTROLLER_OAM_SUBNET_IPV6]
|
||||
|
||||
nameservers = NAMESERVERS_IPV4 + NAMESERVERS_IPV6
|
||||
|
||||
|
||||
class BaseDualStackPrimaryIPv6Mixin(BaseIPv6Mixin):
|
||||
|
||||
secondary_address_family = constants.IPV4_FAMILY
|
||||
|
||||
mgmt_subnets = [MGMT_SUBNET_IPV6, MGMT_SUBNET_IPV4]
|
||||
oam_subnets = [OAM_SUBNET_IPV6, OAM_SUBNET_IPV4]
|
||||
cluster_host_subnets = [CLUSTER_HOST_SUBNET_IPV6, CLUSTER_HOST_SUBNET_IPV4]
|
||||
cluster_pod_subnets = [CLUSTER_POD_SUBNET_IPV6, CLUSTER_POD_SUBNET_IPV4]
|
||||
cluster_service_subnets = [CLUSTER_SERVICE_SUBNET_IPV6, CLUSTER_SERVICE_SUBNET_IPV4]
|
||||
multicast_subnets = [MULTICAST_SUBNET_IPV6, MULTICAST_SUBNET_IPV4]
|
||||
storage_subnets = [STORAGE_SUBNET_IPV6, STORAGE_SUBNET_IPV4]
|
||||
admin_subnets = [ADMIN_SUBNET_IPV6, ADMIN_SUBNET_IPV4]
|
||||
system_controller_subnets = [SYSTEM_CONTROLLER_SUBNET_IPV6, SYSTEM_CONTROLLER_SUBNET_IPV4]
|
||||
system_controller_oam_subnets = [SYSTEM_CONTROLLER_OAM_SUBNET_IPV6,
|
||||
SYSTEM_CONTROLLER_OAM_SUBNET_IPV4]
|
||||
|
||||
nameservers = NAMESERVERS_IPV6 + NAMESERVERS_IPV4
|
||||
|
||||
|
||||
class BaseCephStorageBackendMixin(object):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -135,7 +230,10 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
super(BaseSystemTestCase, self).setUp()
|
||||
self.hosts = []
|
||||
self.address_pools = []
|
||||
self.networks = []
|
||||
self.networks_by_type = {}
|
||||
self.networks_by_id = {}
|
||||
self.address_pools_by_network_id = {}
|
||||
self.addresses_by_id = {}
|
||||
self.network_addrpools = []
|
||||
self.datanetworks = []
|
||||
self._create_test_common()
|
||||
|
@ -152,7 +250,9 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
self.ptp = None
|
||||
self.hosts = []
|
||||
self.address_pools = []
|
||||
self.networks = []
|
||||
self.networks_by_type = {}
|
||||
self.networks_by_id = {}
|
||||
self.address_pools_by_network_id = {}
|
||||
self.network_addrpools = []
|
||||
self.datanetworks = []
|
||||
self.oam = None
|
||||
|
@ -208,27 +308,50 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
self.ptp = dbutils.create_test_ptp(
|
||||
system_id=self.system.id)
|
||||
|
||||
def _create_test_network(self, name, network_type, subnet, ranges=None):
|
||||
address_pool_id = self._create_test_address_pool(name, subnet, ranges).id
|
||||
def _format_pool_name(self, network_name, subnet):
|
||||
if subnet.version == constants.IPV6_FAMILY:
|
||||
family = 'ipv6'
|
||||
else:
|
||||
family = 'ipv4'
|
||||
return network_name + '-' + family
|
||||
|
||||
primary_pool_family = ""
|
||||
if not isinstance(subnet, netaddr.IPNetwork):
|
||||
subnet = netaddr.IPNetwork(subnet)
|
||||
def _create_test_network(self, name, network_type, subnets, link_addresses=False):
|
||||
|
||||
primary_pool_family = constants.IP_FAMILIES[subnet.version]
|
||||
address_pools = []
|
||||
for subnet in subnets:
|
||||
pool_name = self._format_pool_name(name, subnet)
|
||||
address_pool = self._create_test_address_pool(
|
||||
pool_name, subnet, link_addresses=link_addresses)
|
||||
address_pools.append(address_pool)
|
||||
|
||||
primary_pool_family = constants.IP_FAMILIES[subnets[0].version]
|
||||
|
||||
network = dbutils.create_test_network(
|
||||
type=network_type,
|
||||
address_pool_id=address_pool_id,
|
||||
address_pool_id=address_pools[0].id,
|
||||
primary_pool_family=primary_pool_family)
|
||||
|
||||
self.networks.append(network)
|
||||
self._add_network_to_index(network)
|
||||
|
||||
network_addrpool = dbutils.create_test_network_addrpool(address_pool_id=address_pool_id,
|
||||
network_id=network.id)
|
||||
for address_pool in address_pools:
|
||||
network_addrpool = dbutils.create_test_network_addrpool(
|
||||
address_pool_id=address_pool.id, network_id=network.id)
|
||||
self.network_addrpools.append(network_addrpool)
|
||||
self._add_address_pool_to_index(address_pool, network)
|
||||
|
||||
return network
|
||||
|
||||
def _add_network_to_index(self, network):
|
||||
self.networks_by_type[network.type] = network
|
||||
self.networks_by_id[network.id] = network
|
||||
|
||||
def _add_address_pool_to_index(self, addrpool, network):
|
||||
pools = self.address_pools_by_network_id.get(network.id, None)
|
||||
if not pools:
|
||||
pools = []
|
||||
self.address_pools_by_network_id[network.id] = pools
|
||||
pools.append(addrpool)
|
||||
|
||||
def _create_test_route(self, interface, gateway, family=4, network='10.10.10.0', prefix=24):
|
||||
route = dbutils.create_test_route(
|
||||
interface_id=interface.id,
|
||||
|
@ -245,16 +368,20 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
self.datanetworks.append(datanetwork)
|
||||
return datanetwork
|
||||
|
||||
def _create_test_address_pool(self, name, subnet, ranges=None, append=True):
|
||||
def _create_test_address_pool(self, name, subnet, ranges=None, append=True,
|
||||
link_addresses=False):
|
||||
if not ranges:
|
||||
ranges = [(str(subnet[2]), str(subnet[-2]))]
|
||||
base_address = netaddr.IPAddress(subnet[1])
|
||||
gateway_address = None
|
||||
floating_address = None
|
||||
controller0_address = None
|
||||
controller1_address = None
|
||||
if name in ["pxeboot", "management", "oam", "cluster-host", "storage", "admin"]:
|
||||
floating_address = netaddr.IPAddress(ranges[0][0])
|
||||
controller0_address = floating_address + 1
|
||||
controller1_address = floating_address + 2
|
||||
if link_addresses:
|
||||
gateway_address = base_address
|
||||
floating_address = base_address + 1
|
||||
controller0_address = base_address + 2
|
||||
controller1_address = base_address + 3
|
||||
|
||||
pool = dbutils.create_test_address_pool(
|
||||
name=name,
|
||||
|
@ -262,6 +389,7 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
family=subnet.version,
|
||||
prefix=subnet.prefixlen,
|
||||
ranges=ranges,
|
||||
gateway_address=str(gateway_address),
|
||||
floating_address=str(floating_address),
|
||||
controller0_address=str(controller0_address),
|
||||
controller1_address=str(controller1_address))
|
||||
|
@ -273,43 +401,49 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
|
||||
self._create_test_network('pxeboot',
|
||||
constants.NETWORK_TYPE_PXEBOOT,
|
||||
self.pxeboot_subnet)
|
||||
self.pxeboot_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('management',
|
||||
constants.NETWORK_TYPE_MGMT,
|
||||
self.mgmt_subnet)
|
||||
self.mgmt_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('oam',
|
||||
constants.NETWORK_TYPE_OAM,
|
||||
self.oam_subnet)
|
||||
self.oam_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('cluster-host',
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST,
|
||||
self.cluster_host_subnet)
|
||||
self.cluster_host_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('cluster-pod',
|
||||
constants.NETWORK_TYPE_CLUSTER_POD,
|
||||
self.cluster_pod_subnet)
|
||||
self.cluster_pod_subnets)
|
||||
|
||||
self._create_test_network('cluster-service',
|
||||
constants.NETWORK_TYPE_CLUSTER_SERVICE,
|
||||
self.cluster_service_subnet)
|
||||
self.cluster_service_subnets)
|
||||
|
||||
self._create_test_network('storage',
|
||||
constants.NETWORK_TYPE_STORAGE,
|
||||
self.storage_subnet)
|
||||
self.storage_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('admin',
|
||||
constants.NETWORK_TYPE_ADMIN,
|
||||
self.admin_subnet)
|
||||
self.admin_subnets,
|
||||
link_addresses=True)
|
||||
|
||||
self._create_test_network('system-controller',
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER,
|
||||
self.system_controller_subnet)
|
||||
self.system_controller_subnets)
|
||||
|
||||
self._create_test_network('system-controller-oam',
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM,
|
||||
self.system_controller_oam_subnet)
|
||||
self.system_controller_oam_subnets)
|
||||
|
||||
def _create_test_datanetworks(self):
|
||||
|
||||
|
@ -319,12 +453,21 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
self._create_test_datanetwork('data1',
|
||||
constants.DATANETWORK_TYPE_VLAN)
|
||||
|
||||
def _create_test_addresses(self, hostnames, subnet, network_type,
|
||||
def _add_address_to_index(self, address):
|
||||
self.addresses_by_id[address.id] = address
|
||||
|
||||
def _create_test_address(self, **kwargs):
|
||||
address = dbutils.create_test_address(**kwargs)
|
||||
self._add_address_to_index(address)
|
||||
return address
|
||||
|
||||
def _create_test_addresses(self, hostnames, subnets, network_type,
|
||||
start=1, stop=None):
|
||||
ips = itertools.islice(subnet, start, stop)
|
||||
addresses = []
|
||||
for subnet in subnets:
|
||||
ips = itertools.islice(subnet, start, stop)
|
||||
for name in hostnames:
|
||||
address = dbutils.create_test_address(
|
||||
address = self._create_test_address(
|
||||
name=utils.format_address_name(name, network_type),
|
||||
family=subnet.version,
|
||||
prefix=subnet.prefixlen,
|
||||
|
@ -341,36 +484,35 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
]
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.pxeboot_subnet,
|
||||
hostnames, self.pxeboot_subnets,
|
||||
constants.NETWORK_TYPE_PXEBOOT)
|
||||
|
||||
self.mgmt_addresses = self._create_test_addresses(
|
||||
hostnames,
|
||||
self.mgmt_subnet,
|
||||
hostnames, self.mgmt_subnets,
|
||||
constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.oam_subnet,
|
||||
hostnames, self.oam_subnets,
|
||||
constants.NETWORK_TYPE_OAM)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.cluster_host_subnet,
|
||||
hostnames, self.cluster_host_subnets,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.storage_subnet,
|
||||
hostnames, self.storage_subnets,
|
||||
constants.NETWORK_TYPE_STORAGE)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.admin_subnet,
|
||||
hostnames, self.admin_subnets,
|
||||
constants.NETWORK_TYPE_ADMIN)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.system_controller_subnet,
|
||||
hostnames, self.system_controller_subnets,
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER)
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.system_controller_oam_subnet,
|
||||
hostnames, self.system_controller_oam_subnets,
|
||||
constants.NETWORK_TYPE_SYSTEM_CONTROLLER_OAM)
|
||||
|
||||
def _create_test_oam(self):
|
||||
|
@ -386,9 +528,24 @@ class BaseSystemTestCase(BaseIPv4Mixin, DbTestCase):
|
|||
]
|
||||
|
||||
self._create_test_addresses(
|
||||
hostnames, self.multicast_subnet,
|
||||
hostnames, self.multicast_subnets,
|
||||
constants.NETWORK_TYPE_MULTICAST)
|
||||
|
||||
def _get_all_networks(self):
|
||||
return self.networks_by_id.values()
|
||||
|
||||
def _find_network_by_type(self, networktype):
|
||||
return self.networks_by_type.get(networktype, None)
|
||||
|
||||
def _find_network_by_id(self, network_id):
|
||||
return self.networks_by_id.get(network_id, None)
|
||||
|
||||
def _find_network_address_pools(self, network_id):
|
||||
return self.address_pools_by_network_id.get(network_id, [])
|
||||
|
||||
def _find_address_by_id(self, address_id):
|
||||
return self.addresses_by_id.get(address_id, None)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseHostTestCase(BaseSystemTestCase):
|
||||
|
@ -484,10 +641,10 @@ class BaseHostTestCase(BaseSystemTestCase):
|
|||
|
||||
def _create_test_host_addresses(self, hostname):
|
||||
self._create_test_addresses(
|
||||
[hostname], self.mgmt_subnet,
|
||||
[hostname], self.mgmt_subnets,
|
||||
constants.NETWORK_TYPE_MGMT, start=10)
|
||||
self._create_test_addresses(
|
||||
[hostname], self.cluster_host_subnet,
|
||||
[hostname], self.cluster_host_subnets,
|
||||
constants.NETWORK_TYPE_CLUSTER_HOST, start=10)
|
||||
|
||||
def _create_test_host_platform_interface(self, host):
|
||||
|
@ -721,7 +878,8 @@ class OpenstackTestCase(AppTestCase):
|
|||
self._create_test_host_platform_interface(self.host2)
|
||||
self._create_test_host_data_interface(self.host2)
|
||||
self.fake_hieradata = ""
|
||||
with open(os.path.join(os.getcwd(), "sysinv", "tests", "puppet", "fake_hieradata.yaml")) as fake_data:
|
||||
with open(os.path.join(os.getcwd(), "sysinv", "tests",
|
||||
"puppet", "fake_hieradata.yaml")) as fake_data:
|
||||
self.fake_hieradata = fake_data.read()
|
||||
|
||||
|
||||
|
|
|
@ -62,13 +62,14 @@ class DbNetworkTestCaseIPv4(base.BaseHostTestCase):
|
|||
def test_network_addrpool_db(self):
|
||||
|
||||
to_add = [
|
||||
(constants.NETWORK_TYPE_MGMT, ('management', 'management-ipv6')),
|
||||
(constants.NETWORK_TYPE_OAM, ('oam', 'oam-ipv6')),
|
||||
(constants.NETWORK_TYPE_ADMIN, ('admin', 'admin-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_HOST, ('cluster-host', 'cluster-host-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_POD, ('cluster-pod', 'cluster-pod-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_SERVICE, ('cluster-service', 'cluster-service-ipv6')),
|
||||
(constants.NETWORK_TYPE_STORAGE, ('storage', 'storage-ipv6'))
|
||||
(constants.NETWORK_TYPE_MGMT, ('management-ipv4', 'management-ipv6')),
|
||||
(constants.NETWORK_TYPE_OAM, ('oam-ipv4', 'oam-ipv6')),
|
||||
(constants.NETWORK_TYPE_ADMIN, ('admin-ipv4', 'admin-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_HOST, ('cluster-host-ipv4', 'cluster-host-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_POD, ('cluster-pod-ipv4', 'cluster-pod-ipv6')),
|
||||
(constants.NETWORK_TYPE_CLUSTER_SERVICE, ('cluster-service-ipv4',
|
||||
'cluster-service-ipv6')),
|
||||
(constants.NETWORK_TYPE_STORAGE, ('storage-ipv4', 'storage-ipv6'))
|
||||
]
|
||||
|
||||
# test network_addrpool_create()
|
||||
|
@ -101,16 +102,16 @@ class DbNetworkTestCaseIPv4(base.BaseHostTestCase):
|
|||
net_pools = self.dbapi.network_addrpool_get_by_network_id(net.id)
|
||||
self.assertEqual(len(net_pools), 2)
|
||||
self.assertEqual(net_pools[0].network_type, constants.NETWORK_TYPE_MGMT)
|
||||
self.assertEqual(net_pools[0].address_pool_name, "management")
|
||||
self.assertEqual(net_pools[0].address_pool_name, "management-ipv4")
|
||||
self.assertEqual(net_pools[1].network_type, constants.NETWORK_TYPE_MGMT)
|
||||
self.assertEqual(net_pools[1].address_pool_name, "management-ipv6")
|
||||
|
||||
# test network_addrpool_get_by_pool_id()
|
||||
pool4 = self.dbapi.address_pool_query({'name': 'management'})
|
||||
pool4 = self.dbapi.address_pool_query({'name': 'management-ipv4'})
|
||||
net_pools = self.dbapi.network_addrpool_get_by_pool_id(pool4.id)
|
||||
self.assertEqual(len(net_pools), 1)
|
||||
self.assertEqual(net_pools[0].address_pool_id, pool4.id)
|
||||
self.assertEqual(net_pools[0].address_pool_name, 'management')
|
||||
self.assertEqual(net_pools[0].address_pool_name, 'management-ipv4')
|
||||
|
||||
# test network_addrpool_query()
|
||||
net_pool_q = self.dbapi.network_addrpool_query({'address_pool_id': pool4.id,
|
||||
|
@ -152,7 +153,7 @@ class DbNetworkTestCaseIPv4(base.BaseHostTestCase):
|
|||
'controller-mgmt', constants.IPV6_FAMILY)
|
||||
|
||||
self._create_test_addresses(hostnames=[constants.CONTROLLER_HOSTNAME],
|
||||
subnet=netaddr.IPNetwork('fd01::/64'),
|
||||
subnets=[netaddr.IPNetwork('fd01::/64')],
|
||||
network_type=constants.NETWORK_TYPE_MGMT)
|
||||
|
||||
addr = self.dbapi.address_get_by_name_and_family('controller-mgmt',
|
||||
|
|
|
@ -730,31 +730,39 @@ def create_test_address_pool(**kw):
|
|||
controller1_address = address_pool.pop('controller1_address', None)
|
||||
gateway_address = address_pool.pop('gateway_address', None)
|
||||
|
||||
addresses = []
|
||||
if floating_address:
|
||||
try:
|
||||
fl_addr = dbapi.address_get_by_address(floating_address)
|
||||
addresses.append(fl_addr)
|
||||
address_pool['floating_address_id'] = fl_addr.id
|
||||
except Exception:
|
||||
pass
|
||||
if controller0_address:
|
||||
try:
|
||||
c0_addr = dbapi.address_get_by_address(controller0_address)
|
||||
addresses.append(c0_addr)
|
||||
address_pool['controller0_address_id'] = c0_addr.id
|
||||
except Exception:
|
||||
pass
|
||||
if controller1_address:
|
||||
try:
|
||||
c1_addr = dbapi.address_get_by_address(controller1_address)
|
||||
addresses.append(c1_addr)
|
||||
address_pool['controller1_address_id'] = c1_addr.id
|
||||
except Exception:
|
||||
pass
|
||||
if gateway_address:
|
||||
try:
|
||||
c1_addr = dbapi.address_get_by_address(gateway_address)
|
||||
address_pool['gateway_address_id'] = c1_addr.id
|
||||
gw_addr = dbapi.address_get_by_address(gateway_address)
|
||||
addresses.append(gw_addr)
|
||||
address_pool['gateway_address_id'] = gw_addr.id
|
||||
except Exception:
|
||||
pass
|
||||
return dbapi.address_pool_create(address_pool)
|
||||
db_address_pool = dbapi.address_pool_create(address_pool)
|
||||
for address in addresses:
|
||||
dbapi.address_update(address.uuid, {'address_pool_id': db_address_pool.id})
|
||||
return db_address_pool
|
||||
|
||||
|
||||
def get_test_address(**kw):
|
||||
|
@ -1363,6 +1371,18 @@ def create_test_interface(**kw):
|
|||
forihostid = kw.get('forihostid')
|
||||
interface_obj = dbapi.iinterface_create(forihostid, interface)
|
||||
|
||||
ipv4_mode = interface.get('ipv4_mode', None)
|
||||
if ipv4_mode:
|
||||
dbapi.address_mode_update(interface_obj.id,
|
||||
{'family': constants.IPV4_FAMILY, 'mode': ipv4_mode})
|
||||
interface_obj.ipv4_mode = ipv4_mode
|
||||
|
||||
ipv6_mode = interface.get('ipv6_mode', None)
|
||||
if ipv6_mode:
|
||||
dbapi.address_mode_update(interface_obj.id,
|
||||
{'family': constants.IPV6_FAMILY, 'mode': ipv6_mode})
|
||||
interface_obj.ipv6_mode = ipv6_mode
|
||||
|
||||
# assign the network to the interface
|
||||
for network in networks_list:
|
||||
if not network:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -49,11 +49,6 @@ class NetworkingTestCaseMixin(base.PuppetTestCaseMixin):
|
|||
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
|
||||
|
@ -259,11 +254,11 @@ class NetworkingTestTestCaseControllerDualStackIPv4Primary(NetworkingTestCaseMix
|
|||
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],
|
||||
self._create_test_addresses(hostnames=hosts, subnets=[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],
|
||||
subnets=[cfgdata[1][0]],
|
||||
network_type=cfgdata[0], start=1, stop=2)
|
||||
self.network_addrpools.append(network_addrpool)
|
||||
|
||||
|
@ -398,11 +393,11 @@ class NetworkingTestTestCaseControllerDualStackIPv6Primary(NetworkingTestCaseMix
|
|||
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],
|
||||
self._create_test_addresses(hostnames=hosts, subnets=[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],
|
||||
subnets=[cfgdata[1][0]],
|
||||
network_type=cfgdata[0], start=1, stop=2)
|
||||
self.network_addrpools.append(network_addrpool)
|
||||
|
||||
|
|
|
@ -61,11 +61,6 @@ class PlatformFirewallTestCaseMixin(base.PuppetTestCaseMixin):
|
|||
def _setup_configuration(self):
|
||||
pass
|
||||
|
||||
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
|
||||
|
|
|
@ -102,6 +102,7 @@ commands =
|
|||
scripts/query_pci_id
|
||||
|
||||
[testenv:py39]
|
||||
passenv = TOX_DEBUG_LEVEL
|
||||
commands =
|
||||
stestr run {posargs}
|
||||
stestr slowest
|
||||
|
|
Loading…
Reference in New Issue