Skip to content

Commit

Permalink
Merge pull request #4 from sandwichcloud/security
Browse files Browse the repository at this point in the history
update deps, add security-data endpoint, fix docker image
  • Loading branch information
rmb938 committed Dec 5, 2017
2 parents 252e165 + 7f3f960 commit efb3f29
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 21 deletions.
15 changes: 14 additions & 1 deletion .env-sample
@@ -1,4 +1,17 @@
# Copy this to .env

####################
# DATABASE #
####################

DATABASE_HOST=127.0.0.1
DATABASE_USERNAME=sandwich
DATABASE_PASSWORD=hunter2
DATABASE_PASSWORD=hunter2

####################
# Auth #
####################

# This NEED to match what is given to deli-counter
# See deli-counter for explanation of usage
AUTH_FERNET_KEYS=
13 changes: 7 additions & 6 deletions Dockerfile
Expand Up @@ -9,13 +9,9 @@ WORKDIR /usr/src/app

# Install build time dependencies for uwsgi
# Install uwsgi and dumb-init
# Remove build time dependencies
# Install runtime dependencies
RUN apk --no-cache add --virtual build-deps \
build-base linux-headers pcre-dev postgresql-dev && \
pip install uwsgi dumb-init psycopg2 && \
apk del build-deps && \
apk --no-cache add bash openssl pcre libpq ca-certificates
build-base bash linux-headers pcre-dev postgresql-dev libffi-dev && \
pip install uwsgi dumb-init

# COPY tar.gz from build container
# Install it
Expand All @@ -25,6 +21,11 @@ COPY --from=0 /usr/src/app/dist/. .
RUN bash -c "pip install *"
COPY wsgi.ini wsgi.ini

# Remove build time dependencies
# Install runtime dependencies
RUN apk del build-deps && \
apk --no-cache add openssl pcre libpq libffi ca-certificates

# add entrypoint
COPY docker-entrypoint.sh /bin/docker-entrypoint.sh

Expand Down
19 changes: 6 additions & 13 deletions deli_menu/http/mounts/root/routes/metadata.py
Expand Up @@ -19,29 +19,22 @@ def get(self):
region = session.query(Region).filter(Region.id == instance.region_id).first()
zone = session.query(Zone).filter(Zone.id == instance.zone_id).first()

public_keys = []
for public_key in instance.public_keys:
public_keys.append(public_key.key)
keypairs = []
for keypair in instance.keypairs:
keypairs.append(keypair.public_key)

# Strip out user-data
tags = instance.tags if instance.tags is not None else {}
del tags['user-data']

# TODO: include some sort of instance identity document similar to aws PKCS7
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html

# TODO: include some sort of service account (IAM) for the instance.
# This will allow the instance to call the api. We probably need better acls first.

# Those probably should be moved to a /security-creds route ^
if 'user-data' in tags:
del tags['user-data']

metadata = {
'ami-id': instance.image_id,
'instance-id': instance.id,
'region': region.name,
'availability-zone': zone.name,
'tags': tags,
'public-keys': public_keys
'public-keys': keypairs
}

return metadata
43 changes: 43 additions & 0 deletions deli_menu/http/mounts/root/routes/securitydata.py
@@ -0,0 +1,43 @@
import json

import arrow
import cherrypy
from cryptography.fernet import Fernet
from simple_settings import settings

from ingredients_db.models.authn import AuthNServiceAccount
from ingredients_db.models.instance import Instance
from ingredients_http.route import Route
from ingredients_http.router import Router


class SecurityDataRouter(Router):
def __init__(self):
super().__init__(uri_base='security-data')

@Route()
@cherrypy.tools.json_out()
def get(self):
with cherrypy.request.db_session() as session:
instance = session.query(Instance).filter(Instance.id == cherrypy.request.instance_id).first()
service_account: AuthNServiceAccount = session.query(AuthNServiceAccount).filter(
AuthNServiceAccount.id == instance.service_account_id).first()

fernet = Fernet(settings.AUTH_FERNET_KEYS[0])

token_data = {
# Token only lasts 30 minutes. This should be more than enough
'expires_at': arrow.now().shift(minute=+30),
'service_account_id': service_account.id,
'project_id': instance.project_id,
'roles': {
'global': [],
'project': [service_account.role_id]
}
}

# TODO: these will be generated every time an instance asks for it
# Should be cached these somewhere?
return {
"token": fernet.encrypt(json.dumps(token_data).encode()).decode()
}
6 changes: 6 additions & 0 deletions deli_menu/settings.py
Expand Up @@ -67,6 +67,12 @@
DATABASE_USERNAME = os.environ['DATABASE_USERNAME']
DATABASE_PASSWORD = os.environ['DATABASE_PASSWORD']

####################
# Auth #
####################

AUTH_FERNET_KEYS = os.environ['AUTH_FERNET_KEYS'].split(",")

####################
# HTTP #
####################
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
@@ -1,5 +1,6 @@
pbr==3.1.1 # Apache 2.0
python-dotenv==0.7.1 # BSD 3-clause
pyyaml==3.12 # MIT
cryptography==2.1.4 # Apache 2.0 or BSD
ingredients.http==0.0.12 # MIT
ingredients.db==0.0.9 # MIT
ingredients.db==0.0.11 # MIT
2 changes: 2 additions & 0 deletions wsgi.ini
Expand Up @@ -6,6 +6,8 @@ disable-logging = True
processes = 4
master = True
env = settings=deli_menu.settings
; This is to prevent connection reuse. No idea how to make cherry-py support that
add-header = Connection: Close

; If VIRTAL_ENV is set then use its value to specify the virtualenv directory
if-env = VIRTUAL_ENV
Expand Down

0 comments on commit efb3f29

Please sign in to comment.