Ayounsi has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/387880 )

Change subject: Netbox: initial puppet commit
......................................................................

Netbox: initial puppet commit

Change-Id: Ia3354fcf251952a27d58eba3487043d8d4bd26fe
---
M hieradata/role/common/deployment_server.yaml
M manifests/site.pp
A modules/netbox/manifests/init.pp
A modules/netbox/templates/configuration.py.erb
A modules/netbox/templates/gunicorn.erb
A modules/netbox/templates/ldap_config.py.erb
A modules/profile/manifests/netbox.pp
A modules/role/manifests/netbox.pp
A modules/role/templates/netbox/netbox.wikimedia.org.erb
9 files changed, 366 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/80/387880/1

diff --git a/hieradata/role/common/deployment_server.yaml 
b/hieradata/role/common/deployment_server.yaml
index 8eac2e3..865799c 100644
--- a/hieradata/role/common/deployment_server.yaml
+++ b/hieradata/role/common/deployment_server.yaml
@@ -173,6 +173,9 @@
   # Librenms software
   librenms/librenms:
     repository: operations/software/librenms
+  # Netbox software
+  netbox/deploy:
+    repository: operations/software/netbox-deploy
   relforge/mjolnir:
     repository: search/MjoLniR
   statsv/statsv:
diff --git a/manifests/site.pp b/manifests/site.pp
index 0861aed..091fab0 100644
--- a/manifests/site.pp
+++ b/manifests/site.pp
@@ -1954,7 +1954,7 @@
 
 # network monitoring tools, stretch (T125020, T166180)
 node /^netmon(1002|2001)\.wikimedia\.org$/ {
-    role(network::monitor, librenms, rancid, smokeping)
+    role(network::monitor, librenms, rancid, smokeping, netbox)
     interface::add_ip6_mapped { 'main': }
 }
 
