From 15e16c0521ff43e9c8096f6ba4f38b291ff1411f Mon Sep 17 00:00:00 2001 From: Andrew Ying Date: Sun, 19 Nov 2023 12:16:22 +0000 Subject: [PATCH] Initial commit --- LICENSE.md | 24 ++ README.md | 17 ++ galaxy.yml | 61 +++++ meta/runtime.yml | 52 ++++ plugins/README.md | 31 +++ roles/netbox_installation/defaults/main.yml | 6 + roles/netbox_installation/tasks/main.yml | 46 ++++ .../templates/configuration.py.j2 | 244 ++++++++++++++++++ roles/netbox_installation/vars/main.yml | 5 + 9 files changed, 486 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 galaxy.yml create mode 100644 meta/runtime.yml create mode 100644 plugins/README.md create mode 100644 roles/netbox_installation/defaults/main.yml create mode 100644 roles/netbox_installation/tasks/main.yml create mode 100644 roles/netbox_installation/templates/configuration.py.j2 create mode 100644 roles/netbox_installation/vars/main.yml diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..83b459c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +Copyright © 2023 Witine Limited and subsidiaries. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d688143 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Netbox Ansible Collection + +This is a work in progress. This package is unstable and may not work as +expected, or may not work at all. Use this package at your own risk. + +## Postcardware + +You're free to use this package, but if it makes it to your production +environment, we'd really appreciate you sending us a postcard, mentioning which +of our package(s) you are using. + +Our address is: Witine Limited, St John's Innovation Centre, Cowley Road, +Cambridge CB4 0WS, United Kingdom + +## License + +This package is licensed under the [3-clause BSD License](LICENSE.md). diff --git a/galaxy.yml b/galaxy.yml new file mode 100644 index 0000000..b8cfb26 --- /dev/null +++ b/galaxy.yml @@ -0,0 +1,61 @@ +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: witine + +# The name of the collection. Has the same character restrictions as 'namespace' +name: netbox + +# The version of the collection. Must be compatible with semantic versioning +version: 1.0.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- Andrew Ying + +# A short summary description of the collection +description: Netbox Ansible collection + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- BSD-3-Clause + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: ['netbox'] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: https://github.com/witine/ansible-collection-netbox + +# The URL to any online docs +documentation: https://github.com/witine/ansible-collection-netbox + +# The URL to the homepage of the collection/project +homepage: https://github.com/witine/ansible-collection-netbox + +# The URL to the collection issue tracker +issues: https://github.com/witine/ansible-collection-netbox/issues + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered. Mutually exclusive with 'manifest' +build_ignore: [] + +# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a +# list of MANIFEST.in style +# L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key +# 'omit_default_directives' is a boolean that controls whether the default directives are used. Mutually exclusive +# with 'build_ignore' +# manifest: null diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..20f709e --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,52 @@ +--- +# Collections must specify a minimum required ansible version to upload +# to galaxy +# requires_ansible: '>=2.9.10' + +# Content that Ansible needs to load from another location or that has +# been deprecated/removed +# plugin_routing: +# action: +# redirected_plugin_name: +# redirect: ns.col.new_location +# deprecated_plugin_name: +# deprecation: +# removal_version: "4.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# removed_plugin_name: +# tombstone: +# removal_version: "2.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# become: +# cache: +# callback: +# cliconf: +# connection: +# doc_fragments: +# filter: +# httpapi: +# inventory: +# lookup: +# module_utils: +# modules: +# netconf: +# shell: +# strategy: +# terminal: +# test: +# vars: + +# Python import statements that Ansible needs to load from another location +# import_redirection: +# ansible_collections.ns.col.plugins.module_utils.old_location: +# redirect: ansible_collections.ns.col.plugins.module_utils.new_location + +# Groups of actions/modules that take a common set of options +# action_groups: +# group_name: +# - module1 +# - module2 diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 0000000..6260634 --- /dev/null +++ b/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.15/plugins/plugins.html). diff --git a/roles/netbox_installation/defaults/main.yml b/roles/netbox_installation/defaults/main.yml new file mode 100644 index 0000000..ae7bf3c --- /dev/null +++ b/roles/netbox_installation/defaults/main.yml @@ -0,0 +1,6 @@ +--- +netbox_user: netbox +netbox_group: netbox +netbox_install_target: "{{ netbox_latest_release }}" + +netbox_allowed_hosts: [] diff --git a/roles/netbox_installation/tasks/main.yml b/roles/netbox_installation/tasks/main.yml new file mode 100644 index 0000000..a6c29df --- /dev/null +++ b/roles/netbox_installation/tasks/main.yml @@ -0,0 +1,46 @@ +--- +- name: "Gather facts from remote host" + ansible.builtin.setup: + filter: ansible_local + +- name: "Set netbox_install to True if no remote installation was detected" + ansible.builtin.set_fact: + netbox_install: True + when: "ansible_local is not defined or 'witine' is not in ansible_local or 'netbox' is not in ansible_local['witine'] or 'installed_version' is not in ansible_local['witine']['netbox']" + +- name: "Set netbox_install to True if a newer version is available" + ansible.builtin.set_fact: + netbox_install: True + when: + - not netbox_install + - "netbox_install_target['version'] is version(ansible_local['witine']['netbox']['installed_version'], '>')" + +- name: "Ensure that Netbox install target has URL and version information" + ansible.builtin.assert: + that: + - "'url' in netbox_install_target" + - "'version' in netbox_install_target" + when: netbox_install + +- name: "Download and extract Netbox release" + ansible.builtin.unarchive: + src: "{{ netbox_install_target['url'] }}" + dest: "/opt" + remote_src: yes + when: netbox_install + +- name: "Create symbolic link" + ansible.builtin.file: + src: "/opt/netbox-{{ netbox_install_target['version'] }}" + dest: /opt/netbox + state: link + when: netbox_install + +- name: "Delete old Netbox installation" + ansible.builtin.file: + path: "/opt/netbox-{{ ansible_local['witine']['netbox']['installed_version'] }}" + state: absent + when: + - netbox_install + - ansible_local['witine']['netbox']['installed_version'] is defined + diff --git a/roles/netbox_installation/templates/configuration.py.j2 b/roles/netbox_installation/templates/configuration.py.j2 new file mode 100644 index 0000000..6488cef --- /dev/null +++ b/roles/netbox_installation/templates/configuration.py.j2 @@ -0,0 +1,244 @@ +# {{ ansible_managed }} + +# 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 = {{ netbox_allowed_hosts }} + +# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters: +# https://docs.djangoproject.com/en/stable/ref/settings/#databases +DATABASE = { + 'ENGINE': 'django.db.backends.postgresql', # Database engine + 'NAME': 'netbox', # Database name + 'USER': '', # PostgreSQL username + 'PASSWORD': '', # PostgreSQL password + 'HOST': 'localhost', # Database server + 'PORT': '', # Database port (leave blank for default) + 'CONN_MAX_AGE': 300, # Max database connection age +} + +# Redis database settings. Redis is used for caching and for queuing background tasks such as webhook events. A separate +# configuration exists for each. Full connection details are required in both sections, and it is strongly recommended +# to use two separate database IDs. +REDIS = { + 'tasks': { + 'HOST': 'localhost', + 'PORT': 6379, + # Comment out `HOST` and `PORT` lines and uncomment the following if using Redis Sentinel + # 'SENTINELS': [('mysentinel.redis.example.com', 6379)], + # 'SENTINEL_SERVICE': 'netbox', + 'USERNAME': '', + 'PASSWORD': '', + 'DATABASE': 0, + 'SSL': False, + # Set this to True to skip TLS certificate verification + # This can expose the connection to attacks, be careful + # 'INSECURE_SKIP_TLS_VERIFY': False, + # Set a path to a certificate authority, typically used with a self signed certificate. + # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt', + }, + 'caching': { + 'HOST': 'localhost', + 'PORT': 6379, + # Comment out `HOST` and `PORT` lines and uncomment the following if using Redis Sentinel + # 'SENTINELS': [('mysentinel.redis.example.com', 6379)], + # 'SENTINEL_SERVICE': 'netbox', + 'USERNAME': '', + 'PASSWORD': '', + 'DATABASE': 1, + 'SSL': False, + # Set this to True to skip TLS certificate verification + # This can expose the connection to attacks, be careful + # 'INSECURE_SKIP_TLS_VERIFY': False, + # Set a path to a certificate authority, typically used with a self signed certificate. + # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt', + } +} + +# 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/stable/ref/settings/#std:setting-SECRET_KEY +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'), +] + +# Permit the retrieval of API tokens after their creation. +ALLOW_TOKEN_RETRIEVAL = False + +# Enable any desired validators for local account passwords below. For a list of included validators, please see the +# Django documentation at https://docs.djangoproject.com/en/stable/topics/auth/passwords/#password-validation. +AUTH_PASSWORD_VALIDATORS = [ + # { + # 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + # 'OPTIONS': { + # 'min_length': 10, + # } + # }, +] + +# Base URL path if accessing NetBox within a directory. For example, if installed at https://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 = [ + # 'https://hostname.example.com', +] +CORS_ORIGIN_REGEX_WHITELIST = [ + # r'^(https?://)?(\w+\.)?example\.com$', +] + +# The name to use for the CSRF token cookie. +CSRF_COOKIE_NAME = 'csrftoken' + +# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal +# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging +# on a production system. +DEBUG = False + +# Set the default preferred language/locale +DEFAULT_LANGUAGE = 'en-us' + +# Email settings +EMAIL = { + 'SERVER': 'localhost', + 'PORT': 25, + 'USERNAME': '', + 'PASSWORD': '', + 'USE_SSL': False, + 'USE_TLS': False, + 'TIMEOUT': 10, # seconds + 'FROM_EMAIL': '', +} + +# Localization +ENABLE_LOCALIZATION = False + +# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and +# by anonymous users. List models in the form `.`. Add '*' to this list to exempt all models. +EXEMPT_VIEW_PERMISSIONS = [ + # 'dcim.site', + # 'dcim.region', + # 'ipam.prefix', +] + +# HTTP proxies NetBox should use when sending outbound HTTP requests (e.g. for webhooks). +# HTTP_PROXIES = { +# 'http': 'http://10.10.1.10:3128', +# 'https': 'http://10.10.1.10:1080', +# } + +# IP addresses recognized as internal to the system. The debugging toolbar will be available only to clients accessing +# NetBox from an internal IP. +INTERNAL_IPS = ('127.0.0.1', '::1') + +# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: +# https://docs.djangoproject.com/en/stable/topics/logging/ +LOGGING = {} + +# Automatically reset the lifetime of a valid session upon each authenticated request. Enables users to remain +# authenticated to NetBox indefinitely. +LOGIN_PERSISTENCE = 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 but not make any changes. +LOGIN_REQUIRED = False + +# The length of time (in seconds) for which a user will remain logged into the web UI before being prompted to +# re-authenticate. (Default: 1209600 [14 days]) +LOGIN_TIMEOUT = None + +# The view name or URL to which users are redirected after logging out. +LOGOUT_REDIRECT_URL = 'home' + +# 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' + +# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics' +METRICS_ENABLED = False + +# Enable installed plugins. Add the name of each plugin to the list. +PLUGINS = [] + +# 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. +# PLUGINS_CONFIG = { +# 'my_plugin': { +# 'foo': 'bar', +# 'buzz': 'bazz' +# } +# } + +# Remote authentication support +REMOTE_AUTH_ENABLED = False +REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend' +REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER' +REMOTE_AUTH_USER_FIRST_NAME = 'HTTP_REMOTE_USER_FIRST_NAME' +REMOTE_AUTH_USER_LAST_NAME = 'HTTP_REMOTE_USER_LAST_NAME' +REMOTE_AUTH_USER_EMAIL = 'HTTP_REMOTE_USER_EMAIL' +REMOTE_AUTH_AUTO_CREATE_USER = True +REMOTE_AUTH_DEFAULT_GROUPS = [] +REMOTE_AUTH_DEFAULT_PERMISSIONS = {} + +# This repository is used to check whether there is a new release of NetBox available. Set to None to disable the +# version check or use the URL below to check for release in the official NetBox repository. +RELEASE_CHECK_URL = None +# RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases' + +# 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' + +# Maximum execution time for background tasks, in seconds. +RQ_DEFAULT_TIMEOUT = 300 + +# The file path where custom scripts will be stored. A trailing slash is not needed. Note that the default value of +# this setting is derived from the installed location. +# SCRIPTS_ROOT = '/opt/netbox/netbox/scripts' + +# The name to use for the session cookie. +SESSION_COOKIE_NAME = 'sessionid' + +# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use +# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only +# database access.) Note that the user as which NetBox runs must have read and write permissions to this path. +SESSION_FILE_PATH = None + +# 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', +# } + +# Time zone (default: UTC) +TIME_ZONE = 'UTC' + +# Date/time formatting. See the following link for supported formats: +# https://docs.djangoproject.com/en/stable/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' diff --git a/roles/netbox_installation/vars/main.yml b/roles/netbox_installation/vars/main.yml new file mode 100644 index 0000000..57f6b3b --- /dev/null +++ b/roles/netbox_installation/vars/main.yml @@ -0,0 +1,5 @@ +--- +netbox_latest_release: + url: https://github.com/netbox-community/netbox/archive/refs/tags/v3.6.5.tar.gz + version: 3.6.5 +netbox_install: False