# Django:
*.log
*.pot
-migrations/
-settings.py
+
+# Celery
+celerybeat-schedule.db
# KDE:
.directory
# Bower Components:
bower_components/
+
+# Production settings
+config.env
+
+# rsa key files
+rsa.pem
+rsa.pub
--- /dev/null
+build:
+ docker-compose build
+
+up:
+ docker-compose up -d
+
+start:
+ docker-compose start
+
+stop:
+ docker-compose stop
+
+shell-nginx:
+ docker exec -ti ng01 bash
+
+shell-web:
+ docker exec -ti dg01 bash
+
+shell-db:
+ docker exec -ti ps01 bash
+
+log-nginx:
+ docker-compose logs nginx
+
+log-web:
+ docker-compose logs web
+
+log-ps:
+ docker-compose logs postgres
+
+log-rmq:
+ docker-compose logs rabbitmq
+
+log-worker:
+ docker-compose logs worker
--- /dev/null
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG=False
+
+DB_NAME=sample_name
+DB_USER=sample_user
+DB_PASS=sample_pass
+DB_SERVICE=postgres
+DB_PORT=5432
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY=http://www.miniwebtool.com/django-secret-key-generator/
+
+OAUTH_CONSUMER_KEY=sample_key
+OAUTH_CONSUMER_SECRET=sample_secret
+
+JIRA_URL=sample_url
+JIRA_USER_NAME=sample_jira_user
+JIRA_USER_PASSWORD=sample_jira_pass
\ No newline at end of file
--- /dev/null
+upstream web {
+ ip_hash;
+ server web:8000;
+}
+
+# portal
+server {
+ listen 80;
+ server_name localhost;
+ charset utf-8;
+
+ location /static {
+ alias /static;
+ }
+
+ location /media {
+ alias /media;
+ }
+
+ location / {
+ proxy_set_header Host $host;
+ proxy_pass http://web/;
+ }
+}
--- /dev/null
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+#!/bin/env bash
+
+psql -U postgres -c "CREATE USER $DB_USER PASSWORD '$DB_PASS'"
+psql -U postgres -c "CREATE DATABASE $DB_NAME OWNER $DB_USER"
+++ /dev/null
-* Database
-
-** Setup
-- sudo -u postgres psql
-- postgres=# CREATE DATABASE pharos_dashboard
-- postgres=# CREATE USER opnfv WITH PASSWORD 'opnfvopnfv'
-- postgres# createuser --interactive
-- postgres# ALTER ROLE opnfv SET client_encoding TO 'utf8';
-- postgres# ALTER ROLE opnfv SET default_transaction_isolation TO 'read committed';
-- postgres# ALTER ROLE opnfv SET timezone TO 'UTC';
-- postgres# GRANT ALL PRIVILEGES ON DATABASE pharos_dashboard TO opnfv;
-
-** Dump data
-
-- log out all users, stop server
-- (venv) # python manage.py dumpdata > dashboard/fixtures/<dump_name>.json
-
-** Load dump
-
-- setup clean database, run migrate
-- (venv) # python manage.py loaddata <dump_name>
-
-* Django
-
-** Virtualenv setup
-
-- # virtualenv venv
-- # source venv/bin/activate
-- (venv) # pip install -r requirements.txt
-
-** initializing or after change in models.py
-
-- (venv) # python manage.py makemigrations
-- (venv) # python manage.py migrate
-
-** Development
-
-- (venv) # python manage.py runserver
-- (venv) # python manage.py shell
-
-* Dependencies
-
-Javascript / CSS dependencies are managed with bower. To install them, you have to install bower, switch directory to the dashboard/static folder and run
-# bower install
-Bower will download and install the right versions of all the static files.
--- /dev/null
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+version: '2'
+services:
+ nginx:
+ restart: always
+ image: nginx:latest
+ container_name: ng01
+ ports:
+ - "80:80"
+ volumes:
+ - ./config/nginx:/etc/nginx/conf.d
+ - /var/lib/pharos_dashboard/static:/static
+ - /var/lib/pharos_dashboard/media:/media
+ depends_on:
+ - web
+
+ web:
+ restart: always
+ build: ./web/
+ container_name: dg01
+ command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --no-input && gunicorn pharos_dashboard.wsgi -b 0.0.0.0:8000"
+ depends_on:
+ - postgres
+ links:
+ - postgres
+ env_file: config.env
+ volumes:
+ - ./src:/src
+ - /var/lib/pharos_dashboard/static:/static
+ - /var/lib/pharos_dashboard/media:/media
+ expose:
+ - "8000"
+
+ postgres:
+ restart: always
+ image: postgres:latest
+ container_name: ps01
+ env_file: config.env
+ volumes:
+ - ./config/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
+ - /var/lib/pharos_dashboard/postgresql:/var/lib/postgresql
+
+ rabbitmq:
+ restart: always
+ image: rabbitmq:latest
+ container_name: rm01
+ expose:
+ - "5672"
+
+ worker:
+ restart: always
+ build: ./worker/
+ command: bash -c "celery -A pharos_dashboard worker -l info -B"
+ env_file: config.env
+ links:
+ - postgres
+ - rabbitmq
+ volumes:
+ - ./src:/src
+
\ No newline at end of file
--- /dev/null
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+The dashboard is deployed using docker-compose.
+Application / database files are saved in /var/lib/pharos_dashboard/.
+
+Deployment:
+
+- clone the repository
+- complete the config.env.sample file and save it as config.env
+- install docker, docker-compose and bower
+- run 'bower install' in ./src/static/ to fetch javascript dependencies
+- run 'make build' to build the containers
+- run 'make up' to run the dashboard
+
+Updating:
+
+- make stop
+- git pull
+- run 'bower install' if javascript dependencies changed
+- make build
+- make start
+
+If there is migrations that need user input (like renaming a field), they need to be run manually!
+
+Logs / Shell access:
+
+- there is some shortcuts in the makefile
\ No newline at end of file
--- /dev/null
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from django.conf import settings
+from django.contrib import admin
+
+from jenkins.models import JenkinsSlave
+
+if settings.DEBUG:
+ admin.site.register(JenkinsSlave)
\ No newline at end of file
--- /dev/null
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
--- /dev/null
+import os
+from datetime import timedelta
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = os.environ['DEBUG']
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'dashboard',
+ 'booking',
+ 'account',
+ 'jenkins',
+ 'notification',
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'django.contrib.humanize',
+ 'bootstrap3',
+ 'crispy_forms',
+ 'rest_framework',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'account.middleware.TimezoneMiddleware',
+]
+
+ROOT_URLCONF = 'pharos_dashboard.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [os.path.join(BASE_DIR, 'templates')]
+ ,
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'pharos_dashboard.wsgi.application'
+
+# Password validation
+# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.10/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+MEDIA_URL = '/media/'
+STATIC_URL = '/static/'
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+STATICFILES_DIRS = [
+ os.path.join(BASE_DIR, "static"),
+]
+
+LOGIN_REDIRECT_URL = '/'
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = os.environ['SECRET_KEY']
+
+BOOTSTRAP3 = {
+ 'set_placeholder': False,
+}
+
+ALLOWED_HOSTS = ['*']
+
+# Database
+# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': os.environ['DB_NAME'],
+ 'USER': os.environ['DB_USER'],
+ 'PASSWORD': os.environ['DB_PASS'],
+ 'HOST': os.environ['DB_SERVICE'],
+ 'PORT': os.environ['DB_PORT']
+ }
+}
+
+
+# Rest API Settings
+REST_FRAMEWORK = {
+ 'DEFAULT_PERMISSION_CLASSES': [
+ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
+ ],
+ 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
+}
+
+MEDIA_ROOT = '/media'
+STATIC_ROOT = '/static'
+
+# Jira Settings
+CREATE_JIRA_TICKET = False
+
+JIRA_URL = os.environ['JIRA_URL']
+
+JIRA_USER_NAME = os.environ['JIRA_USER_NAME']
+JIRA_USER_PASSWORD = os.environ['JIRA_USER_PASSWORD']
+
+OAUTH_CONSUMER_KEY = os.environ['OAUTH_CONSUMER_KEY']
+OAUTH_CONSUMER_SECRET = os.environ['OAUTH_CONSUMER_SECRET']
+
+OAUTH_REQUEST_TOKEN_URL = JIRA_URL + '/plugins/servlet/oauth/request-token'
+OAUTH_ACCESS_TOKEN_URL = JIRA_URL + '/plugins/servlet/oauth/access-token'
+OAUTH_AUTHORIZE_URL = JIRA_URL + '/plugins/servlet/oauth/authorize'
+
+OAUTH_CALLBACK_URL = JIRA_URL + '/accounts/authenticated'
+
+# Celery Settings
+CELERY_TIMEZONE = 'UTC'
+
+RABBITMQ_URL = 'rabbitmq'
+BROKER_URL = 'amqp://guest:guest@rabbitmq:5672//'
+
+CELERYBEAT_SCHEDULE = {
+ 'sync-jenkins': {
+ 'task': 'jenkins.tasks.sync_jenkins',
+ 'schedule': timedelta(minutes=5)
+ },
+ 'send-booking-notifications': {
+ 'task': 'notification.tasks.send_booking_notifications',
+ 'schedule': timedelta(minutes=5)
+ },
+ 'clean-database': {
+ 'task': 'dashboard.tasks.database_cleanup',
+ 'schedule': timedelta(hours=24)
+ },
+}
\ No newline at end of file
class="fa fa-fw"></i>Jenkins
Slaves</a>
</li>
- <li>
- <a href="{% url 'dashboard:resources' %}"><i
- class="fa fa-fw"></i>Resources
- </a>
- </li>
<li>
<a href="{% url 'account:users' %}"><i
class="fa fa-fw"></i>Users
--- /dev/null
+FROM python:3.5
+ENV PYTHONUNBUFFERED 1
+RUN mkdir /config
+ADD ./requirements.txt /config/
+RUN pip install -r /config/requirements.txt
+RUN mkdir /src;
+WORKDIR /src
--- /dev/null
+celery==3.1.23
+cryptography==1.4
+Django==1.10
+django-bootstrap3==7.0.1
+django-crispy-forms==1.6.0
+django-filter==0.14.0
+django-registration==2.1.2
+djangorestframework==3.4.6
+gunicorn==19.6.0
+jira==1.0.7
+oauth2==1.9.0.post1
+oauthlib==1.1.2
+pika==0.10.0
+psycopg2==2.6.2
+PyJWT==1.4.2
+requests==2.11.0
--- /dev/null
+FROM python:3.5
+ENV PYTHONUNBUFFERED 1
+RUN mkdir /config
+ADD ./requirements.txt /config/
+RUN pip install -r /config/requirements.txt
+RUN useradd -ms /bin/bash celery
+USER celery
+WORKDIR /src
--- /dev/null
+celery==3.1.23
+cryptography==1.4
+Django==1.10
+django-bootstrap3==7.0.1
+django-crispy-forms==1.6.0
+django-filter==0.14.0
+django-registration==2.1.2
+djangorestframework==3.4.6
+gunicorn==19.6.0
+jira==1.0.7
+oauth2==1.9.0.post1
+oauthlib==1.1.2
+pika==0.10.0
+psycopg2==2.6.2
+PyJWT==1.4.2
+requests==2.11.0