Commit 7ac9d6ff authored by Philippe Valfok's avatar Philippe Valfok

Adicionando pipenv para controle de dependencias, adicionando e configurando...

Adicionando pipenv para controle de dependencias, adicionando e configurando django-rq para tarefas em background, iniciando feature para criação dos domínios
parent 33902d64
*.ini
\ No newline at end of file
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /config
ADD /config/requirements/production.pip /config/
RUN pip install -r /config/production.pip
RUN mkdir /src;
WORKDIR /src
\ No newline at end of file
ENV PYTHONUNBUFFERED 1
# -- Install Pipenv:
RUN set -ex && pip install pipenv --upgrade
# -- Install Application into container:
RUN set -ex && mkdir /src
# -- Adding Compose Folder
ADD /compose/*.sh /
RUN chmod +x /*.sh
WORKDIR /src
# -- Adding Pipfiles
ADD Pipfile /
ADD Pipfile.lock /
# -- Install dependencies:
RUN set -ex && pipenv install --deploy --system
\ No newline at end of file
[[source]]
verify_ssl = true
name = "pypi"
url = "https://pypi.python.org/simple"
[dev-packages]
django-extensions = "*"
bpython = "*"
[packages]
django = "*"
dj-database-url = "*"
django-rq = "*"
django-solo = "*"
"psycopg2" = "*"
python-decouple = "*"
unipath = "*"
python-digitalocean = "*"
gunicorn = "*"
[requires]
python_version = "3.6"
This diff is collapsed.
#!/bin/sh
python manage.py migrate
python manage.py collectstatic --no-input
gunicorn backend.wsgi:application -b 0.0.0.0:8000 --workers 3 --log-level=debug
\ No newline at end of file
#!/bin/sh
python manage.py rqworker default
\ No newline at end of file
amqp==2.2.2
billiard==3.5.0.3
blessings==1.6.1
bpython==0.17
certifi==2018.1.18
chardet==3.0.4
click==6.7
curtsies==0.2.11
dj-database-url==0.4.2
Django==2.0.1
django-rq==1.0.1
django-solo==1.1.3
greenlet==0.4.12
idna==2.6
jsonpickle==0.9.5
psycopg2==2.7.3.2
Pygments==2.2.0
python-decouple==3.1
python-digitalocean==1.13.2
python-dotenv==0.7.1
pytz==2017.3
redis==2.10.6
requests==2.18.4
rq==0.10.0
six==1.11.0
Unipath==1.1
urllib3==1.22
vine==1.1.4
wcwidth==0.1.7
amqp==2.2.2
billiard==3.5.0.3
blessings==1.6.1
bpython==0.17
certifi==2018.1.18
chardet==3.0.4
click==6.7
curtsies==0.2.11
dj-database-url==0.4.2
Django==2.0.1
django-rq==1.0.1
django-solo==1.1.3
greenlet==0.4.12
idna==2.6
jsonpickle==0.9.5
psycopg2==2.7.3.2
Pygments==2.2.0
python-decouple==3.1
python-digitalocean==1.13.2
python-dotenv==0.7.1
pytz==2017.3
redis==2.10.6
requests==2.18.4
rq==0.10.0
six==1.11.0
Unipath==1.1
urllib3==1.22
vine==1.1.4
wcwidth==0.1.7
version: '2'
services:
version: '2'
services:
nginx:
image: nginx:latest
container_name: nginx_diario_manager
ports:
- "80:8000"
- "8000:8000"
volumes:
- ./src:/src
- ./config/nginx:/etc/nginx/conf.d
......@@ -13,22 +14,40 @@ services:
depends_on:
- web
restart: always
web:
build: .
container_name: django_diario_manager
command: bash -c "python manage.py migrate && python manage.py collectstatic --no-input && gunicorn backend.wsgi:application -b 0.0.0.0:8000 --workers 3 --log-level=debug"
command: /run_django.sh
volumes:
- ./src:/src
- static-data:/src/frontend/staticfiles
- media-data:/src/media
expose:
- "8000"
environment:
environment: &environment
DEBUG: "False"
DATABASE_URL: "postgres://postgres:infatecbdadmin@165.227.205.36/diario_manager"
SECRET_KEY: "=b+8s@l*rnqjd*=1rrsp!op82-qcgubm6oysex+thbu1+myen-"
restart: always
links:
- redis
rq:
build: .
command: /run_django_rq.sh
volumes:
- ./src:/src
environment: *environment
links:
- redis
depends_on:
- web
redis:
image: 'redis'
volumes:
static-data:
media-data:
\ No newline at end of file
media-data:
redis:
\ No newline at end of file
python-3.6.2
\ No newline at end of file
# Generated by Django 2.0.1 on 2018-01-24 08:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0007_auto_20180123_1123'),
]
operations = [
migrations.AddField(
model_name='cliente',
name='droplet_ip',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='IP do droplet'),
),
migrations.AddField(
model_name='cliente',
name='droplet_status',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='cliente',
name='droplet_id',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='ID do droplet'),
),
]
# Generated by Django 2.0.1 on 2018-01-24 10:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0008_auto_20180124_0839'),
]
operations = [
migrations.RenameField(
model_name='configuracao',
old_name='user_data',
new_name='droplets_user_data',
),
]
......@@ -2,7 +2,9 @@ from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from backend.core.tasks import create_droplet_pipeline
from backend.core.tasks import configuracao_cliente_pipeline
import django_rq
class Cliente(models.Model):
......@@ -16,7 +18,9 @@ class Cliente(models.Model):
password = models.CharField(max_length=50)
# Informações do droplet
droplet_id = models.CharField(_('id do droplet'), max_length=50, blank=True, null=True)
droplet_id = models.CharField(_('ID do droplet'), max_length=50, blank=True, null=True)
droplet_ip = models.CharField(_('IP do droplet'), max_length=50, blank=True, null=True)
droplet_status = models.CharField(max_length=255, blank=True, null=True)
class Meta:
"""Meta definition for Cliente."""
......@@ -32,8 +36,22 @@ class Cliente(models.Model):
)
def save(self, *args, **kwargs):
"""
Sobrescrevendo método save para, logo após
da criação do Model, executar a task de
criação do droplet.
"""
adding = self._state.adding
super().save(*args, **kwargs)
if adding:
create_droplet_pipeline(self)
self.set_status("Iniciando configuração do cliente.")
django_rq.enqueue(configuracao_cliente_pipeline, self)
def set_status(self, text):
"""
Método para alterar status rapidamente enquanto
estiver executando tarefas em background
"""
self.droplet_status = text
self.save()
......@@ -9,12 +9,15 @@ from .chave_ssh import ChaveSSH
class Configuracao(SingletonModel):
"""Model definition for COnfigurations"""
token = models.CharField(max_length=255)
chave_ssh = models.TextField(blank=True)
droplets_region = models.CharField(_('Região dos Droplets'), max_length=50, default="nyc1")
droplets_image = models.CharField(_('Imagem/SO dos Droplets'), max_length=50, default="ubuntu-16-04-x64")
droplets_size = models.CharField(_('Tamanho dos Droplets'), max_length=50, default="s-1vcpu-1gb")
droplets_backups = models.BooleanField(default=False)
droplets_ipv6 = models.BooleanField(default=False)
user_data = models.TextField(blank=True)
droplets_user_data = models.TextField(blank=True)
def __str__(self):
"""String representations for configuration"""
......
import digitalocean
import os
import psycopg2
from decouple import config
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from backend.core.models.configuracao import Configuracao
from urllib import parse
def criar_droplet(cliente):
"""
Função inicial para criação de droplets na digitalocean
:param cliente: Cliente que foi adicionado.
:type cliente: model.Cliente.
:returns: Retorna nada
:raises: Exception
"""
if cliente.droplet_id or cliente.droplet_ip:
raise Exception('Cleinte já possui um droplet.')
try:
cliente.set_status("Coletando informações para criação do droplet.")
configuracoes = Configuracao.get_solo()
droplet = digitalocean.Droplet(
token=configuracoes.token,
name="{}".format(cliente),
region=configuracoes.droplets_region,
image=configuracoes.droplets_image,
size_slug=configuracoes.droplets_size,
backups=configuracoes.droplets_backups,
ipv6=configuracoes.droplets_ipv6,
user_data=configuracoes.droplets_user_data,
ssh_keys=configuracoes.ssh_keys
)
cliente.set_status("Criando droplet.")
droplet.create()
except Exception as err:
msg = "Erro na criação do droplet. ({})".format(err)
cliente.set_status(msg)
raise Exception(msg)
actions = droplet.get_actions()
if actions:
for action in actions:
if action.type == 'create':
cliente.set_status("Aguardando disponibilização do droplet.")
action.wait()
continue
else:
error = "Erro. Nenhuma action encontrada."
cliente.set_status(error)
raise Exception(error)
def criar_banco(cliente):
"""
Função para criação do banco de dados do clinente
no mesmo servidor de bd em que esta aplicação está.
:param cliente: Cliente que foi adicionado.
:type cliente: model.Cliente.
:returns: Retorna nada
:raises: Exception
"""
cliente.set_status("Iniciando criação do banco de dados.")
try:
database_url = config('DATABASE_URL')
database_data = parse.urlparse(database_url)
con = psycopg2.connect(
dbname='postgres',
user=database_data.username,
host=database_data.hostname,
password=database_data.password
)
con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
cur = con.cursor()
cur.execute(f"CREATE DATABASE {cliente.domain_name} ;")
except Exception as err:
msg = "Erro ao criar banco de dados. ({})".format(err)
cliente.set_status(msg)
raise Exception(msg)
def configuracao_cliente_pipeline(cliente):
"""
Pipeline para configuração do servidor do cliente.
:param cliente: Cliente que foi adicionado.
:type cliente: model.Cliente.
:returns: Retorna nada
:raises: Exception
"""
try:
criar_droplet(cliente)
criar_banco(cliente)
except Exception as err:
cliente.set_status(err)
......@@ -37,6 +37,9 @@ INSTALLED_APPS = [
'backend.core',
]
if DEBUG:
INSTALLED_APPS.insert(0, 'django_extensions')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
......@@ -56,14 +59,28 @@ ROOT_URLCONF = 'backend.urls'
SITE_ID = 1
WSGI_APPLICATION = 'backend.wsgi.application'
# RQ_QUEUES = {
# 'default': {
# 'HOST': 'localhost',
# 'PORT': 6379,
# 'DB': 0
# }
# }
# RQ (Redis Queue)
# http://python-rq.org/
RQ_QUEUES = {
'default': {
'HOST': 'localhost',
'PORT': 6379,
'DB': 0
'URL': config('REDIS_URL', default='redis://redis/0'),
}
}
RQ = {
'host': 'redis',
'db': 0,
}
# Database
DATABASES = {
'default': config(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment