Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add redis cert capability #374

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ ENV/
# Translation catalogs
*.mo
*.pot

# Mac Files
.DS_Store
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.PHONY: dev prod run test
.PHONY: base dev prod run test

base: requirements.txt
pip install -r requirements.txt

dev: dev-requirements.txt
pip install -r dev-requirements.txt

prod: requirements.txt
pip install -r requirements.txt
prod: prod-requirements.txt
pip install -r prod-requirements.txt

run: prod
FLASK_DEBUG=1 FLASK_APP=snappass.main NO_SSL=True venv/bin/flask run
Expand Down
35 changes: 30 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ need to change this.

``REDIS_PORT``: is the port redis is serving on, defaults to 6379

``REDIS_CA_CERTS``: useful when connecting to a Redis server that uses SSL. Example: ``"/path/to/ca.pem"``

``SNAPPASS_REDIS_DB``: is the database that you want to use on this redis server. Defaults to db 0

``REDIS_URL``: (optional) will be used instead of ``REDIS_HOST``, ``REDIS_PORT``, and ``SNAPPASS_REDIS_DB`` to configure the Redis client object. For example: redis://username:password@localhost:6379/0
Expand Down Expand Up @@ -197,10 +199,10 @@ To check if a password exists, send a HEAD request to ``/api/v2/passwords/<token
$ curl --head http://localhost:5000/api/v2/passwords/snappassbedf19b161794fd288faec3eba15fa41~hHnILpQ50ZfJc3nurDfHCb_22rBr5gGEya68e_cZOrY%3D

If :
- the passwork_key is valid
- the passwork_key is valid
- the password :
- exists,
- has not been read
- has not been read
- is not expired

Then the API will return a 200 (OK) response like so:
Expand All @@ -224,7 +226,7 @@ Otherwise, the API will return a 404 (Not Found) response like so:
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: close


