diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 4550afe..99bb42e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,13 +1,14 @@ name: Lint on: + pull_request: workflow_dispatch: # Allows you to reuse this workflow from other workflows workflow_call: jobs: lint: - runs-on: [ self-hosted ] + runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/ci-scripts/init.sh b/ci-scripts/init.sh new file mode 100755 index 0000000..4f7290f --- /dev/null +++ b/ci-scripts/init.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +_PODMAN_RUN="sudo podman run --security-opt label=disable --rm -v $PWD:/code -w /code" + +GALAXY_EXTRA_FILE=galaxy-requirements-extra.yml + +if [ -f "$PWD/$GALAXY_EXTRA_FILE" ] +then + export GALAXY_INSTALL="ansible-galaxy collection install \ + -r /code/$GALAXY_EXTRA_FILE" + echo "Found $GALAXY_EXTRA_FILE will load addtional modules" +else + export GALAXY_INSTALL='echo "No additional galaxy collecions specified"' +fi + +echo ">> Working directory: ${PWD}" diff --git a/ci-scripts/lint.sh b/ci-scripts/lint.sh old mode 100644 new mode 100755 index 3110f32..91b6123 --- a/ci-scripts/lint.sh +++ b/ci-scripts/lint.sh @@ -4,5 +4,8 @@ set -e source $PWD/ci-scripts/init.sh ${_PODMAN_RUN} \ - ghcr.io/nerc-project/nerc-ansible-container:sha-11ab902 \ - /srv/docker-ansible/env/bin/ansible-lint $@ + ghcr.io/nerc-project/nerc-ansible-container:sha-61be9eb \ + bash -l -c \ + ". /srv/docker-ansible/env/bin/activate; + $GALAXY_INSTALL; + ansible-lint $@" diff --git a/init.sh b/init.sh deleted file mode 100644 index 8604b82..0000000 --- a/init.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e - -_PODMAN_RUN="sudo podman run --security-opt label=disable --rm -v $PWD:/code -w /code" - -echo ">> Working directory: ${PWD}" diff --git a/roles/netbox/defaults/main.yml b/roles/netbox/defaults/main.yml new file mode 100644 index 0000000..26caf18 --- /dev/null +++ b/roles/netbox/defaults/main.yml @@ -0,0 +1,13 @@ +netbox_version: "v3.7-2.8.0" +netbox_name: "netbox" +netbox_basepath: "" +netbox_auth: "default" +netbox_port: "127.0.0.1:8181" +netbox_s3_bucket_uri: "" +netbox_prefix: "/srv/{{ netbox_name }}" +netbox_network: "{{ netbox_name }}" +netbox_public_url: "{{ inventory_hostname }}" +netbox_postgres_prefix: "/srv/{{ netbox_name }}-postgres" +netbox_postgres_dbrestore: "" +netbox_redis_prefix: "/srv/{{ netbox_name }}-redis" +netbox_redis_cache_prefix: "/srv/{{ netbox_name }}-redis-cache" diff --git a/roles/netbox/handlers/main.yml b/roles/netbox/handlers/main.yml new file mode 100644 index 0000000..fe8f4ce --- /dev/null +++ b/roles/netbox/handlers/main.yml @@ -0,0 +1,8 @@ +- name: Restart Netbox + ansible.builtin.service: + name: "{{ item }}" + state: restarted + loop: + - "container-{{ netbox_name }}" + - "container-{{ netbox_name }}-rqworker" + - "container-{{ netbox_name }}-housekeeping" diff --git a/roles/netbox/tasks/main.yml b/roles/netbox/tasks/main.yml new file mode 100644 index 0000000..1fb4ade --- /dev/null +++ b/roles/netbox/tasks/main.yml @@ -0,0 +1,340 @@ +--- +- name: Create top level directories for Netbox related pods + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: root + group: root + mode: "0700" + loop: + - "{{ netbox_prefix }}" + - "{{ netbox_postgres_prefix }}" + - "{{ netbox_redis_prefix }}" + - "{{ netbox_redis_cache_prefix }}" + +- name: Create Postgresql data directory + ansible.builtin.file: + state: directory + owner: 70 + group: 70 + mode: "0755" + path: "{{ netbox_postgres_prefix }}/data" + +- name: Create Redis data directories + ansible.builtin.file: + state: directory + owner: 0 + group: 0 + mode: "0755" + path: "{{ item }}" + loop: + - "{{ netbox_redis_prefix }}/data" + - "{{ netbox_redis_cache_prefix }}/data" + +- name: Create Netbox config and util directores + ansible.builtin.file: + state: directory + owner: 999 + group: 0 + mode: "0755" + path: "{{ item }}" + loop: + - "{{ netbox_prefix }}/config" + - "{{ netbox_prefix }}/media" + - "{{ netbox_prefix }}/reports" + - "{{ netbox_prefix }}/scripts" + - "{{ netbox_prefix }}/backups" + +- name: Install Netbox config files + ansible.builtin.template: + src: "netbox-config/{{ item }}.j2" + dest: "{{ netbox_prefix }}/config/{{ item }}" + owner: 999 + group: 0 + mode: '0644' + loop: + - "extra.py" + +- name: Install NGINX unit conifg file + ansible.builtin.template: + src: "nginx-unit.json.j2" + dest: "{{ netbox_prefix }}/nginx-unit.json" + owner: 999 + group: 0 + mode: '0644' + +- name: Install Netbox requirements file + ansible.builtin.template: + src: "requirements-container.txt.j2" + dest: "{{ netbox_prefix }}/requirements-container.txt" + owner: 999 + group: 0 + mode: '0644' + +- name: Set netbox allowed host list + ansible.builtin.set_fact: + netbox_allowed_hosts: "{{ inventory_hostname }}" + +- name: Update netbox allowed host list if public url set + ansible.builtin.set_fact: + netbox_allowed_hosts: "{{ inventory_hostname }} {{ netbox_public_url }}" + when: netbox_public_url != "" + +- name: Install Netbox container runtime env file + ansible.builtin.template: + src: "netbox.env-{{ netbox_auth }}.j2" + dest: "{{ netbox_prefix }}/netbox.env" + owner: 0 + group: 0 + mode: '0600' + notify: + - Restart Netbox + +- name: Install Netbox Backup script + ansible.builtin.template: + src: "backup.sh.j2" + dest: "{{ netbox_prefix }}/backup.sh" + owner: 0 + group: 0 + mode: '0755' + +- name: Install s3 config and tools for netbox backups + ansible.builtin.include_tasks: + file: "s3.yml" + when: netbox_s3_bucket_uri != "" + +- name: Create Podman network for Netbox + containers.podman.podman_network: + name: "{{ netbox_network }}" + disable_dns: false + +- name: Create Podman secrets + containers.podman.podman_secret: + state: present + force: true + name: "{{ item.name }}" + data: "{{ item.data }}" + no_log: true + with_items: + - { name: "{{ netbox_name }}_postgres_password", + data: "{{ vault_netbox_postgres_password }}" } + - { name: "{{ netbox_name }}_redis_cache_password", + data: "{{ vault_netbox_redis_cache_password }}" } + - { name: "{{ netbox_name }}_redis_password", + data: "{{ vault_netbox_redis_password }}" } + - { name: "{{ netbox_name }}_secret_key", + data: "{{ vault_netbox_secret_key }}" } + - { name: "{{ netbox_name }}_superuser_password", + data: "{{ vault_obm_pw }}" } + - { name: "{{ netbox_name }}_api_token", + data: "{{ vault_netbox_api_token }}" } + +- name: Set up Postgresql server + containers.podman.podman_container: + name: "{{ netbox_name }}-postgres" + state: started + image: docker.io/postgres:16-alpine + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + path: /etc/systemd/system + secrets: + - "{{ netbox_name }}_postgres_password,target=db_password" + security_opt: + - 'label=disable' + env: + POSTGRES_DB: "netbox" + POSTGRES_USER: "{{ vault_netbox_postgres_username }}" + POSTGRES_PASSWORD_FILE: "/run/secrets/db_password" + volumes: + - "{{ netbox_postgres_prefix }}/data:/var/lib/postgresql/data:rw" + +- name: Restore existing Netbox Postgres DB + # disabled by default, use with lots of CAUTION + ansible.builtin.shell: | + echo "wait for container to start" + sleep 10 + echo "import DB from a file provided by admin" + podman exec -i "{{ netbox_name }}-postgres" psql \ + --user netbox < "{{ netbox_postgres_dbrestore }}" + args: + executable: bash + register: netbox_dbrestore_output + changed_when: netbox_dbrestore_output + when: netbox_postgres_dbrestore != "" + +- name: Set up Redis server + containers.podman.podman_container: + name: "{{ netbox_name }}-redis" + state: started + image: docker.io/redis:7-alpine + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + path: /etc/systemd/system + secrets: + - "{{ netbox_name }}_redis_password,target=redis_password" + env: + REDIS_PASS_FILE: /run/secrets/redis_password + security_opt: + - 'label=disable' + volumes: + - "{{ netbox_redis_prefix }}/data:/data:rw" + command: + - sh + - -c + - redis-server --requirepass "$(cat $REDIS_PASS_FILE)" + +- name: Set up Redis cache server + containers.podman.podman_container: + name: "{{ netbox_name }}-redis-cache" + state: started + image: docker.io/redis:7-alpine + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + path: /etc/systemd/system + secrets: + - "{{ netbox_name }}_redis_cache_password,target=redis_cache_password" + env: + REDIS_PASS_FILE: /run/secrets/redis_cache_password + security_opt: + - 'label=disable' + volumes: + - "{{ netbox_redis_cache_prefix }}/data:/data:rw" + command: + - sh + - -c + - redis-server --requirepass "$(cat $REDIS_PASS_FILE)" + +- name: Create a list of Netbox secrets + ansible.builtin.set_fact: + netbox_secrets: + - "{{ netbox_name }}_postgres_password,target=db_password" + - "{{ netbox_name }}_redis_password,target=redis_password" + - "{{ netbox_name }}_redis_cache_password,target=redis_cache_password" + - "{{ netbox_name }}_secret_key,target=secret_key" + - "{{ netbox_name }}_superuser_password,target=superuser_password" + - "{{ netbox_name }}_api_token,target=superuser_api_token" + +- name: Create a list of Netbox volume mounts + ansible.builtin.set_fact: + netbox_volumes: + - "{{ netbox_prefix }}/nginx-unit.json:/etc/unit/nginx-unit.json:ro" + - "{{ netbox_prefix }}/requirements-container.txt:/opt/netbox/requirements-container.txt:ro" + - "{{ netbox_prefix }}/config/extra.py:/etc/netbox/config/extra.py:ro" + - "{{ netbox_prefix }}/media:/opt/netbox/netbox/media:rw" + - "{{ netbox_prefix }}/reports:/opt/netbox/netbox/reports:rw" + - "{{ netbox_prefix }}/scripts:/opt/netbox/netbox/scripts:rw" + +- name: Handle alternate base URL redirects + when: netbox_basepath and netbox_basepath != "netbox" + block: + + - name: Create redir directory + ansible.builtin.file: + path: '{{ netbox_prefix }}/baseurl_redir' + owner: 999 + group: 0 + mode: '0755' + state: directory + + - name: Create static symlink + ansible.builtin.file: + src: "/opt/netbox/netbox/static" + dest: '{{ netbox_prefix }}/baseurl_redir/static' + owner: 999 + group: 0 + state: link + force: true + follow: false + + - name: Update Netbox container mounts + ansible.builtin.set_fact: + netbox_volumes: "{{ netbox_volumes + ['{{ netbox_prefix }}/baseurl_redir:/opt/netbox/netbox/{{ netbox_basepath }}:ro'] }}" + +- name: Set up Netbox server + containers.podman.podman_container: + name: "{{ netbox_name }}" + state: present + image: "docker.io/netboxcommunity/netbox:{{ netbox_version }}" + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + force: true + path: /etc/systemd/system + secrets: '{{ netbox_secrets }}' + security_opt: + - 'label=disable' + user: "unit:root" + publish: + - "{{ netbox_port }}:8080" + env_file: "{{ netbox_prefix }}/netbox.env" + volumes: '{{ netbox_volumes }}' + +- name: Set up Netbox rqworker + containers.podman.podman_container: + name: "{{ netbox_name }}-rqworker" + state: present + image: "docker.io/netboxcommunity/netbox:{{ netbox_version }}" + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + path: /etc/systemd/system + secrets: '{{ netbox_secrets }}' + security_opt: + - 'label=disable' + user: "unit:root" + env_file: "{{ netbox_prefix }}/netbox.env" + command: + - /opt/netbox/venv/bin/python + - /opt/netbox/netbox/manage.py + - rqworker + volumes: '{{ netbox_volumes }}' + +- name: Set up Netbox housekeeping scheduled tasks + containers.podman.podman_container: + name: "{{ netbox_name }}-housekeeping" + state: present + image: "docker.io/netboxcommunity/netbox:{{ netbox_version }}" + network: "{{ netbox_network }}" + generate_systemd: + names: true + new: true + path: /etc/systemd/system + secrets: '{{ netbox_secrets }}' + security_opt: + - 'label=disable' + user: "unit:root" + env_file: "{{ netbox_prefix }}/netbox.env" + command: + - /opt/netbox/housekeeping.sh + volumes: '{{ netbox_volumes }}' + +- name: Enable and start systemd containers + ansible.builtin.systemd: + name: "{{ item }}" + daemon_reload: true + force: true + state: started + enabled: true + loop: + - "container-{{ netbox_name }}-postgres" + - "container-{{ netbox_name }}-redis-cache" + - "container-{{ netbox_name }}-redis" + - "container-{{ netbox_name }}" + - "container-{{ netbox_name }}-rqworker" + - "container-{{ netbox_name }}-housekeeping" + +- name: Create backup cron + ansible.builtin.cron: + name: "netbox backup" + minute: "0" + hour: "18" + user: root + job: "{{ netbox_prefix }}/backup.sh >> {{ netbox_prefix }}/backups.log 2>&1" diff --git a/roles/netbox/tasks/s3.yml b/roles/netbox/tasks/s3.yml new file mode 100644 index 0000000..c1dbcff --- /dev/null +++ b/roles/netbox/tasks/s3.yml @@ -0,0 +1,19 @@ +--- +- name: Create directroy to hold s3 credentials + ansible.builtin.file: + path: "/root/.aws" + state: directory + owner: root + group: root + mode: "0700" + +- name: Install s3 config and credentials + ansible.builtin.template: + src: "s3/{{ item }}.j2" + dest: "/root/.aws/{{ item }}" + owner: root + group: root + mode: '0600' + loop: + - "config" + - "credentials" diff --git a/roles/netbox/templates/backup.sh.j2 b/roles/netbox/templates/backup.sh.j2 new file mode 100644 index 0000000..b209603 --- /dev/null +++ b/roles/netbox/templates/backup.sh.j2 @@ -0,0 +1,62 @@ +#!/bin/bash + +DEBUG=${DEBUG:-"false"} +BACKUP_DIR=${BACKUP_DIR:-{{ netbox_prefix }}/backups} +BACKUP_ROTATE=${BACKUP_ROTATE:-120} +AWSCLI_CREDS=${AWSCLI_CREDS:-"$HOME/.aws/credentials"} +S3_ENDPOINT=${S3_ENDPOINT:-"{{ vault_s3_endpoint_url }}"} +S3_BUCKET_URI=${S3_BUCKET_URI:-"{{ netbox_s3_bucket_uri }}"} + +[[ "${DEBUG}" =~ (1|true) ]] && set -x + +function retention() { + backups_to_delete=$(find "${BACKUP_DIR}" -type f | sort -rn | tail -n +$((${BACKUP_ROTATE} + 1))) + echo ">>> Running retention (rotate: ${BACKUP_ROTATE})" + for f in $backups_to_delete; do + echo "removing ${f}" + rm -f "${f}" + done +} + +function sync_s3_to_backups_dir() { + echo ">>> Syncing ${S3_BUCKET_URI} to ${BACKUP_DIR} (endpoint: ${S3_ENDPOINT})" + podman run --net host --rm -v $BACKUP_DIR:$BACKUP_DIR:rw,Z -v /root/.aws:/root/.aws:ro,Z docker://amazon/aws-cli s3 sync "${S3_BUCKET_URI}" "${BACKUP_DIR}" +} + +function sync_backups_to_s3() { + echo ">>> Syncing ${BACKUP_DIR} to ${S3_BUCKET_URI} (endpoint: ${S3_ENDPOINT})" + podman run --net host --rm -v $BACKUP_DIR:$BACKUP_DIR:ro,Z -v /root/.aws:/root/.aws:ro,Z docker://amazon/aws-cli s3 sync --delete "${BACKUP_DIR}" "${S3_BUCKET_URI}" +} + + +function exit_error() { + echo $1 1>&2 + exit 1 +} + +function validate_input() { + if [ ! -d "${BACKUP_DIR}" ]; then + exit_error "BACKUP_DIR does not exist: ${BACKUP_DIR}" + fi + if [ ! -f "${AWSCLI_CREDS}" ]; then + exit_error "AWSCLI_CREDS does not exist: ${AWSCLI_CREDS}" + fi +} + +function backup_netbox() { + timestamp=$(date +%Y%m%d%H%M%S) + echo ">>> Backing up Netbox Postgres DB" + podman exec {{ netbox_name }}-postgres sh -c 'PGPASSWORD=$(cat /run/secrets/db_password) pg_dump -h {{ netbox_name }}-postgres -U $POSTGRES_USER $POSTGRES_DB' > $BACKUP_DIR/$timestamp.netbox-postgres.sql + echo ">>> Backing up Netbox Media Files" + cd {{ netbox_prefix }}; tar cfz $BACKUP_DIR/$timestamp.netbox-media.tar.gz media +} + +function main() { + sync_s3_to_backups_dir + validate_input + backup_netbox + retention + sync_backups_to_s3 +} + +main diff --git a/roles/netbox/templates/netbox-config/extra.py.j2 b/roles/netbox/templates/netbox-config/extra.py.j2 new file mode 100644 index 0000000..b78f66c --- /dev/null +++ b/roles/netbox/templates/netbox-config/extra.py.j2 @@ -0,0 +1,78 @@ +from os import environ + +#### +## This file contains extra configuration options that can't be configured +## directly through environment variables. +#### + +## 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'], +# ] + + +## URL schemes that are allowed within links in NetBox +# ALLOWED_URL_SCHEMES = ( +# 'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp', +# ) + +## Enable installed plugins. Add the name of each plugin to the list. +# from netbox.configuration.configuration import PLUGINS +# PLUGINS.append('my_plugin') + +## Plugins configuration settings. These settings are used by various plugins that the user may have installed. +## Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings. +# from netbox.configuration.configuration import PLUGINS_CONFIG +# PLUGINS_CONFIG['my_plugin'] = { +# 'foo': 'bar', +# 'buzz': 'bazz' +# } + + +## Remote authentication support +# REMOTE_AUTH_DEFAULT_PERMISSIONS = {} + + +## By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the +## class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example: +# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage' +# STORAGE_CONFIG = { +# 'AWS_ACCESS_KEY_ID': 'Key ID', +# 'AWS_SECRET_ACCESS_KEY': 'Secret', +# 'AWS_STORAGE_BUCKET_NAME': 'netbox', +# 'AWS_S3_REGION_NAME': 'eu-west-1', +# } + + +## This file can contain arbitrary Python code, e.g.: +# from datetime import datetime +# now = datetime.now().strftime("%d/%m/%Y %H:%M:%S") +# BANNER_TOP = f'This instance started on {now}.' +# +BASE_DIR = environ.get('BASE_DIR','') +BASE_PATH = environ.get('BASE_PATH','') + +## Variables to configure authentication +# +# SOCIAL_AUTH_GITHUB_KEY = environ.get('SOCIAL_AUTH_GITHUB_KEY','') +# SOCIAL_AUTH_GITHUB_SECRET = environ.get('SOCIAL_AUTH_GITHUB_SECRET','') +# SOCIAL_AUTH_KEYCLOAK_KEY = environ.get('SOCIAL_AUTH_KEYCLOAK_KEY','') +# SOCIAL_AUTH_KEYCLOAK_SECRET = environ.get('SOCIAL_AUTH_KEYCLOAK_SECRET','') +# SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY = environ.get('SOCIAL_AUTH_KEYCLOAK_PUBLIC_KEY','') +# SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL = environ.get('SOCIAL_AUTH_KEYCLOAK_AUTHORIZATION_URL','') +# SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL = environ.get('SOCIAL_AUTH_KEYCLOAK_ACCESS_TOKEN_URL','') +# SOCIAL_AUTH_VERIFY_SSL = environ.get('SOCIAL_AUTH_VERIFY_SSL','') + +# SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = environ.get('SOCIAL_AUTH_OIDC_OIDC_ENDPOINT','') +# SOCIAL_AUTH_OIDC_KEY = environ.get('SOCIAL_AUTH_OIDC_KEY','') +# SOCIAL_AUTH_OIDC_SECRET = environ.get('SOCIAL_AUTH_OIDC_SECRET','') +# SOCIAL_AUTH_JSONFIELD_ENABLED = environ.get('SOCIAL_AUTH_JSONFIELD_ENABLED','') + +LOGOUT_REDIRECT_URL = environ.get('LOGOUT_REDIRECT_URL','') +REMOTE_AUTH_USER_FIRST_NAME = environ.get('REMOTE_AUTH_USER_FIRST_NAME','') +REMOTE_AUTH_USER_LAST_NAME = environ.get('REMOTE_AUTH_USER_LAST_NAME','') +REMOTE_AUTH_USER_EMAIL = environ.get('REMOTE_AUTH_USER_EMAIL','') +REMOTE_AUTH_GROUP_HEADER = environ.get('REMOTE_AUTH_GROUP_HEADER','') +REMOTE_AUTH_GROUP_SYNC_ENABLED = environ.get('REMOTE_AUTH_GROUP_SYNC_ENABLED','') +REMOTE_AUTH_GROUP_SEPARATOR = environ.get('REMOTE_AUTH_GROUP_SEPARATOR','') diff --git a/roles/netbox/templates/netbox.env-default.j2 b/roles/netbox/templates/netbox.env-default.j2 new file mode 100644 index 0000000..f825819 --- /dev/null +++ b/roles/netbox/templates/netbox.env-default.j2 @@ -0,0 +1,24 @@ +ALLOWED_HOSTS={{ netbox_allowed_hosts }} host.containers.internal localhost +BASE_DIR=/opt/netbox/netbox +BASE_PATH={{ netbox_basepath }} +CORS_ORIGIN_ALLOW_ALL=true +DB_HOST={{ netbox_name }}-postgres +DB_NAME=netbox +DB_USER={{ vault_netbox_postgres_username }} +GRAPHQL_ENABLED=true +HOUSEKEEPING_INTERVAL=86400 +MEDIA_ROOT=/opt/netbox/netbox/media +METRICS_ENABLED=false +REDIS_CACHE_DATABASE=1 +REDIS_CACHE_HOST={{ netbox_name }}-redis-cache +REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY=false +REDIS_CACHE_SSL=false +REDIS_DATABASE=1 +REDIS_HOST={{ netbox_name }}-redis +REDIS_INSECURE_SKIP_TLS_VERIFY=false +REDIS_SSL=false +RELEASE_CHECK_URL=https://api.github.com/repos/netbox-community/netbox/releases +SKIP_SUPERUSER=false +SUPERUSER_EMAIL= +SUPERUSER_NAME={{ vault_obm_user }} +WEBHOOKS_ENABLED=true diff --git a/roles/netbox/templates/netbox.env-remote-user.j2 b/roles/netbox/templates/netbox.env-remote-user.j2 new file mode 100644 index 0000000..a8dcfbd --- /dev/null +++ b/roles/netbox/templates/netbox.env-remote-user.j2 @@ -0,0 +1,35 @@ +ALLOWED_HOSTS={{ netbox_allowed_hosts }} host.containers.internal localhost +BASE_DIR=/opt/netbox/netbox +BASE_PATH={{ netbox_basepath }} +CORS_ORIGIN_ALLOW_ALL=true +DB_HOST={{ netbox_name }}-postgres +DB_NAME=netbox +DB_USER={{ vault_netbox_postgres_username }} +GRAPHQL_ENABLED=true +HOUSEKEEPING_INTERVAL=86400 +MEDIA_ROOT=/opt/netbox/netbox/media +METRICS_ENABLED=false +REDIS_CACHE_DATABASE=1 +REDIS_CACHE_HOST={{ netbox_name }}-redis-cache +REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY=false +REDIS_CACHE_SSL=false +REDIS_DATABASE=1 +REDIS_HOST={{ netbox_name }}-redis +REDIS_INSECURE_SKIP_TLS_VERIFY=false +REDIS_SSL=false +RELEASE_CHECK_URL=https://api.github.com/repos/netbox-community/netbox/releases +REMOTE_AUTH_ENABLED=True +REMOTE_AUTH_BACKEND=netbox.authentication.RemoteUserBackend +REMOTE_AUTH_AUTO_CREATE_USER=True +REMOTE_AUTH_HEADER=HTTP_REMOTE_USER +SKIP_SUPERUSER=false +REMOTE_AUTH_USER_FIRST_NAME=HTTP_OIDC_CLAIM_GIVEN_NAME +REMOTE_AUTH_USER_LAST_NAME=HTTP_OIDC_CLAIM_FAMILY_NAME +REMOTE_AUTH_USER_EMAIL=HTTP_OIDC_CLAIM_EMAIL +REMOTE_AUTH_GROUP_HEADER=HTTP_OIDC_CLAIM_NERC_ROLES +REMOTE_AUTH_GROUP_SEPARATOR=, +REMOTE_AUTH_GROUP_SYNC_ENABLED=true +LOGOUT_REDIRECT_URL=https://{{ netbox_public_url }}/auth/re?logout=https%3A%2F%2F{{ netbox_public_url }} +SUPERUSER_EMAIL= +SUPERUSER_NAME={{ vault_obm_user }} +WEBHOOKS_ENABLED=true diff --git a/roles/netbox/templates/nginx-unit.json.j2 b/roles/netbox/templates/nginx-unit.json.j2 new file mode 100644 index 0000000..b209e68 --- /dev/null +++ b/roles/netbox/templates/nginx-unit.json.j2 @@ -0,0 +1,68 @@ +{ + "listeners": { + "0.0.0.0:8080": { + "pass": "routes/main" + }, + "[::]:8080": { + "pass": "routes/main" + }, + "0.0.0.0:8081": { + "pass": "routes/status" + }, + "[::]:8081": { + "pass": "routes/status" + } + }, + "routes": { + "main": [ + { + "match": { + {% if netbox_basepath != "" %} + "uri": "/{{ netbox_basepath }}/static/*" + {% else %} + "uri": "/static/*" + {% endif %} + }, + "action": { + {% if netbox_basepath == "netbox" %} + "share": "/opt/netbox${uri}" + {% else %} + "share": "/opt/netbox/netbox${uri}" + {% endif %} + } + }, + { + "action": { + "pass": "applications/netbox" + } + } + ], + "status": [ + { + "match": { + "uri": "/status/*" + }, + "action": { + "proxy": "http://unix:/opt/unit/unit.sock" + } + } + ] + }, + "applications": { + "netbox": { + "type": "python 3", + "path": "/opt/netbox/netbox/", + "module": "netbox.wsgi", + "home": "/opt/netbox/venv", + "processes": { + "max": 4, + "spare": 1, + "idle_timeout": 120 + } + } + }, + "access_log": "/dev/stdout", + "settings": { + "http": { "discard_unsafe_fields": false } + } +} diff --git a/roles/netbox/templates/requirements-container.txt.j2 b/roles/netbox/templates/requirements-container.txt.j2 new file mode 100644 index 0000000..dcff130 --- /dev/null +++ b/roles/netbox/templates/requirements-container.txt.j2 @@ -0,0 +1,6 @@ +django-auth-ldap==4.6.0 +django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.14.2 +dulwich==0.21.7 +psycopg[c,pool]==3.1.16 +python3-saml==1.16.0 +social-auth-core[github] diff --git a/roles/netbox/templates/s3/config.j2 b/roles/netbox/templates/s3/config.j2 new file mode 100644 index 0000000..ecddea4 --- /dev/null +++ b/roles/netbox/templates/s3/config.j2 @@ -0,0 +1,3 @@ +[default] +region = us-east-1 +endpoint_url = {{ vault_s3_endpoint_url }} diff --git a/roles/netbox/templates/s3/credentials.j2 b/roles/netbox/templates/s3/credentials.j2 new file mode 100644 index 0000000..9948f28 --- /dev/null +++ b/roles/netbox/templates/s3/credentials.j2 @@ -0,0 +1,3 @@ +[default] +aws_access_key_id = {{ vault_s3_access_key_id }} +aws_secret_access_key = {{ vault_s3_secret_access_key }}