diff --git a/modules/netbox/manifests/init.pp b/modules/netbox/manifests/init.pp
new file mode 100644
index 0000000..d2b073f
--- /dev/null
+++ b/modules/netbox/manifests/init.pp
@@ -0,0 +1,58 @@
+# == Class: netbox::base
+#
+# Installs Netbox
+#
+class netbox(
+    $secret_key,
+    $ldap_password,
+    $db_password,
+    $debug=false,
+    $port=8001,
+    $config_path = '/srv/deployment/netbox/deploy',
+    $venv_path = '/srv/deployment/netbox/venv',
+    $directory = '/srv/deployment/netbox/netbox'
+    $ensure='present',
+
+) {
+
+require_package('virtualenv', 'python3-dev',
+                'gunicorn', 'libldap2-dev',
+                'build-essential', 'python3-pip',
+                'libsasl2-dev', 'libssl-dev')
+
+# If new install, postgres user needs to be manually added, see:
+# 
http://netbox.readthedocs.io/en/stable/installation/postgresql/#database-creation
+require_package('postgresql', 'libpq-dev')
+
+}
+
+file { "${directory}/netbox/netbox/configuration.py":
+    ensure  => $ensure,
+    owner   => 'root',
+    group   => 'root',
+    mode    => '0555',
+    content => template('netbox/configuration.py.erb'),
+}
+
+file { "${directory}/netbox/netbox/ldap_config.py":
+    ensure  => $ensure,
+    owner   => 'root',
+    group   => 'root',
+    mode    => '0555',
+    content => template('netbox/ldap_config.py.erb'),
+}
+
+service { 'gunicorn':
+    ensure    => ensure_service($ensure),
+    enable    => true,
+    hasstatus => false,
+}
+
+file { '/etc/gunicorn.d/netbox':
+    ensure  => $ensure,
+    owner   => 'root',
+    group   => 'root',
+    mode    => '0555',
+    content => template('netbox/gunicorn.erb'),
+    require => Package['gunicorn'],
+}
diff --git a/modules/netbox/templates/configuration.py.erb 
b/modules/netbox/templates/configuration.py.erb
new file mode 100644
index 0000000..402e4c9
--- /dev/null
+++ b/modules/netbox/templates/configuration.py.erb
@@ -0,0 +1,145 @@
+#########################
+#                       #
+#   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']
+# We are behind an apache httpd server, so use X-Forwarded_Host header
+USE_X_FORWARDED_HOST = True
+ALLOWED_HOSTS = ['netbox.wikimedia.org']
+
+# PostgreSQL database configuration.
+DATABASE = {
+    'NAME': 'netbox',         # Database name
+    'USER': 'netbox',               # PostgreSQL username
+    'PASSWORD': '<%= @db_password %>',           # PostgreSQL password
+    'HOST': 'localhost',      # Database server
+    'PORT': '',               # Database port (leave blank for 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 = '<%= @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 = (
+<%- if @admins -%>
+       <%= @admins%>
+<%- else -%>
+    # ('Your Name', 'your_em...@example.com'),
+<%- end -%>
+)
+
+# Optionally display a persistent banner at the top and/or bottom of every 
page. HTML is allowed. To display the same
+# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = 
BANNER_TOP.
+BANNER_TOP = ''
+BANNER_BOTTOM = ''
+
+# Text to include on the login page above the login form. HTML is allowed.
+BANNER_LOGIN = ''
+
+# 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$',
+]
+
+# 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.
+<%- if @debug -%>
+DEBUG = True
+<%- else -%>
+DEBUG = False
+<%- end -%>
+
+# 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 = True
+
+# Enable custom logging. Please see the Django documentation for detailed 
guidance on configuring custom logs:
+#   https://docs.djangoproject.com/en/1.11/topics/logging/
+LOGGING = {}
+
+# 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 = True
+
+# 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 = ''
+NAPALM_PASSWORD = ''
+
+# 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 = 'UTC'
+
+# 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'
diff --git a/modules/netbox/templates/gunicorn.erb 
b/modules/netbox/templates/gunicorn.erb
new file mode 100644
index 0000000..87883ff
--- /dev/null
+++ b/modules/netbox/templates/gunicorn.erb
@@ -0,0 +1,11 @@
+CONFIG = {
+    'mode': 'wsgi',
+    'working_dir': '<%= @directory %>/netbox',
+    'python': '<%= @venv %>/bin/python',
+    'args': (
+        '--bind=127.0.0.1:<%= @port %>',
+        '--workers=4',
+        '--timeout=10',
+       'wsgi',
+    ),
+}
diff --git a/modules/netbox/templates/ldap_config.py.erb 
b/modules/netbox/templates/ldap_config.py.erb
new file mode 100644
index 0000000..1761905
--- /dev/null
+++ b/modules/netbox/templates/ldap_config.py.erb
@@ -0,0 +1,42 @@
+import ldap
+from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
+
+# Server URI
+AUTH_LDAP_SERVER_URI = "ldap-labs.eqiad.wikimedia.org"
+
+# The following may be needed if you are binding to Active Directory.
+AUTH_LDAP_CONNECTION_OPTIONS = {
+    ldap.OPT_REFERRALS: 0
+}
+
+# Set the DN and password for the NetBox service account.
+AUTH_LDAP_BIND_DN = "cn=proxyagent,ou=profile,dc=wikimedia,dc=org"
+AUTH_LDAP_BIND_PASSWORD = "<%= @ldap_password %>"
+
+# Include this setting if you want to ignore certificate errors. This might be 
needed to accept a self-signed cert.
+# Note that this is a NetBox-specific setting which sets:
+#     ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
+LDAP_IGNORE_CERT_ERRORS = False
+
+
+# This search ought to return all groups to which the user belongs. 
django_auth_ldap uses this to determine group
+# heirarchy.
+AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=people,dc=wikimedia,dc=org", 
ldap.SCOPE_SUBTREE,
+                                    "(objectClass=group)")
+AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
+
+# Define a group required to login.
+AUTH_LDAP_REQUIRE_GROUP = "cn=ops,ou=groups,dc=wikimedia,dc=org"
+
+# Define special user types using groups. Exercise great caution when 
assigning superuser status.
+AUTH_LDAP_USER_FLAGS_BY_GROUP = {
+    "is_active": "cn=librenms-reader,ou=groups,dc=wikimedia,dc=org"
+    "is_superuser": "cn=ops,ou=groups,dc=wikimedia,dc=org"
+}
+
+# For more granular permissions, we can map LDAP groups to Django groups.
+AUTH_LDAP_FIND_GROUP_PERMS = True
+
+# Cache groups for one hour to reduce LDAP traffic
+AUTH_LDAP_CACHE_GROUPS = True
+AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
diff --git a/modules/profile/manifests/netbox.pp 
b/modules/profile/manifests/netbox.pp
new file mode 100644
index 0000000..305584e
--- /dev/null
+++ b/modules/profile/manifests/netbox.pp
@@ -0,0 +1,46 @@
+# Class: profile::netbox
+#
+# This profile installs all the Netbox related parts as WMF requires it
+#
+# Actions:
+#       Deploy Netbox
+#       Install apache, gunicorn, configure reverse proxy to gunicorn, LDAP
+#       authentication
+#
+# Requires:
+#
+# Sample Usage:
+#       include profile::netbox
+#
+
+class profile::netbox {
+  include ::apache
+  include ::apache::mod::proxy_http
+  include ::apache::mod::proxy
+
+
+  include passwords::netbox
+  $db_password = $passwords::netbox::db_password   #### NOT DEFINED YET
+  $secret_key = $passwords::netbox::secret_key     #### NOT DEFINED YET
+
+  # Used for LDAP auth
+  include passwords::ldap::wmf_cluster
+  $proxypass = $passwords::ldap::wmf_cluster::proxypass
+
+  scap::target { 'netbox/deploy':
+      deploy_user => 'deploy-librenms',
+  }
+
+  class { '::netbox':
+      directory     => '/srv/deployment/netbox/netbox',
+      db_password   => $db_password,
+      secret_key    => $secret_key,
+      ldap_password => $proxypass,
+      admins        => '("Ops Team", "o...@lists.wikimedia.org")',
+  }
+
+  apache::site { 'netbox.wikimedia.org':
+      content => template('role/netbox/netbox.wikimedia.org.erb'),
+  }
+
+}
diff --git a/modules/role/manifests/netbox.pp b/modules/role/manifests/netbox.pp
new file mode 100644
index 0000000..c3b0f14
--- /dev/null
+++ b/modules/role/manifests/netbox.pp
@@ -0,0 +1,20 @@
+# Class: profile::netbox
+#
+# This profile installs all the Netbox related parts as WMF requires it
+#
+# Actions:
+#       Deploy Netbox
+#
+# Requires:
+#
+# Sample Usage:
+#       include role::netbox
+#
+
+class role::netbox {
+
+  system::role { 'netbox': description => 'Netbox server' }
+
+  include ::profile::netbox
+
+}
diff --git a/modules/role/templates/netbox/netbox.wikimedia.org.erb 
b/modules/role/templates/netbox/netbox.wikimedia.org.erb
new file mode 100644
index 0000000..6360c32
--- /dev/null
+++ b/modules/role/templates/netbox/netbox.wikimedia.org.erb
@@ -0,0 +1,40 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+#####################################################################
+# vim: filetype=apache
+
+<VirtualHost *:80>
+    ProxyPreserveHost On
+
+    ServerName netbox.wikimedia.org
+
+    Alias /static <%= @directory%>/static
+
+    # Needed to allow token-based API authentication
+    WSGIPassAuthorization on
+
+    <Directory <%= @directory%>/static>
+        Options Indexes FollowSymLinks MultiViews
+        AllowOverride None
+        Require all granted
+    </Directory>
+
+    <Location /static>
+        ProxyPass !
+    </Location>
+
+    <%- if @port -%>
+    ProxyPass / http://127.0.0.1:<%= @port%>/
+    ProxyPassReverse / http://127.0.0.1:<%= @port%>/
+    <%- else -%>
+    ProxyPass / http://127.0.0.1:8001/
+    ProxyPassReverse / http://127.0.0.1:8001/
+    <%- end -%>
+
+    # Possible values include: debug, info, notice, warn, error, crit,
+    # alert, emerg.
+    LogLevel warn
+    CustomLog /var/log/apache2/netbox.wikimedia.org-access.log wmf
+    ErrorLog /var/log/apache2/netbox.wikimedia.org-error.log
+
+</VirtualHost>

-- 
To view, visit https://gerrit.wikimedia.org/r/387880
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia3354fcf251952a27d58eba3487043d8d4bd26fe
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Ayounsi <ayou...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to