Read a password
"""""""""""""""
Expand All @@ -236,10 +238,10 @@ To read a password, send a GET request to ``/api/v2/passwords/<password_key>``,
$ curl -X GET http://localhost:5000/api/v2/passwords/snappassbedf19b161794fd288faec3eba15fa41~hHnILpQ50ZfJc3nurDfHCb_22rBr5gGEya68e_cZOrY%3D

If :
- the token is valid
- the token is valid
- the password :
- exists
- has not been read
- has not been read
- is not expired

Then the API will return a 200 (OK) with a JSON response containing the password :
Expand Down Expand Up @@ -286,6 +288,29 @@ Alternatively, you can use `Docker`_ and `Docker Compose`_ to install and run Sn

This will pull all dependencies, i.e. Redis and appropriate Python version (3.7), then start up SnapPass and Redis server. SnapPass server is accessible at: http://localhost:5000

Kubernetes
------

Alternatively, you can run SnapPass in a Kubernetes cluster. A sample deployment file is provided in the `kubernetes` directory.

.. _Kubernetes: https://kubernetes.io/

Do the required changes in the `kubernetes/kustomize/overlays/dev` or `kubernetes/kustomize/overlays/prod` directory and then apply the changes using `kubectl`:

::

$ kubectl kustomize kubernetes/kustomize/overlays/dev | kubectl apply -f -

OR

::

$ kubectl apply -f kubernetes/kustomize/overlays/prod | kubectl apply -f -


This will pull all dependencies, i.e. Redis and appropriate Python version (3.7), then start up SnapPass and Redis server. SnapPass server is accessible at: http://localhost:5000


Similar Tools
-------------

Expand Down
13 changes: 13 additions & 0 deletions kubernetes/kustomize/base/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: snappass
namespace: snappass
data:
REDIS_HOST: KUSTOMIZE_HERE
REDIS_PORT: KUSTOMIZE_HERE
NO_SSL: "False"
SNAPPASS_REDIS_DB: "0"
REDIS_PREFIX: snappass
HOST_OVERRIDE: KUSTOMIZE_HERE
95 changes: 95 additions & 0 deletions kubernetes/kustomize/base/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: snappass
namespace: snappass
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app.k8s.com/name: snappass
app.k8s.com/instance: snappass
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
spec:
containers:
- name: snappass
image: pinterest/snappass
imagePullPolicy: IfNotPresent
env:
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: snappass
key: REDIS_HOST
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: snappass
key: REDIS_PORT
- name: NO_SSL
valueFrom:
configMapKeyRef:
name: snappass
key: NO_SSL
- name: SNAPPASS_REDIS_DB
valueFrom:
configMapKeyRef:
name: snappass
key: SNAPPASS_REDIS_DB
- name: REDIS_PREFIX
valueFrom:
configMapKeyRef:
name: snappass
key: REDIS_PREFIX
- name: HOST_OVERRIDE
valueFrom:
configMapKeyRef:
name: snappass
key: HOST_OVERRIDE
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: snappass
key: SECRET_KEY
- name: REDIS_CA_CERTS
value: /etc/ssl/redis/redis.pem
ports:
- name: http
containerPort: 5000
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 60
readinessProbe:
httpGet:
path: /
port: http
resources:
requests:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: redis-ca-certs
mountPath: "/etc/ssl/redis"
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumes:
- name: redis-ca-certs
secret:
secretName: redis-ca-certs
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
serviceAccountName: snappass-ksa
22 changes: 22 additions & 0 deletions kubernetes/kustomize/base/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: snappass-ingress
namespace: snappass
spec:
ingressClassName: nginx-ingress
rules:
- host: KUSTOMIZE_HERE
http:
paths:
- backend:
service:
name: snappass-http
port:
name: snappass-http
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- KUSTOMIZE_HERE
11 changes: 11 additions & 0 deletions kubernetes/kustomize/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- namespace.yaml
- secret.yaml
- configmap.yaml
- serviceaccount.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
5 changes: 5 additions & 0 deletions kubernetes/kustomize/base/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: snappass
7 changes: 7 additions & 0 deletions kubernetes/kustomize/base/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
apiVersion: v1
data:
redis.pem: KUSTOMIZE_HERE
kind: Secret
metadata:
name: redis-ca-certs
17 changes: 17 additions & 0 deletions kubernetes/kustomize/base/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: snappass-http
namespace: snappass
spec:
ports:
- name: snappass-http
port: 5000
protocol: TCP
targetPort: 5000
selector:
app.k8s.com/name: snappass
app.k8s.com/instance: snappass
sessionAffinity: None
type: ClusterIP
6 changes: 6 additions & 0 deletions kubernetes/kustomize/base/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: snappass-ksa
namespace: snappass
8 changes: 8 additions & 0 deletions kubernetes/kustomize/overlays/dev/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
- ../../base

# Add patches for configMap, Secret and Ingress
patches: []
22 changes: 22 additions & 0 deletions kubernetes/kustomize/overlays/prod/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
- ../../base

patches:
- patch: |-
- op: add
path: /spec/template/spec/containers/0/command
value: ["gunicorn"]
- op: add
path: /spec/template/spec/containers/0/args
value:
- snappass.main:app
- --bind=0.0.0.0:5000
- --workers=4
target:
kind: Deployment
name: snappass

# Add patches for configMap, Secret and Ingress
9 changes: 9 additions & 0 deletions prod-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cryptography==42.0.3
Flask==3.0.0
itsdangerous==2.1.2
Jinja2==3.1.3
MarkupSafe==2.1.1
redis==5.0.1
Werkzeug==3.0.3
flask-babel
gunicorn==22.0.0
20 changes: 18 additions & 2 deletions snappass/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
URL_PREFIX = os.environ.get('URL_PREFIX', None)
HOST_OVERRIDE = os.environ.get('HOST_OVERRIDE', None)
TOKEN_SEPARATOR = '~'
REDIS_CA_CERTS = os.environ.get('REDIS_CA_CERTS', None) # Path to the CA PEM file

# Initialize Flask Application
app = Flask(__name__)
Expand Down Expand Up @@ -45,8 +46,23 @@ def get_locale():
redis_host = os.environ.get('REDIS_HOST', 'localhost')
redis_port = os.environ.get('REDIS_PORT', 6379)
redis_db = os.environ.get('SNAPPASS_REDIS_DB', 0)
redis_client = redis.StrictRedis(
host=redis_host, port=redis_port, db=redis_db)

# Use SSL/TLS if CA certs are provided
if REDIS_CA_CERTS:
redis_client = redis.StrictRedis(
host=redis_host,
port=redis_port,
db=redis_db,
ssl=True,
ssl_ca_certs=REDIS_CA_CERTS
)
else:
redis_client = redis.StrictRedis(
host=redis_host,
port=redis_port,
db=redis_db
)

REDIS_PREFIX = os.environ.get('REDIS_PREFIX', 'snappass')

TIME_CONVERSION = {'two weeks': 1209600, 'week': 604800, 'day': 86400,
Expand Down