diff --git a/scripts/READMEmd b/scripts/READMEmd new file mode 100644 index 0000000000000000000000000000000000000000..eddfe1936b791a31654ec872c490986fd5a6990a --- /dev/null +++ b/scripts/READMEmd @@ -0,0 +1,147 @@ +# Custom Script to initialise data in Netbox + + +## The Script +**universal_init_data** is the script is used to initialise data inside netbox. It can be used to create all types of objects in Netbox by following a specific structure in the data file. + + +## The Data Files + +This script uses Json files placed in the folder opt/netbox/netbox/scripts/data* + +##### Structure: + +The data file follow a specific structure and specific fields that will be used to generate objects and relationships between them, for example: + +- **object_type**: Used to refer to which object will be created. Usually the names correspond to the model name in singular form and lowercase (matches the ContentType for that object, check database table **django_content_type**). + The models can be found using the `manage.py` command: + ```bash + manage.py nbshell -c "lsmodels()" + ``` + if needed mode information can be checked with the command: + ```bash + manage.py nbshell -c "help(<model name>)" + ``` +- **assigned_object**: Used to create relationships between objects that are connected by assigned object relations + + +The rest of the fields are specific for each type of object. The required fields follow the same logic as the UI forms. + + +Example on how to create a simple object, a Site and a Cluster Type: +```json +[ + { + "object_type": "site", + "name": "Site", + "status": "active", + "slug": "site1", + "description": "init site" + }, + { + "object_type": "clustertype", + "name": "cluster-name", + "slug": "clustername", + "description": "cluster Type description" + }, + ] +``` + +To create a simple relatonship between netbox objects we just need to include the property `{"name":""}` in the field responsible for the relationship. For example when we connect the previously created objects, Site and Cluster type, to a new Cluster: +##### Foreign key relations: +```json +[ + { + "object_type": "cluster", + "name": "cluster name", + "status": "active", + "type":{"name":"cluster-name"}, + "site":{"name":"Site"}, + "description": "cluster description" + } + ] +``` + +##### Assigned_object relation: +In some cases, mainly plugins that extend the netbox data model like Mac Address Plugin and SYS plugin, we can connect objects based on the assigned object logic. In this case we need to specify the property `{"name":""}` and also the type of object we want to connect with by using the property `{"object_type":""}` in a field called `"assigned_object":{}` +```json +[ + { + "object_type": "virtualmachinetype", + "virtual_machine_type_name": "LARGE", + "virtual_machine_type_desc": "Large VM Type", + "assigned_object": {"name":"cluster-name","object_type":"clustertype"} + } + ] +``` + +##### Roles and Permissions: + +Roles can be created by simply specifying the correct object type and the name of the group +```json +[ + { + "object_type": "group", + "name": "SuperUser" + }, + { + "object_type": "group", + "name": "Administrator" + }, +``` + +To create permissions for specific objects (objects in netbox and plugins) and add the previously created groups we need to follow a specific rules and structure: + +- The name of Permission will be created using some parts: `Name` of the permission + `Object_type.model` value + (`Object_type.app_label`). For the example described, the permission will be called **View Cable (Dcim)** . This was done this way due to the fact that multiple `Object_type.app_label` can use the same name for `Object_type.model`, for example: **Add Device (Dcim)** and **Add Device (Netbox_docker_plugin)** + +- To assign groups to this permisson we use the field `groups` with the property `{"name":""}` with the name of the group + +- To assign object types to this permisson we use the field `object_types` with the properties `{"app_label":""}` and `{"model":""}` where `app_label` refers to the "aplication" that the object is part and `model` refers to the model class of the object. +*If there is access to the database this logic can be checked based on the table **django_content_type** + +```json + { + "object_type": "ObjectPermission", + "name": "view", + "enabled": "True", + "groups": [ + { + "name": "SuperUser" + }, + { + "name": "Administrator" + } + ], + "object_types": [ + { + "app_label": "dcim", + "model": "cable" + } + ] + } + ] +``` + +## How to execute the script + +During netbox startup a row is inserted in the table core_managedfile, the table that manages the files uploaded, with the help of Django: +```django +ManagedFile.objects.get_or_create(data_path="universal_init_data.py",file_root="scripts",file_path="universal_init_data.py") +``` +This record makes it possbile to use the script in two different ways: + +##### UI +The script is available in the UI by using the menu **Customization** > **Scripts**. +The script can use the path to the data file inside the **netbox container** or the updaload of a **file** + +##### CLI +The script can be executed by using Netbox `manage.py` in combination with the option `runscript` from inside the netbox container. +To load a data file we need to specify a variable called `file_path` by using an encapsulated JSON blob with option `--data`, for example: + +From inside the netbox docker container: +```bash +python manage.py runscript universal_init_data.InitializeJsonDataScript --data '{"file_path":"/opt/netbox/netbox/scripts/data/data_file.json"}' --commit +``` +If we don´t include the `--commit` option the script will performe a dry execution, no record will be inserted. + +