mirror of
https://opendev.org/openstack/ironic.git
synced 2026-01-11 19:57:20 +00:00
Merge "Trait Based Networking Simulator"
This commit is contained in:
commit
6362fa4663
3 changed files with 175 additions and 0 deletions
37
tools/trait_based_networking/network_objects.yaml.sample
Normal file
37
tools/trait_based_networking/network_objects.yaml.sample
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
ports:
|
||||
- uuid: fake_uuid_0001
|
||||
address: aa:bb:cc:dd:ee:00
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
- uuid: fake_uuid_0002
|
||||
address: aa:bb:cc:dd:ee:01
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
- uuid: fake_uuid_0003
|
||||
address: aa:bb:cc:dd:ee:02
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
- uuid: fake_uuid_0004
|
||||
address: aa:bb:cc:dd:ee:03
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
- uuid: fake_uuid_0005
|
||||
address: aa:bb:cc:dd:ee:04
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
portgroups:
|
||||
- uuid: fake_uuid_0001
|
||||
address: aa:bb:cc:dd:ee:01
|
||||
category: storage
|
||||
physical_network: fabric_a
|
||||
vendor: purple
|
||||
networks:
|
||||
- network_id: fake_net_id_01
|
||||
name: test_network
|
||||
tags:
|
||||
- test
|
||||
115
tools/trait_based_networking/simulator.py
Executable file
115
tools/trait_based_networking/simulator.py
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python3
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import ironic.common.trait_based_networking.base as tbn
|
||||
import ironic.common.trait_based_networking.config_file as tbn_config
|
||||
import ironic.common.trait_based_networking.plan as tbn_plan
|
||||
|
||||
import ironic.tests.unit.common.trait_based_networking.utils as test_utils
|
||||
|
||||
import argparse
|
||||
import yaml
|
||||
|
||||
arg_parser = argparse.ArgumentParser(
|
||||
prog="Trait Based Networking Simulator",
|
||||
description=("See how TBN will plan a network for a node given a set "
|
||||
"of network traits, ports, portgroups, etc."))
|
||||
|
||||
arg_parser.add_argument('config_file')
|
||||
arg_parser.add_argument('network_file')
|
||||
|
||||
|
||||
def main():
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
cf = tbn_config.ConfigFile(args.config_file)
|
||||
print("Read Trait Based Networking configuration file "
|
||||
f"'{args.config_file}'")
|
||||
valid, reasons = cf.validate()
|
||||
if not valid:
|
||||
print(f"'{args.config_file}' is NOT valid!")
|
||||
for reason in reasons:
|
||||
print(f"ERROR: {reason}")
|
||||
print("Please correct these errors and try again.")
|
||||
return
|
||||
print("Configuration is valid.")
|
||||
|
||||
cf.parse()
|
||||
print("Parsed configuration.")
|
||||
for trait in cf.traits():
|
||||
print(f"Got trait '{trait.name}' with {len(trait.actions)} action(s).")
|
||||
print("")
|
||||
|
||||
print("Loading test set of network objects (ports, portgroups, networks) "
|
||||
f"from '{args.network_file}'")
|
||||
data = TestNetworkDataFile(args.network_file)
|
||||
print("Test set loaded.")
|
||||
print(f"Got {len(data.ports())} test ports.")
|
||||
print(f"Got {len(data.portgroups())} test portgroups.")
|
||||
print(f"Got {len(data.networks())} test networks.")
|
||||
print("")
|
||||
|
||||
for trait in cf.traits():
|
||||
print(f"Planning based on trait '{trait.name}':")
|
||||
actions = tbn_plan.plan_network(trait,
|
||||
"fake_node_uuid",
|
||||
data.ports(),
|
||||
data.portgroups(),
|
||||
data.networks())
|
||||
print(f"Got {len(actions)} actions:")
|
||||
for action in actions:
|
||||
print(f" {str(action)}")
|
||||
print("")
|
||||
|
||||
|
||||
class TestNetworkDataFile(object):
|
||||
def __init__(self, filename):
|
||||
self._filename = filename
|
||||
self.read()
|
||||
|
||||
def read(self):
|
||||
with open(self._filename, 'r') as file:
|
||||
self._contents = yaml.safe_load(file)
|
||||
|
||||
for typename in ['ports', 'portgroups', 'networks']:
|
||||
assert typename in self._contents, (f"no {typename} were found in "
|
||||
"the test data file!")
|
||||
|
||||
self._ports = [
|
||||
tbn.Port(test_utils.FauxPortLikeObject(**port))
|
||||
for port in self._contents['ports']
|
||||
]
|
||||
|
||||
self._portgroups = [
|
||||
tbn.Portgroup(test_utils.FauxPortLikeObject(**portgroup))
|
||||
for portgroup in self._contents['portgroups']
|
||||
]
|
||||
|
||||
self._networks = [
|
||||
tbn.Network(**network)
|
||||
for network in self._contents['networks']
|
||||
]
|
||||
|
||||
def ports(self):
|
||||
return self._ports
|
||||
|
||||
def portgroups(self):
|
||||
return self._portgroups
|
||||
|
||||
def networks(self):
|
||||
return self._networks
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
23
tools/trait_based_networking/tbn_trait_config.yaml.sample
Normal file
23
tools/trait_based_networking/tbn_trait_config.yaml.sample
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
CUSTOM_TRAIT_NAME:
|
||||
- action: bond_ports
|
||||
filter: port.vendor == 'clover'
|
||||
min_count: 2
|
||||
CUSTOM_DIRECT_ATTACH_A_PURPLE_TO_STORAGE:
|
||||
- action: attach_port
|
||||
filter: port.vendor == 'purple' && port.category == 'storage'
|
||||
CUSTOM_BOND_PURPLE_BY_2:
|
||||
- action: group_and_attach_ports
|
||||
filter: port.vendor == 'purple'
|
||||
max_count: 2
|
||||
CUSTOM_BOND_GREEN_STORAGE_TO_STORAGE_BY_2:
|
||||
- action: group_and_attach_ports
|
||||
filter: port.vendor == 'green' && port.category == 'storage'
|
||||
max_count: 2
|
||||
min_count: 2
|
||||
CUSTOM_USE_PHYSNET_A_OR_B:
|
||||
- action: attach_port
|
||||
filter: port.physical_network == 'fabric_a'
|
||||
min_count: 2
|
||||
max_count: 4
|
||||
- action: attach_portgroup
|
||||
filter: port.vendor == 'purple'
|
||||
Loading…
Add table
Reference in a new issue