Skip to content

Add the possibility to specify a custom name for network scenario configuration file from the Python API  #261

@tcaiazzi

Description

@tcaiazzi

Currently, the LabParser.parse() method only accepts a configuration file called lab.conf.

@staticmethod
def parse(path: str) -> Lab:
"""Parse the lab.conf and return the corresponding Kathara network scenario.
Args:
path (str): The path to lab.conf file.
Returns:
Kathara.model.Lab.Lab: A Kathara network scenario.
"""
lab_conf_path = os.path.join(path, 'lab.conf')
if not os.path.exists(lab_conf_path):
raise IOError("No lab.conf in given directory.")
if os.stat(lab_conf_path).st_size == 0:
raise IOError("lab.conf file is empty.")
# Reads lab.conf in memory so it is faster.
try:
with open(lab_conf_path, 'r') as lab_file:
lab_mem_file = mmap.mmap(lab_file.fileno(), 0, access=mmap.ACCESS_READ)
except Exception:
raise IOError("Cannot open lab.conf file.")
lab = Lab(None, path=path)
line_number = 1
line = lab_mem_file.readline().decode('utf-8')
while line:
matches = re.search(
r"^(?P<key>[a-z0-9_]{1,30})\[(?P<arg>\w+)\]=([\"\']?)(?P<value>[^\"\']+)(\3)(\s+\#.*)?$",
line.strip()
)
if matches:
key = matches.group("key").strip()
arg = matches.group("arg").strip()
value = matches.group("value").replace('"', '').replace("'", '')
if key in RESERVED_MACHINE_NAMES:
raise ValueError(f"In lab.conf - Line {line_number}: "
f"`{key}` is a reserved name, you can not use it for a device.")
try:
# It's an interface, handle it.
interface_number = int(arg)
if re.search(r"^\w+$", value):
lab.connect_machine_to_link(key, value, machine_iface_number=interface_number)
else:
raise SyntaxError(f"In lab.conf - Line {line_number}: "
f"Collision domain `{value}` contains non-alphanumeric characters.")
except ValueError:
# Not an interface, add it to the machine metas.
if lab.assign_meta_to_machine(key, arg, value) is not None:
logging.warning(f"In lab.conf - Line {line_number}: "
f"Device `{key}` already has a value assigned to meta `{arg}`. "
f"Previous value has been overwritten with `{value}`.")
else:
if not line.startswith('#') and \
line.strip():
if not any([line.startswith(f"{x}=") for x in LAB_METADATA]):
raise SyntaxError(f"In lab.conf - Line {line_number}: `{line}`.")
else:
(key, value) = line.split("=")
key = key.replace("LAB_", "").lower()
setattr(lab, key, value.replace('"', '').replace("'", '').strip())
line_number += 1
line = lab_mem_file.readline().decode('utf-8')
lab.check_integrity()
return lab

Adding the possibility to specify the name of the configuration file will improve flexibility.

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions