From 7c400dd5fab4070b0e0c02597d72a94449730193 Mon Sep 17 00:00:00 2001 From: Guillaume Mazoyer Date: Thu, 13 Dec 2018 22:51:53 +0100 Subject: [PATCH] Rework the whole role for NetBox 2.5. Only support Debian 9 for now but the role will be extend later. All the role has been rewritten. NetBox is now setup using a virtualenv to avoid messing with the Python dependencies in the system. Also rework variables to set, mostly to configure NetBox. --- .gitignore | 12 ++ .travis.yml | 6 - README.md | 29 ++-- defaults/main.yml | 38 +++-- handlers/main.yml | 9 +- meta/main.yml | 8 +- tasks/include-vars.yml | 28 ---- tasks/include_vars.yml | 33 ++++ tasks/install-packages.yml | 33 ---- tasks/install_packages.yml | 12 ++ tasks/main.yml | 29 +++- tasks/setup-netbox.yml | 97 ------------ ...{setup-database.yml => setup_database.yml} | 7 +- tasks/setup_netbox.yml | 147 ++++++++++++++++++ ...-web-backend.yml => setup_web_backend.yml} | 22 +-- ...eb-frontend.yml => setup_web_frontend.yml} | 1 - templates/configuration.py.j2 | 136 ++-------------- templates/gunicorn_config.py.j2 | 7 - templates/gunicorn_process.sh.j2 | 27 ++++ templates/netbox.conf.j2 | 5 +- templates/netbox_vhost.conf.j2 | 4 +- tests/test.yml | 4 +- vars/Debian.yml | 29 ++-- vars/Ubuntu-18.04.yml | 49 ------ vars/main.yml | 19 +++ 25 files changed, 366 insertions(+), 425 deletions(-) create mode 100644 .gitignore delete mode 100644 tasks/include-vars.yml create mode 100644 tasks/include_vars.yml delete mode 100644 tasks/install-packages.yml create mode 100644 tasks/install_packages.yml delete mode 100644 tasks/setup-netbox.yml rename tasks/{setup-database.yml => setup_database.yml} (61%) create mode 100644 tasks/setup_netbox.yml rename tasks/{setup-web-backend.yml => setup_web_backend.yml} (55%) rename tasks/{setup-web-frontend.yml => setup_web_frontend.yml} (95%) delete mode 100644 templates/gunicorn_config.py.j2 create mode 100644 templates/gunicorn_process.sh.j2 delete mode 100644 vars/Ubuntu-18.04.yml create mode 100644 vars/main.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b23dd85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +### VirtualEnv ### +.Python +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +[Ss]hare +pyvenv.cfg +.venv +pip-selfcheck.json diff --git a/.travis.yml b/.travis.yml index 2950e35..5ae6cce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,12 +6,6 @@ env: - distro: debian9 init: /lib/systemd/systemd run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" - - distro: ubuntu1604 - init: /lib/systemd/systemd - run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" - - distro: ubuntu1804 - init: /lib/systemd/systemd - run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" before_install: - 'docker pull gmazoyer/ansible-docker-${distro}:latest' diff --git a/README.md b/README.md index 72caba6..1ad44f2 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Setup for the PostgreSQL database: Where to get NetBox and which version: - netbox_version: v2.3.4 + netbox_version: v2.5.1 netbox_git_url: https://github.com/digitalocean/netbox.git Where to install NetBox: @@ -50,16 +50,12 @@ Set the timezone to be used (a list of available TZs can be found netbox_config_time_zone: UTC -The username and email for the super user. Its password must be set manually -via the manage.py tool of the application: +The username, password and email for the super user. netbox_superuser_username: admin + netbox_superuser_password: admin netbox_superuser_email: admin@example.com -Force user to login to see data recorded inside NetBox: - - netbox_login_required: false - LDAP can be used as authentication mechanism. It must be enabled, and the whole LDAP configuration has to be provided in the following variables (see NetBox [documentation](http://netbox.readthedocs.io/en/latest/installation/ldap/)): @@ -67,23 +63,32 @@ LDAP configuration has to be provided in the following variables (see NetBox netbox_setup_ldap_auth: false netbox_ldap_config: "" -NAPALM integration with username and password to be used when connecting to -devices: +NAPALM integration, please note that you must set the username and password for +NAPALM in the configuration otherwise it will not be enabled: netbox_use_napalm: false - netbox_devices_username: '' - netbox_devices_password: '' Whether or not to load the initial data of NetBox: netbox_load_initial_data: true +The configuration for NetBox must be given as `key: value` pairs like the +following, please note that the secret key does not need to be given as it will +be generated automatically: + + netbox_config: + ALLOWED_HOSTS: + - localhost + - 127.0.0.1 + TIME_ZONE: "Europe/Paris" + … + Configuration for the backend web servers: netbox_setup_web_backend: false netbox_gunicorn_address: 127.0.0.1 netbox_gunicorn_port: 8001 - netbox_gunicorn_workers_number: 3 + netbox_gunicorn_workers_number: 4 netbox_gunicorn_user: root netbox_supervisor_user: root diff --git a/defaults/main.yml b/defaults/main.yml index c6e3fac..1e52e73 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,26 +1,20 @@ --- -# Database related variables (password must be changed) -netbox_database: netbox -netbox_database_user: netbox -netbox_database_password: netbox -netbox_database_host: localhost - # Git URL and version to use, version must be a Git tag -netbox_version: v2.3.4 +netbox_version: v2.5.1 netbox_git_url: https://github.com/digitalocean/netbox.git # Where to install Netbox netbox_install_directory: /opt/netbox +netbox_virtualenv_path: "{{ netbox_install_directory }}/venv" -# Configuration settings, to be ajusted, especially the secret key -netbox_config_allowed_hosts: - - localhost - - netbox.example.com -netbox_config_secret_key: R+9A&c7R935e(5pI5t!_8s1(hXGHmUIUm!X+)O-^Js4bII12_t -netbox_config_time_zone: UTC +# Which user/group should own the files +netbox_user: netbox +netbox_group: netbox +netbox_user_home_directory: /home/netbox # Mostly used for the first setup, superuser password still need to be set netbox_superuser_username: admin +netbox_superuser_password: admin netbox_superuser_email: admin@example.com netbox_load_initial_data: true @@ -41,9 +35,21 @@ netbox_ldap_config: "" netbox_setup_web_backend: false netbox_gunicorn_address: 127.0.0.1 netbox_gunicorn_port: 8001 -netbox_gunicorn_workers_number: 3 -netbox_gunicorn_user: root -netbox_supervisor_user: root +netbox_gunicorn_workers_number: 4 # Web frontend variables (not configured by default) netbox_setup_web_frontend: false + +# Database related variables (password must be changed) +netbox_database: netbox +netbox_database_user: netbox +netbox_database_password: netbox +netbox_database_host: localhost + +# Configuration +netbox_config: + ALLOWED_HOSTS: + - localhost + - 127.0.0.1 + MEDIA_ROOT: "{{ netbox_install_directory }}/netbox/media" + REPORTS_ROOT: "{{ netbox_install_directory }}/netbox/reports" diff --git a/handlers/main.yml b/handlers/main.yml index f19d892..81a7c30 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,5 +1,12 @@ --- +- name: restart netbox + supervisorctl: + name: netbox + state: restarted + when: netbox_setup_web_backend + - name: restart apache2 service: name: "{{ apache2_service }}" - state: restarted \ No newline at end of file + state: restarted + when: netbox_setup_web_frontend diff --git a/meta/main.yml b/meta/main.yml index 27f89bf..cb47cf9 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,17 +1,13 @@ --- galaxy_info: author: Guillaume Mazoyer - description: A role to install and update Netbox. + description: A role to install and update NetBox. license: GPL-3+ - min_ansible_version: 2.1.0 + min_ansible_version: 2.5.0 platforms: - name: Debian versions: - stretch - - name: Ubuntu - versions: - - xenial - - bionic galaxy_tags: - system - networking diff --git a/tasks/include-vars.yml b/tasks/include-vars.yml deleted file mode 100644 index 15cac72..0000000 --- a/tasks/include-vars.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -# Include variables and define needed ones -- name: include OS-specific variables - include_vars: "{{ item }}" - with_first_found: - - "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" - - "{{ ansible_distribution }}.yml" - - "{{ ansible_os_family }}.yml" - -- name: define postgresql packages - set_fact: - postgresql_packages: "{{ __postgresql_packages | list }}" - when: postgresql_packages is not defined - -- name: define dependencies packages - set_fact: - dependencies_packages: "{{ __dependencies_packages | list }}" - when: dependencies_packages is not defined - -- name: define web backend packages - set_fact: - web_backend_packages: "{{ __web_backend_packages | list }}" - when: web_backend_packages is not defined - -- name: define web frontend packages - set_fact: - web_frontend_packages: "{{ __web_frontend_packages | list }}" - when: web_frontend_packages is not defined \ No newline at end of file diff --git a/tasks/include_vars.yml b/tasks/include_vars.yml new file mode 100644 index 0000000..dfdde17 --- /dev/null +++ b/tasks/include_vars.yml @@ -0,0 +1,33 @@ +--- +# Include variables and define needed ones +- name: include os-specific variables + include_vars: "{{ item }}" + with_first_found: + - "{{ ansible_distribution | lower }}-{{ ansible_distribution_version }}.yml" + - "{{ ansible_distribution | lower }}.yml" + - "{{ ansible_os_family | lower }}.yml" + +- name: define python packages + set_fact: + netbox_python_packages: "{{ __netbox_python_packages | list }}" + when: netbox_python_packages is not defined + +- name: define postgresql packages + set_fact: + netbox_postgresql_packages: "{{ __netbox_postgresql_packages | list }}" + when: netbox_postgresql_packages is not defined + +- name: define other packages + set_fact: + netbox_other_packages: "{{ __netbox_other_packages | list }}" + when: netbox_other_packages is not defined + +- name: define web backend packages + set_fact: + netbox_web_backend_packages: "{{ __netbox_web_backend_packages | list }}" + when: netbox_web_backend_packages is not defined + +- name: define web frontend packages + set_fact: + netbox_web_frontend_packages: "{{ __netbox_web_frontend_packages | list }}" + when: netbox_web_frontend_packages is not defined diff --git a/tasks/install-packages.yml b/tasks/install-packages.yml deleted file mode 100644 index cbbada0..0000000 --- a/tasks/install-packages.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -# Install and setup tasks -- name: install postgresql - package: - name: "{{ item }}" - state: present - with_items: "{{ postgresql_packages }}" - -- name: ensure postgresql is started - service: - name: "{{ postgresql_service }}" - enabled: yes - state: started - -- name: install dependencies - package: - name: "{{ item }}" - state: present - with_items: "{{ dependencies_packages }}" - -- name: install web backend tools - package: - name: "{{ item }}" - state: present - with_items: "{{ web_backend_packages }}" - when: netbox_setup_web_backend - -- name: install web frontend tools - package: - name: "{{ item }}" - state: present - with_items: "{{ web_frontend_packages }}" - when: netbox_setup_web_frontend \ No newline at end of file diff --git a/tasks/install_packages.yml b/tasks/install_packages.yml new file mode 100644 index 0000000..4ccf6d4 --- /dev/null +++ b/tasks/install_packages.yml @@ -0,0 +1,12 @@ +--- +- name: install required packages + package: + name: "{{ __netbox_required_packages | flatten}}" + state: present + vars: + __netbox_required_packages: + - "{{ netbox_python_packages }}" + - "{{ netbox_postgresql_packages }}" + - "{{ netbox_other_packages }}" + - "{{ netbox_web_backend_packages if netbox_setup_web_backend else [] }}" + - "{{ netbox_web_frontend_packages if netbox_setup_web_frontend else [] }}" diff --git a/tasks/main.yml b/tasks/main.yml index 8f20fb1..32c779c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,14 +1,27 @@ --- -- include: include-vars.yml +- import_tasks: include_vars.yml +- import_tasks: install_packages.yml -- include: install-packages.yml +- name: ensure python 3 is used + set_fact: + ansible_python_interpreter: "{{ netbox_python_binary }}" -- include: setup-database.yml +- block: + - name: create netbox group + group: + name: "{{ netbox_group }}" -- include: setup-netbox.yml + - name: create netbox user + user: + name: "{{ netbox_user }}" + group: "{{ netbox_group }}" + home: "{{ netbox_user_home_directory }}" -- include: setup-web-backend.yml - when: netbox_setup_web_backend +- import_tasks: setup_database.yml + when: netbox_database_host == 'localhost' +- import_tasks: setup_netbox.yml -- include: setup-web-frontend.yml - when: netbox_setup_web_frontend \ No newline at end of file +- include: setup_web_backend.yml + when: netbox_setup_web_backend +- include: setup_web_frontend.yml + when: netbox_setup_web_frontend diff --git a/tasks/setup-netbox.yml b/tasks/setup-netbox.yml deleted file mode 100644 index 95eee6d..0000000 --- a/tasks/setup-netbox.yml +++ /dev/null @@ -1,97 +0,0 @@ ---- -# Setup Netbox -- name: check if there is a netbox install - stat: - path: "{{ netbox_install_directory }}" - register: netbox_installed - -- name: download netbox using git - git: - repo: "{{ netbox_git_url }}" - version: "{{ netbox_version }}" - dest: "{{ netbox_install_directory }}" - register: netbox_downloaded - -- name: install virtualenv using pip - pip: - name: virtualenv - extra_args: "--upgrade" - executable: "{{ netbox_pip_binary }}" - -- name: install napalm for pulling devices info - pip: - name: napalm - extra_args: "--upgrade" - virtualenv: "{{ netbox_install_directory }}" - virtualenv_python: "{{ netbox_python_binary }}" - when: netbox_use_napalm and (netbox_devices_username is defined) and - (netbox_devices_password is defined) - -- block: - - name: delete stale bytecode - command: find . -name '*.pyc' -delete - args: - chdir: "{{ netbox_install_directory }}" - - - name: install python requirements - pip: - requirements: "{{ netbox_install_directory }}/requirements.txt" - extra_args: "--upgrade" - virtualenv: "{{ netbox_install_directory }}" - virtualenv_python: "{{ netbox_python_binary }}" - when: netbox_downloaded.changed - -- name: configure netbox - template: - src: configuration.py.j2 - dest: "{{ netbox_install_directory }}/netbox/netbox/configuration.py" - owner: root - group: root - mode: 0644 - -- block: - - name: install django-auth-ldap - pip: - name: django-auth-ldap - extra_args: "--upgrade" - virtualenv: "{{ netbox_install_directory }}" - virtualenv_python: "{{ netbox_python_binary }}" - - - name: configure ldap auth - copy: - content: "{{ netbox_ldap_config }}" - dest: "{{ netbox_install_directory }}/netbox/netbox/ldap_config.py" - owner: root - group: root - mode: 0644 - when: netbox_setup_ldap_auth - -- block: - - name: perform database migration - django_manage: - app_path: "{{ netbox_install_directory }}/netbox" - command: migrate - virtualenv: "{{ netbox_install_directory }}" - - - name: collect static files - django_manage: - app_path: "{{ netbox_install_directory }}/netbox" - command: collectstatic - virtualenv: "{{ netbox_install_directory }}" - when: netbox_downloaded.changed - -- block: - - name: create super user - django_manage: - app_path: "{{ netbox_install_directory }}/netbox" - command: "createsuperuser --noinput --username={{ netbox_superuser_username }} --email={{ netbox_superuser_email }}" - virtualenv: "{{ netbox_install_directory }}" - - - name: load initial data - django_manage: - app_path: "{{ netbox_install_directory }}/netbox" - command: loaddata - fixtures: initial_data - virtualenv: "{{ netbox_install_directory }}" - when: netbox_load_initial_data - when: not netbox_installed.stat.exists diff --git a/tasks/setup-database.yml b/tasks/setup_database.yml similarity index 61% rename from tasks/setup-database.yml rename to tasks/setup_database.yml index a0c688d..923e397 100644 --- a/tasks/setup-database.yml +++ b/tasks/setup_database.yml @@ -1,11 +1,9 @@ --- -# Create database and its user - name: create postgresql database postgresql_db: name: "{{ netbox_database }}" become: true - become_method: "{{ become_method_to_use }}" - become_user: "{{ postgresql_user }}" + become_user: "{{ __netbox_postgresql_user }}" - name: create postgresql user postgresql_user: @@ -15,5 +13,4 @@ db: "{{ netbox_database }}" priv: ALL become: true - become_method: "{{ become_method_to_use }}" - become_user: "{{ postgresql_user }}" + become_user: "{{ __netbox_postgresql_user }}" diff --git a/tasks/setup_netbox.yml b/tasks/setup_netbox.yml new file mode 100644 index 0000000..bf53c3c --- /dev/null +++ b/tasks/setup_netbox.yml @@ -0,0 +1,147 @@ +--- +- name: check if there is an existing installation + stat: + path: "{{ netbox_install_directory }}" + register: netbox_installed + +- name: create the install directory + file: + path: "{{ netbox_install_directory }}" + owner: "{{ netbox_user }}" + group: "{{ netbox_group }}" + state: directory + when : not netbox_installed.stat.exists + +- name: download using git + git: + repo: "{{ netbox_git_url }}" + version: "{{ netbox_version }}" + dest: "{{ netbox_install_directory }}" + become: true + become_user: "{{ netbox_user }}" + register: netbox_downloaded + +- name: upgrade pip in virtualenv + pip: + name: pip + extra_args: "--upgrade" + virtualenv: "{{ netbox_virtualenv_path }}" + virtualenv_command: "{{ netbox_python_binary }} -m venv" + become: true + become_user: "{{ netbox_user }}" + +- name: install napalm for pulling devices info + pip: + name: napalm + extra_args: "--upgrade" + virtualenv: "{{ netbox_virtualenv_path }}" + virtualenv_command: "{{ netbox_python_binary }} -m venv" + become: true + become_user: "{{ netbox_user }}" + when: > + netbox_use_napalm + and (netbox_config.NAPALM_USERNAME is defined) + and (netbox_config.NAPALM_PASSWORD is defined) + +- block: + - name: delete stale bytecode + command: find . -name '*.pyc' -delete + args: + chdir: "{{ netbox_install_directory }}" + + - name: install python requirements + pip: + requirements: "{{ netbox_install_directory }}/requirements.txt" + extra_args: "--upgrade" + virtualenv: "{{ netbox_virtualenv_path }}" + virtualenv_command: "{{ netbox_python_binary }} -m venv" + become: true + become_user: "{{ netbox_user }}" + notify: + - restart netbox + when: netbox_downloaded.changed + +- block: + - name: generate a secret key + shell: "{{ netbox_python_binary }} {{ netbox_install_directory }}/netbox/generate_secret_key.py | tr -d $'\n' > {{ netbox_user_home_directory }}/secret.key" + args: + creates: "{{ netbox_user_home_directory }}/secret.key" + become: true + become_user: "{{ netbox_user }}" + + - name: load secret key + slurp: + src: "{{ netbox_user_home_directory }}/secret.key" + register: __netbox_secret_key_file + + - name: set secret key in configuration + set_fact: + netbox_config: "{{ netbox_config | combine({'SECRET_KEY': __netbox_secret_key_file['content'] | b64decode}) }}" + +- name: configure netbox + template: + src: configuration.py.j2 + dest: "{{ netbox_install_directory }}/netbox/netbox/configuration.py" + owner: "{{ netbox_user }}" + group: "{{ netbox_group }}" + mode: 0644 + notify: + - restart netbox + +- block: + - name: install django-auth-ldap + pip: + name: django-auth-ldap + extra_args: "--upgrade" + virtualenv: "{{ netbox_virtualenv_path }}" + virtualenv_command: "{{ netbox_python_binary }} -m venv" + become: true + become_user: "{{ netbox_user }}" + - name: configure ldap auth + copy: + content: "{{ netbox_ldap_config }}" + dest: "{{ netbox_install_directory }}/netbox/netbox/ldap_config.py" + owner: "{{ netbox_user }}" + group: "{{ netbox_group }}" + mode: 0644 + notify: + - restart netbox + when: netbox_setup_ldap_auth + +- block: + - name: perform database migration + django_manage: + app_path: "{{ netbox_install_directory }}/netbox" + command: migrate + virtualenv: "{{ netbox_virtualenv_path }}" + become: true + become_user: "{{ netbox_user }}" + notify: + - restart netbox + - name: collect static files + django_manage: + app_path: "{{ netbox_install_directory }}/netbox" + command: collectstatic + clear: yes + virtualenv: "{{ netbox_virtualenv_path }}" + become: true + become_user: "{{ netbox_user }}" + when: netbox_downloaded.changed + +- block: + - name: create super user + shell: "printf '{{ netbox_superuser_script }}' | {{ netbox_virtualenv_path }}/bin/python {{ netbox_install_directory }}/netbox/manage.py shell" + become: true + become_user: "{{ netbox_user }}" + register: __netbox_superuser_result + changed_when: "'changed' in __netbox_superuser_result.stdout" + - name: load initial data + django_manage: + app_path: "{{ netbox_install_directory }}/netbox" + command: loaddata + fixtures: initial_data + virtualenv: "{{ netbox_virtualenv_path }}" + become: true + become_user: "{{ netbox_user }}" + when: netbox_load_initial_data + when: not netbox_installed.stat.exists diff --git a/tasks/setup-web-backend.yml b/tasks/setup_web_backend.yml similarity index 55% rename from tasks/setup-web-backend.yml rename to tasks/setup_web_backend.yml index 96313fc..e315251 100644 --- a/tasks/setup-web-backend.yml +++ b/tasks/setup_web_backend.yml @@ -1,19 +1,20 @@ --- -# Setup web backend if enabled - name: install gunicorn pip: name: gunicorn extra_args: "--upgrade" - virtualenv: "{{ netbox_install_directory }}" - virtualenv_python: "{{ netbox_python_binary }}" + virtualenv: "{{ netbox_virtualenv_path }}" + virtualenv_command: "{{ netbox_python_binary }} -m venv" + become: true + become_user: "{{ netbox_user }}" - name: configure gunicorn template: - src: gunicorn_config.py.j2 - dest: "{{ netbox_install_directory }}/gunicorn_config.py" - owner: root - group: root - mode: 0644 + src: gunicorn_process.sh.j2 + dest: "{{ netbox_user_home_directory }}/gunicorn_process.sh" + owner: "{{ netbox_user }}" + group: "{{ netbox_group }}" + mode: 0755 register: gunicorn_config - name: configure supervisord @@ -34,5 +35,6 @@ supervisorctl: name: netbox state: restarted - when: gunicorn_config.changed or supervisord_config.changed or - netbox_downloaded.changed + when: > + gunicorn_config.changed or supervisord_config.changed + or netbox_downloaded.changed diff --git a/tasks/setup-web-frontend.yml b/tasks/setup_web_frontend.yml similarity index 95% rename from tasks/setup-web-frontend.yml rename to tasks/setup_web_frontend.yml index c5e8c66..da40ee2 100644 --- a/tasks/setup-web-frontend.yml +++ b/tasks/setup_web_frontend.yml @@ -1,5 +1,4 @@ --- -# Setup web frontend if enabled - name: enable mod_proxy and mod_proxy_http apache2_module: state: present diff --git a/templates/configuration.py.j2 b/templates/configuration.py.j2 index e4ac7d5..39c73bd 100644 --- a/templates/configuration.py.j2 +++ b/templates/configuration.py.j2 @@ -1,127 +1,15 @@ -######################### -# # -# Required settings # -# # -######################### - -# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write -# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. -# -# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local'] -ALLOWED_HOSTS = [ -{% for host in netbox_config_allowed_hosts %} - '{{ host }}', -{% endfor %} -] - -# PostgreSQL database configuration. DATABASE = { - 'NAME': '{{ netbox_database }}', # Database name - 'USER': '{{ netbox_database_user }}', # PostgreSQL username - 'PASSWORD': '{{ netbox_database_password }}', # PostgreSQL password - 'HOST': '{{ netbox_database_host }}', # Database server - 'PORT': '', # Database port (leave blank for default) + 'NAME': '{{ netbox_database }}', + 'USER': '{{ netbox_database_user }}', + 'PASSWORD': '{{ netbox_database_password }}', + 'HOST': '{{ netbox_database_host }}', + 'PORT': '{{ netbox_database_port | default('') }}', } -# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. -# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and -# symbols. NetBox will not run without this defined. For more information, see -# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY -SECRET_KEY = '{{ netbox_config_secret_key }}' - - -######################### -# # -# Optional settings # -# # -######################### - -# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of -# application errors (assuming correct email settings are provided). -ADMINS = [ - # ['John Doe', 'jdoe@example.com'], -] - -# Optionally display a persistent banner at the top and/or bottom of every page. To display the same content in both -# banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP. -BANNER_TOP = '' -BANNER_BOTTOM = '' - -# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set: -# BASE_PATH = 'netbox/' -BASE_PATH = '' - -# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be -# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or -# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers -CORS_ORIGIN_ALLOW_ALL = False -CORS_ORIGIN_WHITELIST = [ - # 'hostname.example.com', -] -CORS_ORIGIN_REGEX_WHITELIST = [ - # r'^(https?://)?(\w+\.)?example\.com$', -] - -# Email settings -EMAIL = { - 'SERVER': 'localhost', - 'PORT': 25, - 'USERNAME': '', - 'PASSWORD': '', - 'TIMEOUT': 10, # seconds - 'FROM_EMAIL': '', -} - -# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space within the global table -# (all prefixes and IP addresses not assigned to a VRF), set ENFORCE_GLOBAL_UNIQUE to True. -ENFORCE_GLOBAL_UNIQUE = False - -# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users -# are permitted to access most data in NetBox (excluding secrets) but not make any changes. -LOGIN_REQUIRED = {{ netbox_login_required | default('False')  }} - -# Setting this to True will display a "maintenance mode" banner at the top of every page. -MAINTENANCE_MODE = False - -# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g. -# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request -# all objects by specifying "?limit=0". -MAX_PAGE_SIZE = 1000 - -# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that -# the default value of this setting is derived from the installed location. -# MEDIA_ROOT = '/opt/netbox/netbox/media' - -# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM. -NAPALM_USERNAME = '{{ netbox_devices_username | default('') }}' -NAPALM_PASSWORD = '{{ netbox_devices_password | default('') }}' - -# NAPALM timeout (in seconds). (Default: 30) -NAPALM_TIMEOUT = 30 - -# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must -# be provided as a dictionary. -NAPALM_ARGS = {} - -# Determine how many objects to display per page within a list. (Default: 50) -PAGINATE_COUNT = 50 - -# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to -# prefer IPv4 instead. -PREFER_IPV4 = False - -# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of -# this setting is derived from the installed location. -# REPORTS_ROOT = '/opt/netbox/netbox/reports' - -# Time zone (default: UTC) -TIME_ZONE = '{{ netbox_config_time_zone }}' - -# Date/time formatting. See the following link for supported formats: -# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date -DATE_FORMAT = 'N j, Y' -SHORT_DATE_FORMAT = 'Y-m-d' -TIME_FORMAT = 'g:i a' -SHORT_TIME_FORMAT = 'H:i:s' -DATETIME_FORMAT = 'N j, Y g:i a' -SHORT_DATETIME_FORMAT = 'Y-m-d H:i' +{% for setting, value in netbox_config.items() %} +{% if value in [True, False] %} +{{ setting }} = {{ 'True' if value else 'False' }} +{% else %} +{{ setting }} = {{ value | to_nice_json }} +{% endif %} +{% endfor %} diff --git a/templates/gunicorn_config.py.j2 b/templates/gunicorn_config.py.j2 deleted file mode 100644 index 41a56f3..0000000 --- a/templates/gunicorn_config.py.j2 +++ /dev/null @@ -1,7 +0,0 @@ -# {{ ansible_managed }} - -command = '{{ netbox_install_directory }}/bin/gunicorn' -pythonpath = '{{ netbox_install_directory }}/netbox' -bind = '{{ netbox_gunicorn_address }}:{{ netbox_gunicorn_port }}' -workers = {{ netbox_gunicorn_workers_number }} -user = '{{ netbox_gunicorn_user }}' diff --git a/templates/gunicorn_process.sh.j2 b/templates/gunicorn_process.sh.j2 new file mode 100644 index 0000000..3ab9553 --- /dev/null +++ b/templates/gunicorn_process.sh.j2 @@ -0,0 +1,27 @@ +#!/bin/bash + +# {{ ansible_managed }} + +NAME="netbox" +DJANGODIR={{ netbox_install_directory }}/netbox/ +USER={{ netbox_user }} +GROUP={{ netbox_group }} +NUM_WORKERS={{ netbox_gunicorn_workers_number }} +DJANGO_SETTINGS_MODULE=netbox.settings + +echo "Starting ${NAME} as $(whoami)" + +# Activate the virtual environment +source {{ netbox_virtualenv_path }}/bin/activate +export DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE} +export PYTHONPATH=${DJANGODIR}:${PYTHONPATH} + +# Start your Django Unicorn +# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon) +exec {{ netbox_virtualenv_path }}/bin/gunicorn ${NAME}.wsgi:application \ + --name ${NAME} \ + --workers ${NUM_WORKERS} \ + --user=${USER} --group=${GROUP} \ + --bind '{{ netbox_gunicorn_address }}:{{ netbox_gunicorn_port }}' + --log-level=debug \ + --log-file=- diff --git a/templates/netbox.conf.j2 b/templates/netbox.conf.j2 index d4a0f2d..c088352 100644 --- a/templates/netbox.conf.j2 +++ b/templates/netbox.conf.j2 @@ -1,6 +1,5 @@ # {{ ansible_managed }} [program:netbox] -command = {{ netbox_install_directory }}/bin/gunicorn -c {{ netbox_install_directory }}/gunicorn_config.py netbox.wsgi -directory = {{ netbox_install_directory }}/netbox/ -user = {{ netbox_supervisor_user }} +command = {{ netbox_user_home_directory }}/gunicorn_process.sh +user = {{ netbox_user }} diff --git a/templates/netbox_vhost.conf.j2 b/templates/netbox_vhost.conf.j2 index 02d41ad..ccaf656 100644 --- a/templates/netbox_vhost.conf.j2 +++ b/templates/netbox_vhost.conf.j2 @@ -1,10 +1,10 @@ # {{ ansible_managed }} -{% for host in netbox_config_allowed_hosts %} +{% for host in netbox_config.ALLOWED_HOSTS %} ServerName {{ host }} - Alias /static {{ netbox_install_directory}}/netbox/static + Alias /static {{ netbox_install_directory }}/netbox/static # Needed to allow token-based API authentication WSGIPassAuthorization on diff --git a/tests/test.yml b/tests/test.yml index e380d78..775efa3 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -2,5 +2,7 @@ - hosts: localhost remote_user: root + vars: + netbox_setup_web_backend: true roles: - - role_under_test \ No newline at end of file + - role_under_test diff --git a/vars/Debian.yml b/vars/Debian.yml index 300a342..a129aa0 100644 --- a/vars/Debian.yml +++ b/vars/Debian.yml @@ -1,42 +1,39 @@ --- -__postgresql_packages: +__netbox_python_packages: + - python3.5 + - python3.5-dev + - python3-venv + - python3-pip + - python3-psycopg2 +__netbox_postgresql_packages: - postgresql - libpq-dev - python-psycopg2 -__dependencies_packages: +__netbox_other_packages: - git - - python3.5 - - python3.5-dev - - python3-pip - libxml2-dev - libxslt1-dev - libffi-dev - libjpeg-dev - graphviz - - libpq-dev - libssl-dev - - zlib1g-dev -__ldap_packages: +__netbox_ldap_packages: - libldap2-dev - libsasl2-dev -__web_backend_packages: +__netbox_web_backend_packages: - supervisor - -__web_frontend_packages: +__netbox_web_frontend_packages: - apache2 - apache2-utils - libapache2-mod-wsgi netbox_python_binary: /usr/bin/python3.5 -netbox_pip_binary: pip3 - -become_method_to_use: su -postgresql_service: postgresql -postgresql_user: postgres +__netbox_postgresql_service: postgresql +__netbox_postgresql_user: postgres supervisord_service: supervisor supervisord_config_directory: /etc/supervisor/conf.d diff --git a/vars/Ubuntu-18.04.yml b/vars/Ubuntu-18.04.yml deleted file mode 100644 index 85bb519..0000000 --- a/vars/Ubuntu-18.04.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -__postgresql_packages: - - postgresql - - libpq-dev - - python-psycopg2 - -__dependencies_packages: - - git - - python3.6 - - python3.6-dev - - python3-pip - - libxml2-dev - - libxslt1-dev - - libffi-dev - - libjpeg-dev - - graphviz - - libpq-dev - - libssl-dev - - zlib1g-dev - -__ldap_packages: - - libldap2-dev - - libsasl2-dev - -__web_backend_packages: - - supervisor - -__web_frontend_packages: - - apache2 - - apache2-utils - - libapache2-mod-wsgi - -netbox_python_binary: /usr/bin/python3.6 -netbox_pip_binary: pip3 - -become_method_to_use: su - -postgresql_service: postgresql -postgresql_user: postgres - -supervisord_service: supervisor -supervisord_config_directory: /etc/supervisor/conf.d - -apache2_service: apache2 -apache2_user: www-data -apache2_group: www-data -apache2_sites_available_path: /etc/apache2/sites-available -apache2_sites_enabled_path: /etc/apache2/sites-enabled -apache2_default_vhost: 000-default.conf diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..99e38f2 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,19 @@ +--- +netbox_virtualenv_directory: "{{ netbox_install_directory }}/venv-py3" +netbox_superuser_script: | + from django.contrib.auth.models import User + from base64 import b64decode + password = b64decode("{{ netbox_superuser_password | b64encode }}").decode("UTF-8") + query = User.objects.filter(username="{{ netbox_superuser_username }}") + if not query.exists(): + User.objects.create_superuser("{{ netbox_superuser_username }}", "{{ netbox_superuser_email }}", password) + print("changed") + else: + user = User.objects.get(username="{{ netbox_superuser_username }}") + if not user.is_superuser or user.email != "{{ netbox_superuser_email }}" or not user.check_password(password): + user.is_superuser = True + user.is_staff = True + user.email = "{{ netbox_superuser_email }}" + user.set_password(password) + user.save() + print("changed")