Initial Commit

This commit is contained in:
David Todd (c0de) 2018-04-16 19:57:29 -05:00
commit 56784cfe4f
16 changed files with 437 additions and 0 deletions

21
.editorconfig Normal file
View File

@ -0,0 +1,21 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
[*.py]
quote_type = single
[*.{css,html}]
quote_type = double
[*.js]
quote_type = single

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
venv/*
*.pyc
backup/*
*.db

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM python:2.7
WORKDIR /src
ADD . /src
RUN set -ex \
&& curl -L https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -o /usr/local/bin/wait-for-it.sh \
&& chmod +x /usr/local/bin/wait-for-it.sh \
&& pip install -r requirements.txt
CMD python manage.py runserver 0.0.0.0:8000

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 David Todd (c0de) <c0de@c0defox.es>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

124
README.docker.md Normal file
View File

@ -0,0 +1,124 @@
# local development
You'll need to have installed `docker-compose` and `docker`, and have a running
docker daemon.
# starting services with docker-compose
You should be inside the `django-cms` directory when running this command.
```sh
docker-compose u
```
You'll see labeled output from each service.
When you make changes on your local copy of django-cms, they will automatically propagate to the running container.
## accessing the database (cli)
There are cases where you may need access to the database (such as restoring a backup).
These commands will allow you access into the database over the command line.
1. Have docker running. Eg. `docker-compose up -f docker-compose.yaml`
2. Locate your container. `docker ps`, select the CONTAINER ID for postgres
3. Establish a shell in the container. `docker exec -t -i (CONTAINER ID) bash`
4. Connect to the database. `su postgres -c psql`
Now that you are connected to the database CLI, you can perform queries as the root postgres user.
For remote access to this database, you may create a role for yourself with the following query.
`create role your-name with superuser createdb login password 'your-password';`
To restore a database backup from the command line:
1. Find a way to copy the database into the container (or access it externally)
2. Become the postgres root user. `su postgres -c bash`
3. Stop the portal docker container (this can be accomplished with `docker stop (CONTAINER ID)`)
4. Verify that there are no other connections to the DB and enter psql
5. Rename or drop the imagehost_db database so it is out of the way
6. create the database and public schema
7. set permissions for the imagehost user
8. leave psql and run `pg_restore -F -c imagehost_db.custom` on newly created imagehost_db db
## accessing the database (GUI)
GUI access to the database can be established with PGAdmin (3 or 4) connected to localhost.
This assumes that you created a user for yourself in the previous section
(if you haven't, you can use the imagehost user at limited permissions)
1. Open PGAdmin and add a new server with an identifying name
2. Under the connection tab
* Hostname/address should be localhost
* Username should be what you added in the previous section
* Password should be what you added in the previous section
3. Save and connect, you should now be able to run queries with administrative privileges.
To restore a database backup inside PGAdmin:
1. Copy the imagehost_db.custom to your desktop (or somewhere easy) and
rename to imagehost_db.backup
2. Connect to the database server
3. Stop the portal docker container (this can be accomplished with `docker stop (CONTIANER ID)`)
4. Verify that there are no other connections to the db and either rename or drop the database
5. Create a new database with the owner set to imagehost
6. Right-click the newly created database and click restore
7. Navigate to your .backup file and select that
8. Let the restore run
Some errors are expected from the above, such as a non-existant usagereports role.
These can safely be ignored for development use (the role requires read-only access in prod)
## applying migrations
After you have made changes to the database or models, migrations need
to be made and then applied. To accomplish that in the docker env:
1. Have docker running. Eg. `docker-compose up -f docker-compose.yaml`
2. Locate your container. `docker ps`, select the CONTAINER ID for the portal
3. Establish a shell in the container. `docker exec -t -i (CONTIANER ID) bash`
4. CD to the portal directory (in docker-compose.yaml, this is defined as /portal)
5. Make your migrations. `python manage.py makemigrations`
6. Apply the migrations. `python manage.py migrate`
7. Optionally exit the shell. It is no longer needed.
You may get errors on your last step if you are restoring from a database
backup. Before making the migrations, first run `python manage.py --fake-initial`
If your database has migrations applied, it should be able to continue from
whichever the last applied migration was.
# staging/testing
You'll need to have `docker-machine` installed. You can create a fully
provisioned VM on ESXi using this command:
```sh
docker-machine create \
--driver vmwarevsphere \
--vmwarevsphere-username root \
--vmwarevsphere-password password \
--vmwarevsphere-vcenter 500.500.500.500 \
my-docker
```
You should replace `my-docker` with whatever you want to uniquely reference this
VM by.
Note: If you get an error similar to "ServerFaultCode: Current license or ESXi version prohibits execution of the requested operation."
you must first put the vmserver in "Evaluation Mode" as the Free tier license does not support remote management of VMs.
This can be accomplished by logging into the esxi interface, navigating to configuration and changing the license config.
## remote environment
First, you'll set up your local docker client to connect to the remote docker host:
```sh
eval $(docker-machine env my-docker)
```
You can see the containers running on the remote host using regular docker
commands like `docker ps`.
## create a production environment
```sh
docker-compose -f docker-compose.yaml -f docker-compose.production.yaml up
```

13
README.md Normal file
View File

@ -0,0 +1,13 @@
# Django-CMS
This is a minimalistic microservice to run a Content Management System (CMS).
Normally, a CMS is used to run blogging platforms, and will be the end result for what will happen here.
Does not provide the proxy to connect to the services.
Automatic unit testing is done by CircleCI
Refer to the docker README for docker info
License: MIT
Copyright 2018 David Todd (c0de) c0de@c0defox.es
Check the LICENSE file for further details

0
cms/cms/__init__.py Normal file
View File

120
cms/cms/settings.py Normal file
View File

@ -0,0 +1,120 @@
"""
Django settings for cms project.
Generated by 'django-admin startproject' using Django 1.11.4.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ')ry_&w-pg5o1%h$6@aqf369-0)=)k@x#9z*0oe2c5!!nya#pu('
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'cms.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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 = 'cms.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/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.11/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.11/howto/static-files/
STATIC_URL = '/static/'

21
cms/cms/urls.py Normal file
View File

@ -0,0 +1,21 @@
"""cms URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]

16
cms/cms/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for cms project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.settings")
application = get_wsgi_application()

22
cms/manage.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cms.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)

34
docker-compose.yaml Normal file
View File

@ -0,0 +1,34 @@
version: '3'
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: totallyHacked1337
POSTGRES_USER: django_cms
POSTGRES_DB: cms_db
volumes:
- ./backup:/backup
ports:
- '5432:5432'
imagehost_portal:
build: .
environment:
PORTAL_DEBUG: 'true'
POSTGRES_PASSWORD: totallyHacked1337
POSTGRES_USER: django_cms
POSTGRES_DB: cms_db
POSTGRES_HOST: postgres
volumes:
- .:/portal
ports:
- '8000:8000'
depends_on:
- postgres
working_dir: /portal
command: |
/usr/local/bin/wait-for-it.sh -t 60 postgres:5432 --
sh /portal/run.sh

2
newdb.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
su postgres -c "psql < newdb.sql"

2
newdb.sql Normal file
View File

@ -0,0 +1,2 @@
CREATE USER django_cms WITH LOGIN PASSWORD 'totallyHacked1337';
CREATE DATABASE cms_db OWNER django_cms;

20
requirements.txt Normal file
View File

@ -0,0 +1,20 @@
asn1crypto==0.22.0
cffi==1.10.0
cryptography==2.0.3
Django==1.11.4
django-debug-panel==0.8.3
django-debug-toolbar==1.8
django-inline-actions==1.1.0
djangorestframework==3.6.3
enum34==1.1.6
idna==2.6
ipaddress==1.0.18
psycopg2==2.7.3
pycparser==2.18
pycrypto==2.6.1
pyOpenSSL==17.2.0
pytz==2017.2
six==1.10.0
sqlparse==0.2.3
uWSGI==2.0.15
zipstream==1.1.4

6
run.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
cd /portal
sleep 1 # Hopefully enough for the database to start accepting connections
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000