NAT MCH module usage¶
This page includes some examples about the usage of the
gendev_tools.nat_mch.nat_mch.NATMCH class. This is not a
thoroughful description neither of the implementation nor the child modules.
If looking for such information, visit the previous link to the module.
The NATMCH class offers two main features: retrieving the values for some configuration parameters of the MCH; and the modification of those values. Unfortunately, the interface is not as user-friendly as it should be: not all the values can be directly sent through this module. The backplane configuration needs a TFTP server that delivers a particular configuration file for the backplane.
3 main workflows are distinguished:
Retrieval of some subset of values for the configuration of an MCH.
Modification of some subset of values for the configuration of an MCH.
Modification of the backplane configuration.
The values for the MCH configuration can be defined within a text file using the YAML language. In brief, a configuration file includes one or more dictionaries defining pairs of a configuration setting name and the assigned value to it. Example files can be obtained at the ESS Confluence portal.
Data retrieval from the MCH¶
Running any of the get methods is the easiest way to get in contact with the data formatting expected by the module. If you’re unsure about what settings can be specified, the valid values for those, or anything, just retrieve the configuration you aim to change first.
This is a simple code snippet that shows how to retrieve the device information and the values for the PCIe Virtual Switch. Then, the result is stored in a file using the YAML module.
The MHC is connected is accessible in the network, so that, the
gendev_tools.gendev_interface.ConnType.ETHER. The type of backplane
is also needed to be specified using an instance of
gendev_tools.nat_mch.nat_mch.BackplaneType
import yaml
from pprint import pprint
from collections import OrderedDict
from gendev_tools.nat_mch.nat_mch import NATMCH, BackplaneType
from gendev_tools.gendev_interface import ConnType
# Change the IP!
mch = NATMCH(
ip_address="172.30.5.255",
allowed_conn=[ConnType.ETHER],
backplane=BackplaneType.B3U,
)
valid, info = mch.device_info()
# This will print the main information for the target MCH
if valid:
pprint(info)
# Let's get the PCIe configuration, if you don't know what values
# you have to pass to the method, read the docs!
# help(mch.get_configuration)
# The key for retrieving the PCIe Virtual Switch conf is "pcie"
valid, config = mch.get_configuration("pcie")
if valid:
pprint(config)
# Now, let's write that configuration to a file, some tricks are needed
# when using OrderedDicts:
def represent_dictionary_order(self, dict_data):
return self.represent_mapping("tag:yaml.org,2002:map", dict_data.items())
def setup_yaml():
yaml.add_representer(OrderedDict, represent_dictionary_order)
setup_yaml()
with open(
'mch_{serial_num}.yaml'.format_map(info['Board']), 'w'
) as configfile:
yaml.dump(config, configfile)
The previous example retrieves the PCIe Network Switch configuration for the MCH and writes it to a file keeping the same ordered as information is found in the web page of the MCH. Using OrderedDict objects is not a strict requirement, regular dictionaries can be used instead, but ordering is not guaranteed in the later.
Changing the configuration of the MCH¶
This example needs a configuration file in the same folder where your code is running. An example of configuration file can be obtained at Confluence. Now, we aim to set the base configuration of the MCH using the values from a file. This procedure is shown in the following code snippet:
import yaml
from pprint import pprint
from collections import OrderedDict
from gendev_tools.nat_mch.nat_mch import NATMCH, BackplaneType
from gendev_tools.gendev_interface import ConnType
# Again, this trick forces the yaml parser to use OrderedDict objects
# rather than regular dict objects
def represent_dictionary_order(self, dict_data):
return self.represent_mapping("tag:yaml.org,2002:map", dict_data.items())
def setup_yaml():
yaml.add_representer(OrderedDict, represent_dictionary_order)
setup_yaml()
# Change the IP!
mch = NATMCH(
ip_address="172.30.5.255",
allowed_conn=[ConnType.ETHER],
backplane=BackplaneType.B3U,
)
valid, info = mch.device_info()
# This will print the main information for the target MCH
if valid:
pprint(info)
# Once we know the MCH is alive and reachable, let's load the file and
# push it to the MCH:
with open("mch_3u_golden.yaml", "r") as configfile:
config = yaml.safe_load(configfile)
# Check the docs if you don't know what values are needed!
# help(mch.set_configuration)
# Using apply=True, we force the MCH to reboot. The method returns after
# some delay, but sometimes the MCH takes even more time to get back.
mch.set_configuration('basecfg', config, apply=True)
# If running an interactive session, just wait a few minutes or use
# device_info() to detect when the MCH is alive. Anyway, all the
# methods raise an exception when the host is down.
# Finally, let's check that the values in the MCH match what we have in the
# configuration file.
valid, message = mch.check_configuration('basecfg', config)
if not valid:
print(message)
else:
print('The base configuration is good!')
Backplane configuration¶
The backplane configuration was somewhat tricky to implement. While accessing it using a get method or running a sanity check is available using the regular ConnType.ETHER, changing it needs the Telnet backend (ConnType.TELNET) or the MOXA backend, and a TFTP server with the target configuration file.
The following example needs a TFTP server and the Telnet server enabled in the MCH configuration. By default, the NATMCH module points to a server inside the ESS intranet, the address of the server can be changed if needed, read the docs of the module!
from gendev_tools.nat_mch.nat_mch import NATMCH, BackplaneType
from gendev_tools.gendev_interface import ConnType
# Change the IP!
mch = NATMCH(
ip_address="172.30.5.255",
allowed_conn=[ConnType.ETHER, ConnType.TELNET],
backplane=BackplaneType.B3U,
)
valid, info = mch.device_info()
# This will print the main information for the target MCH
if valid:
pprint(info)
# This time, a simple dictionary will be created containing the needed
# information, but the procedure from the previous examples can be
# used as well.
config = {
'Backplane configuration': {
'option': 'generic'
}
}
# This will reboot the MCH, use the argument `apply` to change this
# behaviour.
valid, message = mch.set_configuration('backplane', config)
if not valid:
print(message)
Checking the backplane configuration follows a similar procedure as the one shown for the check of the base configuration. In this case, read the txt file with the backplane configuration in a str and add the extra key file to the previous dictionary:
# Read the content of the file to backplanecfg
config = {
'Backplane configuration': {
'option': 'generic',
'file': backplanecfg,
}
}