#!/usr/bin/env python3

#   -------------------------------------------------------------
#   NetBox - migrate gateways fields
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   Project:        Nasqueron
#   Description:    Copy a singleton in a list in NetBox
#   Dependencies:   pynetbox
#   License:        BSD-2-Clause
#   -------------------------------------------------------------


import pynetbox
import yaml


#   -------------------------------------------------------------
#   Get NetBox config and credentials
#
#   Salt configuration is used to get credentials.
#   As a fallback, ~/.config/netbox/auth.yaml is used.
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


def get_netbox_config_from_salt():
    config_path = "/usr/local/etc/salt/master.d/netbox.conf"

    if not os.path.exists(config_path):
        return False, None

    with open(config_path) as fd:
        salt_config = yaml.safe_load(fd)
        salt_config = salt_config["ext_pillar"][0]["netbox"]
        return True, {
            "server": salt_config["api_url"].replace("/api/", ""),
            "token": salt_config["api_token"],
        }


def get_netbox_config_from_config_dir():
    try:
        config_path = os.path.join(os.environ["HOME"], ".config", "netbox", "auth.yaml")
    except KeyError:
        return False, None

    if not os.path.exists(config_path):
        return False, None

    with open(config_path) as fd:
        return True, yaml.safe_load(fd)


def get_netbox_config():
    methods = [get_netbox_config_from_salt, get_netbox_config_from_config_dir]

    for method in methods:
        has_config, config = method()
        if has_config:
            return config

    raise RuntimeError("Can't find NetBox config")


def connect_to_netbox(config):
    return pynetbox.api(config["server"], token=config["token"])


#   -------------------------------------------------------------
#   NetBox migration
#
#   Migrate a custom field with only one object to a field
#   accepting several objects.
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


def migrate_object(object, singleton_old_field, new_field):
    value = object.custom_fields[singleton_old_field]

    if value is not None:
        object.custom_fields[new_field] = [value]
        object.save()


def migrate(objects, singleton_old_field, new_field):
    for object in objects:
        migrate_object(object, singleton_old_field, new_field)


#   -------------------------------------------------------------
#   Application entry point
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


def run():
    config = get_netbox_config()
    nb = connect_to_netbox(config)

    migrate(nb.dcim.interfaces.all(), "default_gw", "default_gateways")
    migrate(
        nb.virtualization.interfaces.all(), "default_gw_virt", "default_gateways_virt"
    )


if __name__ == "__main__":
    run()