diff --git a/.gitignore b/.gitignore index c5c4371..411bdf2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store cmd/a3s/a3s cmd/a3sctl/a3sctl coverage.xml @@ -6,3 +7,4 @@ remod.dev .remod .data docker/in +helm/**.tgz diff --git a/Makefile b/Makefile index f5eaf90..7465962 100644 --- a/Makefile +++ b/Makefile @@ -73,3 +73,6 @@ package_ca_certs: mkdir -p docker/in extract-nss-root-certs > docker/in/ca-certificates.pem rm -f certdata.txt + +charts: + cd helm && make all \ No newline at end of file diff --git a/helm/Makefile b/helm/Makefile new file mode 100644 index 0000000..a3104f9 --- /dev/null +++ b/helm/Makefile @@ -0,0 +1,11 @@ +export DOCKER_TAG ?= v0.0.0-dev + +default: lint charts + +lint: + helm lint ./a3s --values ./test/values.yaml + +charts: lint + helm package a3s --version $(DOCKER_TAG) -d . + helm push --force ./a3s-$(DOCKER_TAG).tgz local; + helm repo update \ No newline at end of file diff --git a/helm/a3s/Chart.yaml b/helm/a3s/Chart.yaml new file mode 100644 index 0000000..e088698 --- /dev/null +++ b/helm/a3s/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: Authentication As A Service +name: a3s +version: 0.0.0-dev diff --git a/helm/a3s/templates/deployment.yaml b/helm/a3s/templates/deployment.yaml new file mode 100644 index 0000000..7df0d56 --- /dev/null +++ b/helm/a3s/templates/deployment.yaml @@ -0,0 +1,185 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.labels.name | default "a3s" }} +spec: + replicas: {{ .Values.replicas | default 1}} + strategy: + type: {{ .Values.updateStrategy | default "RollingUpdate" }} + selector: + matchLabels: + app: {{ .Values.labels.name | default "a3s" }} + type: {{ .Values.labels.type | default "core" }} + template: + metadata: + labels: + app: {{ .Values.labels.name | default "a3s" }} + type: {{ .Values.labels.type | default "core" }} + spec: + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds | default 60 }} + containers: + - name: a3s + image: {{ required "global.imageRegistry is required" .Values.global.imageRegistry }}/a3s:{{ required "global.imageTag is required" .Values.global.imageTag }} + imagePullPolicy: {{ .Values.imagePullPolicy | default "Always" }} + env: + # Init + - name: A3S_INIT + value: "{{ .Values.init.run | default "false" }}" + + - name: A3S_INIT_CONTINUE + value: "{{ .Values.init.continue | default "false" }}" + + - name: A3S_INIT_ROOT_CA + value: /certs/init-root-ca.pem + + # General + - name: A3S_LISTEN + value: ":{{ .Values.service.port | default 1443 }}" + + {{- if .Values.global.encoding }} + - name: A3S_ENCODING + value: {{ .Values.global.encoding | quote }} + {{- end }} + + # Log + {{- if .Values.log.format }} + - name: A3S_LOG_FORMAT + value: {{ .Values.log.format | quote }} + {{- end }} + {{- if .Values.log.level }} + - name: A3S_LOG_LEVEL + value: {{ .Values.log.level | quote }} + {{- end }} + + # Health + - name: A3S_HEALTH_LISTEN + value: ":{{ .Values.service.healthPort | default 1080 }}" + - name: A3S_HEALTH_ENABLED + value: "true" + + # Profiling + {{- if .Values.global.profiling.enabled }} + - name: A3S_PROFILING_ENABLED + value: "true" + - name: A3S_PROFILING_LISTEN + value: {{ required "global.profiling.listen is required" .Values.global.profiling.listen | quote }} + {{- end }} + + # TLS + - name: A3S_TLS_CERT + value: /certs/server-cert.pem + - name: A3S_TLS_KEY + value: /certs/server-key.pem + - name: A3S_TLS_KEY_PASS + value: file:///certs/server-key.pass + + # JWT + - name: A3S_JWT_CERT + value: /certs/jwt-cert.pem + - name: A3S_JWT_KEY + value: /certs/jwt-key.pem + - name: A3S_JWT_KEY_PASS + value: file:///certs/jwt-key.pass + - name: A3S_JWT_ISSUER + value: {{ required "global.issuer is required" .Values.global.issuer | quote }} + - name: A3S_JWT_AUDIENCE + value: {{ required "global.audience is required" .Values.global.audience | quote }} + + # Mongo + - name: A3S_MONGO_URL + value: {{ required "global.mongo.host is required" .Values.global.mongo.host }} + - name: A3S_MONGO_AUTH_DB + value: {{ required "global.mongo.db is required" .Values.global.mongo.db | quote }} + - name: A3S_MONGO_USER + value: {{ required "global.mongo.user is required" .Values.global.mongo.user | quote}} + - name: A3S_MONGO_ENCRYPTION_KEY + value: file:///certs/attribute-encryption-key.pass + - name: A3S_MONGO_TLS_DISABLE + value: {{ .Values.global.mongo.tls.disable | default "false" | quote }} + {{- if eq .Values.global.mongo.tls.disable false }} + - name: A3S_MONGO_CUSTOM_CA + value: /certs/mongo-ca.pem + - name: A3S_MONGO_TLS_CERT + value: /certs/mongo-full.pem + - name: A3S_MONGO_TLS_KEY + value: /certs/mongo-key.pem + - name: A3S_MONGO_TLS_KEY_PASS + value: file:///certs/mongo-key.pass + {{- end }} + + # Nats + - name: A3S_NATS_URL + value: {{ required "global.nats.host is required" .Values.global.nats.host }} + - name: A3S_NATS_USER + value: file:///certs/nats.user + - name: A3S_NATS_PASS + value: file:///certs/nats.pass + - name: A3S_NATS_TLS_DISABLE + value: {{ required "global.nats.tls.disable is required" .Values.global.nats.tls.disable | quote }} + {{- if eq .Values.global.mongo.tls.disable false }} + - name: A3S_NATS_TLS_CA + value: /certs/nats-ca.pem + - name: A3S_NATS_TLS_CERT + value: /certs/nats-cert.pem + - name: A3S_NATS_TLS_KEY + value: /certs/nats-key.pem + - name: A3S_NATS_TLS_KEY_PASS + value: file:///certs/nats-key.pass + {{- end }} + + volumeMounts: + - name: certs + mountPath: /certs + readOnly: true + volumes: + - name: certs + secret: + secretName: a3s-secrets + items: + # Init + - key: init-root-ca.pem + path: init-root-ca.pem + + # TLS + - key: server-cert.pem + path: server-cert.pem + - key: server-key.pem + path: server-key.pem + - key: server-key.pass + path: server-key.pass + + # JWT + - key: jwt-cert.pem + path: jwt-cert.pem + - key: jwt-key.pem + path: jwt-key.pem + - key: jwt-key.pass + path: jwt-key.pass + + # Mongo + - key: mongo-ca.pem + path: mongo-ca.pem + - key: mongo-full.pem + path: mongo-full.pem + - key: mongo-cert.pem + path: mongo-cert.pem + - key: mongo-key.pem + path: mongo-key.pem + - key: mongo-key.pass + path: mongo-key.pass + - key: attribute-encryption-key.pass + path: attribute-encryption-key.pass + + # Nats + - key: nats-ca.pem + path: nats-ca.pem + - key: nats-cert.pem + path: nats-cert.pem + - key: nats-key.pem + path: nats-key.pem + - key: nats-key.pass + path: nats-key.pass + - key: nats.user + path: nats.user + - key: nats.pass + path: nats.pass \ No newline at end of file diff --git a/helm/a3s/templates/secrets.yaml b/helm/a3s/templates/secrets.yaml new file mode 100644 index 0000000..93bf901 --- /dev/null +++ b/helm/a3s/templates/secrets.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: a3s-secrets +data: + # Init + init-root-ca.pem: {{ required "init.ca is required" .Values.init.ca | quote }} + + # TLS + server-cert.pem: {{ required "global.server.cert is required" .Values.global.server.cert | quote }} + server-key.pem: {{ required "global.server.key is required" .Values.global.server.key | quote }} + server-key.pass: {{ required "global.server.pass is required" .Values.global.server.pass | b64enc | quote }} + + # JWT + jwt-cert.pem: {{ required "global.jwt.cert is required" .Values.global.jwt.cert | quote }} + jwt-key.pem: {{ required "global.jwt.key is required" .Values.global.jwt.key | quote }} + jwt-key.pass: {{ required "global.jwt.pass is required" .Values.global.jwt.pass | b64enc | quote }} + + # Mongo + mongo-ca.pem: {{ .Values.global.mongo.tls.ca | quote }} + mongo-full.pem: {{ .Values.global.mongo.tls.full | quote }} + mongo-cert.pem: {{ .Values.global.mongo.tls.cert | quote }} + mongo-key.pem: {{ .Values.global.mongo.tls.key | quote }} + mongo-key.pass: {{ .Values.global.mongo.tls.pass | b64enc | quote }} + attribute-encryption-key.pass: {{ required "global.mongo.attributeEncryptionKey is required" .Values.global.mongo.attributeEncryptionKey | b64enc | quote }} + + # Nats + nats-ca.pem: {{ required "global.nats.tls.ca is required" .Values.global.nats.tls.ca | quote }} + nats-cert.pem: {{ required "global.nats.tls.cert is required" .Values.global.nats.tls.cert | quote }} + nats-key.pem: {{ required "global.nats.tls.key is required" .Values.global.nats.tls.key | quote }} + nats-key.pass: {{ required "global.nats.tls.pass is required" .Values.global.nats.tls.pass | b64enc | quote }} + nats.user: {{ required "global.nats.user is required" .Values.global.nats.user | b64enc | quote }} + nats.pass: {{ required "global.nats.pass is required" .Values.global.nats.pass | b64enc | quote }} + + + diff --git a/helm/a3s/templates/service.yaml b/helm/a3s/templates/service.yaml new file mode 100644 index 0000000..3fec83b --- /dev/null +++ b/helm/a3s/templates/service.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.labels.name | default "a3s" }} + labels: + app: {{ .Values.labels.name | default "a3s" }} + type: {{ .Values.labels.type | default "core" }} +spec: + type: {{ .Values.service.type | default "LoadBalancer" }} + selector: + app: {{ .Values.labels.name | default "a3s" }} + ports: + - targetPort: {{ .Values.service.targetPort | default "1443" }} + port: {{ .Values.service.port | default "443" }} + name: https +--- +apiVersion: v1 +kind: Service +metadata: + name: health-a3s + labels: + app: {{ .Values.labels.name | default "a3s" }} + type: {{ .Values.labels.name | default "core" }} +spec: + selector: + app: {{ .Values.labels.name | default "a3s" }} + clusterIP: {{ required "clusterIP is required" .Values.clusterIP }} + ports: + - port: {{ .Values.service.healthPort | default 1080 }} + name: health +--- diff --git a/helm/a3s/values.yaml b/helm/a3s/values.yaml new file mode 100644 index 0000000..a42e641 --- /dev/null +++ b/helm/a3s/values.yaml @@ -0,0 +1,69 @@ +replicas: 1 +clusterIP: None + +service: + type: + port: + targetPort: + healthPort: + +labels: + name: + type: + +log: + level: + format: + +init: + run: + continue: + ca: init-root-ca + +global: + encoding: + audience: + issuer: + imageRegistry: gcr.io/aporetodev + imageTag: latest + terminationGracePeriodSeconds: 60 + + server: + cert: + key: + pass: + + jwt: + cert: jwt-cert + key: jwt-key + pass: jwt-pass + + mongo: + tls: + disable: + ca: + cert: + key: + pass: + db: "$external" + user: "CN=mongodb-admin,OU=users,O=mongodb" + + host: mongodb-shard-router-0.mongodb-shard-router,mongodb-shard-router-1.mongodb-shard-router,mongodb-shard-router-2.mongodb-shard-router + sharded: true + readConsistency: nearest + attributeEncryptionKey: + + nats: + tls: + disable: + ca: + cert: + key: + pass: + user: + pass: + + profiling: + enabled: false + listen: ":6060" + \ No newline at end of file diff --git a/helm/test/values.yaml b/helm/test/values.yaml new file mode 100644 index 0000000..2554715 --- /dev/null +++ b/helm/test/values.yaml @@ -0,0 +1,69 @@ +replicas: 1 +clusterIP: None + +service: + type: + port: + targetPort: + healthPort: + + +labels: + name: + type: + +log: + level: + format: + +init: + run: + continue: + ca: init-root-ca + +global: + encoding: + audience: "a3s.com" + issuer: https://issuer.a3s.com + imageRegistry: gcr.io/aporetodev + imageTag: latest + + server: + cert: server-cert + key: server-key + pass: server-key-pass + + jwt: + cert: jwt-cert + key: jwt-key + pass: jwt-pass + + mongo: + tls: + disable: false + ca: mongo-ca + cert: mongo-cert + key: mongo-key + pass: mongo-key-pass + db: "$external" + user: "CN=mongodb-admin,OU=users,O=mongodb" + host: mongodb-shard-router-0.mongodb-shard-router,mongodb-shard-router-1.mongodb-shard-router,mongodb-shard-router-2.mongodb-shard-router + sharded: true + readConsistency: nearest + attributeEncryptionKey: "abcdefghijkl" + + nats: + tls: + disable: false + ca: nats-ca + cert: nats-cert + key: nats-key + pass: nats-key-pass + user: username + pass: password + host: "nats://nats:4222" + + profiling: + enabled: false + listen: ":6060" + \ No newline at end of file diff --git a/pkgs/bootstrap/clients.go b/pkgs/bootstrap/clients.go index 8dfb664..cf73da4 100644 --- a/pkgs/bootstrap/clients.go +++ b/pkgs/bootstrap/clients.go @@ -93,7 +93,7 @@ func MakeMongoManipulator(cfg conf.MongoConf, hasher sharder.Hasher, additionalO tlscfg, err := cfg.TLSConfig() if err != nil { - zap.L().Fatal("Unable to prepare TLS config for nats", zap.Error(err)) + zap.L().Fatal("Unable to prepare TLS config for mongo", zap.Error(err)) } if tlscfg != nil {