commit 59cf25f14512f6e654739fa24af2935c11392ce1 Author: IluaAir Date: Fri May 30 18:22:12 2025 +0300 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e76776b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.venv/ +/.vagrant/ +/.idea/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..fec68b9 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,17 @@ +Vagrant.configure("2") do |config| + config.vm.box = "spox/ubuntu-arm" # Выбрать образ для х86 + config.vm.provision "ansible_local" do |ansible| + ansible.become = true + ansible.playbook = "provisioning/playbook.yml" + ansible.config_file = "provisioning/ansible.cfg" + end + config.vm.provider :vmware_desktop do |hypervisor| # Заменить :virtualbox + hypervisor.gui = true + hypervisor.cpus = 2 + hypervisor.memory = 4096 + # hypervisor.vmx["ethernet0.virtualdev"] = "vmxnet3" + # hypervisor.ssh_info_public = true + hypervisor.linked_clone = false + hypervisor.vmx["vhv.enable"] = "TRUE" # Для аппаратной виртуализации + end +end \ No newline at end of file diff --git a/provisioning/ansible.cfg b/provisioning/ansible.cfg new file mode 100644 index 0000000..7cc06fd --- /dev/null +++ b/provisioning/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +allow_world_readable_tmpfiles = true \ No newline at end of file diff --git a/provisioning/playbook.yml b/provisioning/playbook.yml new file mode 100644 index 0000000..1a62fe8 --- /dev/null +++ b/provisioning/playbook.yml @@ -0,0 +1,268 @@ +--- +- name: Update web servers + hosts: all + become: yes + vars: + netbox_ver: 4.3.1 + timezone: Europe/Moscow + db_name: netbox + db_user: netbox + db_user_password: "J5brHrAXFLQSif0K" + postgres_admin_user: postgres + postgres_admin_password: postgres + superuser_username: admin + superuser_email: admin@example.com + superuser_password: "P@ssw0rd" + gunicorn_systemd: + - netbox + - netbox-rq + required_packages: + - postgresql-14 + - postgresql-contrib + - redis + - python3-pip + - libpq-dev + netbox_packages: + - python3.10 + - python3.10-venv + - python3.10-dev + - build-essential + - libxml2-dev + - libxslt1-dev + - libffi-dev + - libssl-dev + - zlib1g-dev + - git + + tasks: + - name: Stop PostgreSQL 12 cluster if running + command: pg_ctlcluster 12 main stop + ignore_errors: yes + tags: database + - name: Disable auto-start of PostgreSQL 12 cluster + systemd: + name: postgresql@12-main + enabled: no + state: stopped + ignore_errors: yes + tags: database + + - name: Add key for Postgres repo + apt_key: + url: https://www.postgresql.org/media/keys/ACCC4CF8.asc + state: present + - name: Add PostgreSQL APT repository (PGDG) with GPG key + apt_repository: + repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_lsb.codename }}-pgdg main" + filename: pgdg + state: present + tags: packages + + - name: Add Python repo + apt_repository: + repo: ppa:deadsnakes/ppa + state: present + tags: packages + - name: Update apt cache + apt: + update_cache: yes + tags: packages + - name: Install Postgresql14 + apt: + name: "{{ item }}" + loop: "{{ required_packages }}" + tags: packages + - name: Create and start PostgreSQL 14 cluster + become: yes + command: pg_createcluster 14 main --start + args: + creates: /var/lib/postgresql/14/main + tags: database + + - name: Ensure PostgreSQL service is running + service: + name: postgresql@14-main + state: started + enabled: yes + tags: database + + - name: Ensure Redis service is running + service: + name: redis + state: started + enabled: yes + tags: redis + - name: Install psycopg2 python package + pip: + name: psycopg2 + tags: post + - name: Create a new database with name "Netbox" + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ db_name }}" + tags: database + - name: Ensure netbox user exists + become_user: postgres + community.postgresql.postgresql_user: + name: "{{ db_user }}" + password: "{{ db_user_password }}" + tags: database + - name: Change owner of the database to netbox user + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ db_name }}" + owner: "{{ db_user }}" + tags: database + - name: Grant CREATE privilege on public schema to netbox + become_user: postgres + community.postgresql.postgresql_query: + db: "{{ db_name }}" + query: "GRANT CREATE ON SCHEMA public TO {{ db_user }};" + tags: database + - name: Install netbox-components + apt: + name: "{{ item }}" + loop: "{{ netbox_packages }}" + tags: packages + + - name: Download Netbox + get_url: + url: "https://github.com/netbox-community/netbox/archive/refs/tags/v{{ netbox_ver }}.tar.gz" + dest: "/root/v{{ netbox_ver }}.tar.gz" + tags: netbox + - name: Extract Netbox + unarchive: + src: "/root/v{{ netbox_ver }}.tar.gz" + dest: "/opt" + remote_src: yes + tags: netbox + - name: Link Netbox files + file: + src: "/opt/netbox-{{ netbox_ver }}" + dest: "/opt/netbox" + state: link + tags: netbox + - name: Create group 'netbox' + group: + name: netbox + system: yes + tags: netbox + - name: Create system user + user: + name: netbox + system: yes + group: netbox + create_home: no + tags: netbox + - name: Change folders own + file: + path: "{{ item }}" + owner: netbox + recurse: yes + loop: + - "/opt/netbox/netbox/media/" + - "/opt/netbox/netbox/reports/" + - "/opt/netbox/netbox/scripts/" + tags: netbox + - name: Generate NetBox SECRET_KEY if not already set + shell: "openssl rand -base64 50" + register: secret_key_output + changed_when: false + when: secret_key == '' or secret_key is not defined + - name: Set generated SECRET_KEY fact + set_fact: + secret_key: "{{ secret_key_output.stdout }}" + when: secret_key == '' or secret_key is not defined + - name: Generate NetBox configuration + template: + src: configuration.py.j2 + dest: /opt/netbox/netbox/netbox/configuration.py + owner: netbox + group: netbox + mode: '0640' + tags: netbox + - name: Run NetBox upgrade script with Python 3.10 + environment: + PYTHON: /usr/bin/python3.10 + command: /opt/netbox/upgrade.sh + tags: netbox + - name: Create NetBox superuser + vars: + netbox_dir: /opt/netbox/netbox + venv_dir: /opt/netbox/venv + environment: + DJANGO_SUPERUSER_USERNAME: "{{ superuser_username }}" + DJANGO_SUPERUSER_EMAIL: "{{ superuser_email }}" + DJANGO_SUPERUSER_PASSWORD: "{{ superuser_password }}" + command: "{{ venv_dir }}/bin/python3 manage.py createsuperuser --no-input" + args: + chdir: "{{ netbox_dir }}" + register: create_superuser + failed_when: false + changed_when: "'Superuser created successfully' in create_superuser.stdout" + tags: netbox + + - name: Debug superuser creation result + debug: + var: create_superuser.stderr + tags: netbox + - name: Link Netbox-Housekeeping + file: + src: "/opt/netbox/contrib/netbox-housekeeping.sh" + dest: "/etc/cron.daily/netbox-housekeeping" + state: link + tags: netbox + - name: Copy Gunicorn config + copy: + src: "/opt/netbox/contrib/gunicorn.py" + dest: "/opt/netbox/gunicorn.py" + tags: gunicorn + - name: Copy Gunicorn-sysctl unit + copy: + src: "/opt/netbox/contrib/{{ item }}.service" + dest: "/etc/systemd/system/{{ item }}.service" + loop: "{{ gunicorn_systemd }}" + tags: gunicorn + - name: Reload systemd daemon to recognize new service + systemd: + daemon_reload: yes + tags: gunicorn + - name: Enable and start netbox-gunicorn service + systemd: + name: "{{ item }}" + enabled: yes + state: started + loop: "{{ gunicorn_systemd }}" + tags: gunicorn + - name: Generate self-signed SSL certificate for NetBox + command: > + openssl req -x509 -nodes -days 365 + -newkey rsa:2048 + -keyout /etc/ssl/private/netbox.key + -out /etc/ssl/certs/netbox.crt + -subj "/C=RU/ST=Moscow/L=Moscow/O=YourOrg/OU=IT/CN=netbox.example.com" + args: + creates: /etc/ssl/private/netbox.key + become: yes + tags: ssl + - name: Install Nginx + apt: + name: nginx + state: present + tags: nginx + - name: Copy configuration nebox to Nginx + copy: + src: "/opt/netbox/contrib/nginx.conf" + dest: "/etc/nginx/sites-available/netbox" + tags: nginx + - name: Enable netbox site in Nginx + file: + src: "/etc/nginx/sites-available/netbox" + dest: "/etc/nginx/sites-enabled/netbox" + state: link + tags: nginx + - name: Restart Nginx + systemd: + name: nginx + state: reloaded + tags: nginx diff --git a/provisioning/templates/configuration.py.j2 b/provisioning/templates/configuration.py.j2 new file mode 100644 index 0000000..69e9891 --- /dev/null +++ b/provisioning/templates/configuration.py.j2 @@ -0,0 +1,112 @@ +######################### +# # +# Required settings # +# # +######################### + +ALLOWED_HOSTS = {{ allowed_hosts | default(['*']) }} + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': '{{ db_name }}', + 'USER': '{{ db_user }}', + 'PASSWORD': '{{ db_user_password }}', + 'HOST': '{{ db_host | default("localhost") }}', + 'PORT': '{{ db_port | default("") }}', + 'CONN_MAX_AGE': 300, + } +} + +REDIS = { + 'tasks': { + 'HOST': '{{ redis_host | default("localhost") }}', + 'PORT': {{ redis_port | default(6379) }}, + 'USERNAME': '', + 'PASSWORD': '', + 'DATABASE': 0, + 'SSL': False, + }, + 'caching': { + 'HOST': '{{ redis_host | default("localhost") }}', + 'PORT': {{ redis_port | default(6379) }}, + 'USERNAME': '', + 'PASSWORD': '', + 'DATABASE': 1, + 'SSL': False, + } +} + +SECRET_KEY = '{{ secret_key | replace("\n", "") }}' + +######################### +# # +# Optional settings # +# # +######################### + +ADMINS = {{ admins | default([]) }} + +ALLOW_TOKEN_RETRIEVAL = False + +AUTH_PASSWORD_VALIDATORS = [] + +BASE_PATH = '{{ base_path | default("") }}' + +CORS_ORIGIN_ALLOW_ALL = False +CORS_ORIGIN_WHITELIST = {{ cors_whitelist | default([]) }} +CORS_ORIGIN_REGEX_WHITELIST = {{ cors_regex_whitelist | default([]) }} + +CSRF_COOKIE_NAME = 'csrftoken' + +DEBUG = {{ debug | default(False) }} + +DEFAULT_LANGUAGE = '{{ default_language | default("en-us") }}' + +EMAIL = { + 'SERVER': '{{ email_server | default("localhost") }}', + 'PORT': {{ email_port | default(25) }}, + 'USERNAME': '{{ email_username | default("") }}', + 'PASSWORD': '{{ email_password | default("") }}', + 'USE_SSL': {{ email_use_ssl | default(False) }}, + 'USE_TLS': {{ email_use_tls | default(False) }}, + 'TIMEOUT': 10, + 'FROM_EMAIL': '{{ email_from | default("") }}', +} + +EXEMPT_VIEW_PERMISSIONS = {{ exempt_view_permissions | default([]) }} + +INTERNAL_IPS = ('127.0.0.1', '::1') + +LOGGING = {} + +LOGIN_PERSISTENCE = False +LOGIN_REQUIRED = True +LOGIN_TIMEOUT = None +LOGIN_FORM_HIDDEN = False +LOGOUT_REDIRECT_URL = 'home' + +METRICS_ENABLED = False + +PLUGINS = {{ plugins | default([]) }} + +PLUGINS_CONFIG = {{ plugins_config | default({}) }} + +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 = {} + +RELEASE_CHECK_URL = None + +RQ_DEFAULT_TIMEOUT = 300 + +SESSION_COOKIE_NAME = 'sessionid' +SESSION_FILE_PATH = None + +TIME_ZONE = '{{ timezone | default("UTC") }}'