#!/usr/bin/env python3

# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
# SPDX-License-Identifier: Apache-2.0

# pxeconfig.py
# Given a yaml config file (same as ansible inventory for a site), create a
# YAML file consumable by ansible that has input for the pxeboot role, for creating
# preseed files for servers

from __future__ import absolute_import

import nbhelper
from ruamel import yaml

# main function that calls other functions
if __name__ == "__main__":

    # this is passed to argparse, key is option name, rest is kwargs
    extra_args = {
        "domain_extension": {
            "default": "aetherproject.net",
            "nargs": "?",
            "type": ascii,
            "help": "Domain extension (optional, default: aetherproject.net)",
        },
    }

    args = nbhelper.initialize(extra_args)
    tenant = nbhelper.Tenant()

    yaml_out = {}
    pxeboot_hosts = []

    for device in tenant.get_devices():

        # only pxeboot for servers
        if device.data.device_role.slug in ["server", "router"]:

            pxe_dev = {}
            pxe_dev["hostname"] = device.data["name"]
            pxe_dev["domain"] = args.domain_extension

            if device.data["serial"]:
                pxe_dev["serial"] = device.data["serial"]

            if device.primary_iface["mac_address"]:
                pxe_dev["mac_address"] = device.primary_iface["mac_address"].lower()

            pxeboot_hosts.append(pxe_dev)

    #    yaml_out["devices"] = devices
    yaml_out["pxeboot_hosts"] = pxeboot_hosts

    print(yaml.safe_dump(yaml_out, indent=2))
