diff --git a/Dockerfile b/Dockerfile index b85f1c4..88e1c39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,12 @@ ENV PYTHONUNBUFFERED 1 WORKDIR /app/ -RUN apt update && apt install -y netcat libmariadb-dev-compat libmariadb-dev mariadb-client gcc +RUN apt update && apt install -y procps less netcat libmariadb-dev-compat libmariadb-dev mariadb-client gcc nginx-light -COPY ./docker/scripts/entrypoint.sh /usr/local/bin/entrypoint +COPY ./docker/nginx/updatesdashboard.conf /etc/nginx/sites-enabled/updatesdashboard.conf +RUN rm -f /etc/nginx/sites-enabled/default + +COPY ./docker/scripts/entrypoint.dev.sh /usr/local/bin/entrypoint RUN chmod +x /usr/local/bin/entrypoint RUN addgroup --system gunicorn --gid ${APP_GID} && adduser --uid ${APP_UID} --system --disabled-login --group gunicorn @@ -25,7 +28,6 @@ COPY ./app/updatesdashboard/.env.dev ./updatesdashboard/.env RUN python /app/manage.py makemigrations RUN python /app/manage.py makemigrations dashboard -RUN python /app/manage.py collectstatic RUN rm -f ./updatesdashboard/.env diff --git a/app/dashboard/admin.py b/app/dashboard/admin.py index 4898622..edda903 100644 --- a/app/dashboard/admin.py +++ b/app/dashboard/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import Os, ServerStatus, Server, PackageStatus, Team +from .models import Os, ServerStatus, Server, PackageStatus class OsAdmin(admin.ModelAdmin): @@ -10,4 +10,3 @@ admin.site.register(Os, OsAdmin) admin.site.register(ServerStatus) admin.site.register(PackageStatus) admin.site.register(Server) -admin.site.register(Team) diff --git a/app/dashboard/fixtures/teams.yaml b/app/dashboard/fixtures/teams.yaml deleted file mode 100644 index 2dfe9c0..0000000 --- a/app/dashboard/fixtures/teams.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This is initial data for prod teams - -- model: dashboard.team - pk: null - fields: { - name: System, - color: pink - } diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 3c4c4f3..5cfc66e 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -32,32 +32,9 @@ class Os(models.Model): -class Group(models.Model): - name = models.CharField(max_length=50, unique=True) - full_name = models.CharField(max_length=50, null=True) - - def __str__(self): - if self.full_name: - return self.full_name - else: - return self.name - - - -class Team(models.Model): - name = models.CharField(max_length=20) - color = models.CharField(max_length=20, unique=True) - - def __str__(self): - return self.name - - - class Server(models.Model): hostname = models.CharField(max_length=200, unique=True) os = models.ForeignKey(Os, null=True, related_name="servers", on_delete=models.SET_NULL) - group = models.ForeignKey(Group, null=True, blank=True, related_name="groups", on_delete=models.SET_NULL) - team = models.ForeignKey(Team, null=True, related_name="teams", on_delete=models.SET_NULL) def __str__(self): return self.hostname diff --git a/app/dashboard/templates/os-statistics.html b/app/dashboard/templates/os-statistics.html index 6aadc01..bd6d607 100644 --- a/app/dashboard/templates/os-statistics.html +++ b/app/dashboard/templates/os-statistics.html @@ -20,7 +20,7 @@ - + diff --git a/app/dashboard/urls.py b/app/dashboard/urls.py index 3632f93..748e2ae 100644 --- a/app/dashboard/urls.py +++ b/app/dashboard/urls.py @@ -19,12 +19,6 @@ urlpatterns = [ re_path(r'^server-list/(?P[0-9]{4})/(?P[0-9]{1,2})/(?P[0-9]{1,2})/?$', views.server_list, name='server-list-by-date'), - re_path(r'^server-list/(?P[a-z0-9\-_]*)/(?P[0-9]{4})/(?P[0-9]{1,2})/(?P[0-9]{1,2})/?$', - views.server_list, - name='server-list-by-group'), - re_path(r'^server-list/team/(?P[a-z]*)/(?P[0-9]{4})/(?P[0-9]{1,2})/(?P[0-9]{1,2})/?$', - views.server_list, - name='server-list-by-team'), # package list re_path(r'^packages/?$', @@ -69,9 +63,6 @@ urlpatterns = [ re_path(r'^manage-packages/upload_csv_results_packages', views.upload_csv_results_packages, name='upload_csv_results_packages'), -# re_path(r'^manage/update-groups/?$', -# views.update_groups, -# name='update_groups'), # manage packages re_path(r'^manage-packages/?$', diff --git a/app/dashboard/views.py b/app/dashboard/views.py index b037c31..3e706be 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -16,7 +16,7 @@ from django.core.cache import cache from django.db import IntegrityError from django.contrib.auth.decorators import login_required # project -from .models import Os, Group, Server, ServerStatus, PackageStatus, Team, Document_Servers, Document_Packages +from .models import Os, Server, ServerStatus, PackageStatus, Document_Servers, Document_Packages from .forms import DocumentForm @@ -36,7 +36,7 @@ def index(request): ## ----------------------------------------------------------------------------- @login_required -def server_list(request, year=None, month=None, day=None, group=None, team=None): +def server_list(request, year=None, month=None, day=None): # TODO: use date.today? now = datetime.now() if not year or not month or not day: @@ -64,24 +64,11 @@ def server_list(request, year=None, month=None, day=None, group=None, team=None) next_result_date = next_result.date results_date = current_date - if group: - group = get_object_or_404(Group, name=group) - status_list = ServerStatus.objects.filter(date=current_date, server__group=group).order_by('server__hostname') - if previous_result and not status_list: - status_list = ServerStatus.objects.filter(date=previous_result_date, server__group=group).order_by('server__hostname') - results_date = previous_result_date - elif team: - team = get_object_or_404(Team, color=team) - status_list = ServerStatus.objects.filter(date=current_date, server__team=team).order_by('server__hostname') - if previous_result and not status_list: - status_list = ServerStatus.objects.filter(date=previous_result_date, server__team=team).order_by('server__hostname') - results_date = previous_result_date - else: - # status_list = ServerStatus.objects.filter(date=current_date).order_by('server__hostname') - status_list = ServerStatus.objects.filter(date=current_date).order_by('server__hostname').select_related('server', 'server__group', 'server__os') - if previous_result and not status_list: - status_list = ServerStatus.objects.filter(date=previous_result_date).order_by('server__hostname').select_related('server', 'server__group', 'server__os') - results_date = previous_result_date + # status_list = ServerStatus.objects.filter(date=current_date).order_by('server__hostname') + status_list = ServerStatus.objects.filter(date=current_date).order_by('server__hostname').select_related('server', 'server__os') + if previous_result and not status_list: + status_list = ServerStatus.objects.filter(date=previous_result_date).order_by('server__hostname').select_related('server', 'server__os') + results_date = previous_result_date if not status_list: return render(request, 'generic.html', { @@ -90,7 +77,6 @@ def server_list(request, year=None, month=None, day=None, group=None, team=None) return render(request, 'server-list.html', { - 'group': group, 'status_list': status_list, 'results_date': results_date, 'previous_result_date': previous_result_date, @@ -332,7 +318,6 @@ def purge_all(request): ServerStatus.objects.all().delete() Os.objects.all().delete() PackageStatus.objects.all().delete() - Group.objects.all().delete() content = "" diff --git a/app/defaults/settings_local.py b/app/defaults/settings_local.py index 9064ad4..a5173f4 100644 --- a/app/defaults/settings_local.py +++ b/app/defaults/settings_local.py @@ -37,37 +37,9 @@ INSTALLED_APPS_LOCAL = [ # LDAP AUTH AUTHENTICATION_BACKENDS = ( - 'django_python3_ldap.auth.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', ) -LDAP_AUTH_URL = "ldaps://SERVER:PORT" -LDAP_AUTH_USE_TLS = True -LDAP_AUTH_SEARCH_BASE = "ou=USERS,dc=MY,dc=ORG" -LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson" -LDAP_AUTH_USER_FIELDS = { - "username": "uid", - "first_name": "givenName", - "last_name": "sn", - "email": "mail", -} -LDAP_AUTH_FORMAT_SEARCH_FILTERS = "dashboard.module.custom_format_search_filters" -LDAP_AUTH_CUSTOM_OBJECT_CLASS = "ACLASS" -LDAP_AUTH_CUSTOM_FILTERS = "(SOMEFIELD=SOMEVALUE)" MIDDLEWARE_LOCAL = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', ] - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.10/howto/static-files/ - -STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, './static') - -# custom -RESULT_DIR = os.path.join(BASE_DIR, 'results') -RESULT_PACKAGES_DIR = os.path.join(BASE_DIR, 'results-packages') -INVENTORY_DIR = os.path.join(BASE_DIR, 'inventory') - -LOGIN_URL = '/login' -LOGIN_REDIRECT_URL = 'index' diff --git a/app/requirements.txt b/app/requirements.txt index 63c3449..885b423 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -3,6 +3,7 @@ Django django-extensions gunicorn django-debug-toolbar +django-environ django-python3-ldap requests mysqlclient diff --git a/app/results/2022-08-17.csv b/app/results/2022-08-17.csv new file mode 100644 index 0000000..5a680a5 --- /dev/null +++ b/app/results/2022-08-17.csv @@ -0,0 +1,19 @@ +vlearning-db001-tst.infolegale.net;Debian;10;0;5 +app-db001-tst.infolegale.net;Debian;10;0;9 +consults-db001-tst.infolegale.net;Debian;10;0;147 +vador-db001-tst.infolegale.net;Debian;10;0;147 +tlearning-db003-tst.infolegale.net;Ubuntu;18.04;0;308 +transdb-db001-tst.infolegale.net;Debian;10;0;147 +mysql8-db001-tst.infolegale.net;Debian;11;3;119 +mongo-db001-tst.infolegale.net;Ubuntu;20.04;0;28 +orchestrator-mgr001-tst.infolegale.net;Ubuntu;20.04;0;28 +redis5-db001-tst.infolegale.net;Debian;10;0;326 +redis-db001-tst.infolegale.net;Ubuntu;18.04;0;326 +docker-hpv001-tst.infolegale.net;Ubuntu;20.04;0;106 +docker-hpv002-tst.infolegale.net;Ubuntu;20.04;0;398 +docker-hpv003-tst.infolegale.net;Ubuntu;20.04;0;125 +rundeck-sch001-tst.infolegale.net;Debian;10;0;91 +proxysql-db001-tst.infolegale.net;Ubuntu;20.04;0;475 +docker-hpv005-tst.infolegale.net;Ubuntu;20.04;0;119 +docker-hpv004-tst.infolegale.net;Ubuntu;20.04;0;28 +docker-hpv006-tst.infolegale.net;Ubuntu;20.04;0;309 diff --git a/app/updatesdashboard/.env.dev b/app/updatesdashboard/.env.dev new file mode 100644 index 0000000..b9119a7 --- /dev/null +++ b/app/updatesdashboard/.env.dev @@ -0,0 +1,10 @@ +GUNICORN_CMD_ARGS=--bind=127.0.0.1:3000 --workers=3 --timeout=300 --error-logfile=/var/log/gunicorn-error.log +DJANGO_SUPERUSER_PASSWORD=admin +SECRET_KEY=uv88xpv8kb2r6j7rubtnhkps +DATABASE_NAME=updates_dashboard +DATABASE_USER=updates_dashboard +DATABASE_PASSWORD=miengetBatheajOf +DATABASE_HOST=mysql +DATABASE_PORT=3306 +DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 +DJANGO_CSRF_TRUSTED_ORIGINS=http://localhost diff --git a/app/updatesdashboard/settings.py b/app/updatesdashboard/settings.py index 6149a85..007f329 100644 --- a/app/updatesdashboard/settings.py +++ b/app/updatesdashboard/settings.py @@ -10,11 +10,23 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.10/ref/settings/ """ +import os from .settings_local import * +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +# for debug_toolbar +INTERNAL_IPS = ['127.0.0.1', ] +DEBUG_TOOLBAR = True # Application definition - +INSTALLED_APPS_LOCAL = [ + 'debug_toolbar', +# 'django_python3_ldap', +] INSTALLED_APPS = [ 'dashboard.apps.DashboardConfig', 'django.contrib.admin', @@ -26,6 +38,10 @@ INSTALLED_APPS = [ 'django_extensions', ] + INSTALLED_APPS_LOCAL +MIDDLEWARE_LOCAL = [ + 'debug_toolbar.middleware.DebugToolbarMiddleware', +] + MIDDLEWARE = MIDDLEWARE_LOCAL + [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -74,6 +90,23 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.10/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, './static') + +# custom +RESULT_DIR = os.path.join(BASE_DIR, 'results') +RESULT_PACKAGES_DIR = os.path.join(BASE_DIR, 'results-packages') +INVENTORY_DIR = os.path.join(BASE_DIR, 'inventory') + +LOGIN_URL = '/login' +LOGIN_REDIRECT_URL = 'index' + +# for debug_toolbar +INTERNAL_IPS = ['127.0.0.1', ] +DEBUG_TOOLBAR = True # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ diff --git a/app/updatesdashboard/settings_local.py b/app/updatesdashboard/settings_local.py new file mode 100644 index 0000000..a31defc --- /dev/null +++ b/app/updatesdashboard/settings_local.py @@ -0,0 +1,19 @@ +import environ + +env = environ.Env() +# reading .env file +environ.Env.read_env() + +ALLOWED_HOSTS = env("DJANGO_ALLOWED_HOSTS").split(" ") +CSRF_TRUSTED_ORIGINS = env("DJANGO_CSRF_TRUSTED_ORIGINS").split(" ") +SECRET_KEY = env("SECRET_KEY") +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': env("DATABASE_NAME"), + 'USER': env("DATABASE_USER"), + 'PASSWORD': env("DATABASE_PASSWORD"), + 'HOST': env("DATABASE_HOST"), + 'PORT': int(env("DATABASE_PORT")), + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 327d1d2..23c7e1e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,9 +5,8 @@ services: build: context: ./ target: app_dev - command: /usr/local/bin/gunicorn /app/manage.py ports: - - "3000:80" + - "3000:3001" volumes: - ./app/:/app/ env_file: diff --git a/docker/nginx/updatesdashboard.conf b/docker/nginx/updatesdashboard.conf new file mode 100644 index 0000000..60a1fad --- /dev/null +++ b/docker/nginx/updatesdashboard.conf @@ -0,0 +1,25 @@ +server { + listen 3001; + server_name updates-dashboard.infolegale.net; + + # css, js… + location /static { + alias /app/static; + } + + if ($request_uri !~ "^/admin.*") { + # don't rewrite admin + rewrite ^/(.*)/$ /$1 permanent; + } + + location / { + include proxy_params; + proxy_pass http://127.0.0.1:3000; + proxy_connect_timeout 120s; + proxy_read_timeout 300s; + + } + + error_log /var/log/updatesdashboard-error.log; + access_log /var/log/updatesdashboard-access.log; +} diff --git a/docker/scripts/entrypoint.dev.sh b/docker/scripts/entrypoint.dev.sh new file mode 100644 index 0000000..82beb9b --- /dev/null +++ b/docker/scripts/entrypoint.dev.sh @@ -0,0 +1,11 @@ +#!/bin/sh +until nc -vz $1 $2; do echo "Waiting for MySQL $1:$2..."; sleep 3; done; + +python /app/manage.py migrate +python /app/manage.py collectstatic +python /app/manage.py loaddata /app/dashboard/fixtures/os.yaml +python /app/manage.py createsuperuser --noinput --username admin --email test@example.com +service nginx start +gunicorn updatesdashboard.wsgi:application + +exec "$@" diff --git a/docker/scripts/entrypoint.prod.sh b/docker/scripts/entrypoint.prod.sh new file mode 100644 index 0000000..3d3b1be --- /dev/null +++ b/docker/scripts/entrypoint.prod.sh @@ -0,0 +1,8 @@ +#!/bin/sh +until nc -vz $1 $2; do echo "Waiting for MySQL $1:$2..."; sleep 3; done; + +#python /app/manage.py flush --no-input +#python /app/manage.py migrate +#python /app/manage.py loaddata dashboard/fixtures/os.yaml + +exec "$@" diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh deleted file mode 100644 index ceda1db..0000000 --- a/docker/scripts/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -until nc -vz $1 $2; do echo "Waiting for MySQL $1:$2..."; sleep 3; done; - -python /app/manage.py migrate -python /app/manage.py loaddata dashboard/fixtures/os.yaml
HostnameDistribution Number Percentage