diff --git a/stable/express-gateway/.helmignore b/stable/express-gateway/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/stable/express-gateway/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/stable/express-gateway/Chart.yaml b/stable/express-gateway/Chart.yaml new file mode 100644 index 0000000000..e214b34461 --- /dev/null +++ b/stable/express-gateway/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +description: Express Gateway is an API Gateway that sits at the heart of any microservices architecture +engine: gotpl +home: https://express-gateway.io +icon: https://cdn.rawgit.com/ExpressGateway/express-gateway/1757a863/logo/mark-only/ExpressGateway_logomark.png +maintainers: +- name: XVincentX + email: vincenz.chianese@icloud.com +name: express-gateway +sources: +- https://github.com/expressgateway/express-gateway +version: 0.1.0 +appVersion: 10.0.2 diff --git a/stable/express-gateway/README.md b/stable/express-gateway/README.md new file mode 100644 index 0000000000..364f91e24f --- /dev/null +++ b/stable/express-gateway/README.md @@ -0,0 +1,122 @@ +## Express Gateway + +[Express Gateway](https://express-gateway.io) is an API Gateway that sits at the heart of any microservices architecture. +## TL;DR; + +```bash +$ helm install stable/express-gateway +``` + +## Introduction + +This chart bootstraps all the components needed to run Express Gateway on a [Kubernetes](http://kubernetes.io) +cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.9+ +- PV provisioner support in the underlying infrastructure if persistence + is needed for Express Gateway datastore (backed by Redis) + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```bash +$ helm install --name my-release stable/express-gateway +``` + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```bash +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the +chart and deletes the release. + +## Configuration + +### General Deployment Configuration Parameters + +The following table lists the configurable parameters of the Express Gateway chart +and their default values. + +| Parameter | Description | Default | +|----------------------|--------------------------------------------------------------------------------------------------------|----------------------------------| +| image.repository | Express Gateway image | `expressgateway/express-gateway` | +| image.tag | Express Gateway image version | `1.10.2` | +| image.pullPolicy | Image pull policy | `IfNotPresent` | +| replicaCount | Express Gateway instance count | `1` | +| admin.servicePort | TCP port on which the Express Gateway admin service is exposed | `9876` | +| admin.containerPort | TCP port on which Express Gateway app listens for admin traffic | `9876` | +| admin.nodePort | Node port when service type is `NodePort`. Randomly chonsen by Kubernetes if not provided | | +| admin.type | k8s service type, Options: NodePort, ClusterIP, LoadBalancer | `NodePort` | +| admin.loadBalancerIP | Will reuse an existing ingress static IP for the admin service | `null` | +| proxy.https | Secure Proxy traffic | `true` | +| proxy.tls | When `proxy.https` is `true`, an [array of key][eg-tls-section] | `{}` | +| proxy.servicePort | TCP port on which the Express Gateway Proxy Service is exposed | `8080` | +| proxy.containerPort | TCP port on which the Express Gateway app listens for Proxy traffic | `8080` | +| proxy.nodePort | Node port when service type is `NodePort`. Randomly chonsen by Kubernetes if not provided | | +| proxy.type | k8s service type. Options: NodePort, ClusterIP, LoadBalancer | `NodePort` | +| proxy.loadBalancerIP | To reuse an existing ingress static IP for the admin service | | +| readinessProbe | Express Gateway readiness probe | | +| livenessProbe | Express Gateway liveness probe | | +| affinity | Node/pod affinities | | +| nodeSelector | Node labels for pod assignment | `{}` | +| podAnnotations | Annotations to add to each pod | `{}` | +| resources | Pod resource requests & limits | `{}` | +| tolerations | List of node taints to tolerate | `[]` | + + +### Express Gateway configuration parameters + +Express Gateway is configured through the [Admin API interface][admin-api]. Its complete configuraton is stored in a config map. +However there are some parameters that need to beset up before the container can start. + +```yml + +storage: + emulate: true + namespace: EG + +crypto: + cipherKey: sensitiveKey + algorithm: aes256 + saltRounds: 10 +session: + secret: keyboard cat + resave: false + saveUninitialized: false +accessTokens: + timeToExpiry: 7200000 +refreshTokens: + timeToExpiry: 7200000 +authorizationCodes: + timeToExpiry: 300000 + +``` + +For a complete list of Express Gateway cnfiguration parameters please check https://www.express-gateway.io/docs/configuration/system.config.yml + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install stable/express-gateway --name my-release \ + --set=image.tag=10.0.2,env.database=cassandra,cassandra.enabled=true +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install stable/express-gateway --name my-release -f values.yaml +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +[eg-tls-section]: https://www.express-gateway.io/docs/configuration/gateway.config.yml/https/#description +[admin-api]: https://www.express-gateway.io/docs/admin/ diff --git a/stable/express-gateway/requirements.lock b/stable/express-gateway/requirements.lock new file mode 100644 index 0000000000..67c48cca1f --- /dev/null +++ b/stable/express-gateway/requirements.lock @@ -0,0 +1,6 @@ +dependencies: +- name: redis + repository: https://kubernetes-charts.storage.googleapis.com/ + version: 3.0.6 +digest: sha256:3a654ee61a6951ecb71e4e0ea1f8c8a88ffeb3a967d2bf1f86c058d77afe7746 +generated: 2018-08-10T12:30:58.235835665+02:00 diff --git a/stable/express-gateway/requirements.yaml b/stable/express-gateway/requirements.yaml new file mode 100644 index 0000000000..6f66e5467e --- /dev/null +++ b/stable/express-gateway/requirements.yaml @@ -0,0 +1,5 @@ +dependencies: +- name: redis + version: ~3.0.0 + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: !redis.emulate diff --git a/stable/express-gateway/templates/NOTES.txt b/stable/express-gateway/templates/NOTES.txt new file mode 100644 index 0000000000..bd18cc2225 --- /dev/null +++ b/stable/express-gateway/templates/NOTES.txt @@ -0,0 +1,43 @@ +1. Express Gateway Admin can be accessed inside the cluster using: + DNS={{ template "eg.fullname" . }}-admin.{{ .Release.Namespace }}.svc.cluster.local + PORT={{ .Values.admin.servicePort }} + +To connect from outside the K8s cluster: + {{- if contains "LoadBalancer" .Values.admin.type }} + HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-admin -o jsonpath='{.status.loadBalancer.ingress.ip}') + PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-admin -o jsonpath='{.spec.ports[0].nodePort}') + + {{- else if contains "NodePort" .Values.admin.type }} + HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath='{.items[0].status.addresses[0].address}') + PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-admin -o jsonpath='{.spec.ports[0].nodePort}') + + {{- else if contains "ClusterIP" .Values.admin.type }} + HOST=127.0.0.1 + + # Execute the following commands to route the connection to Admin SSL port: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ .Release.Name }}, app={{ template "eg.name" . }}" -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME {{ .Values.admin.servicePort }}:{{ .Values.admin.servicePort }} + {{- end }} + + +2. Express Gateway Proxy can be accessed inside the cluster using: + DNS={{ template "eg.fullname" . }}-proxy.{{ .Release.Namespace }}.svc.cluster.local + PORT={{ .Values.proxy.servicePort }} + + +To connect from outside the K8s cluster: + {{- if contains "LoadBalancer" .Values.proxy.type }} + HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-proxy -o jsonpath='{.status.loadBalancer.ingress.ip}') + PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-proxy -o jsonpath='{.spec.ports[0].nodePort}') + + {{- else if contains "NodePort" .Values.proxy.type }} + HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath='{.items[0].status.addresses[0].address}') + PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "eg.fullname" . }}-proxy -o jsonpath='{.spec.ports[0].nodePort}') + + {{- else if contains "ClusterIP" .Values.proxy.type }} + HOST=127.0.0.1 + + # Execute the following commands to route the connection to proxy SSL port: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ .Release.Name }}, app={{ template "eg.name" . }}" -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME {{ .Values.proxy.servicePort }}:{{ .Values.proxy.servicePort }} + {{- end }} diff --git a/stable/express-gateway/templates/_helpers.tpl b/stable/express-gateway/templates/_helpers.tpl new file mode 100644 index 0000000000..d96cfa9582 --- /dev/null +++ b/stable/express-gateway/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} + +{{- define "eg.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "eg.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "eg.redis.fullname" -}} +{{- $name := default "redis" .Values.redis.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/stable/express-gateway/templates/configmap.yaml b/stable/express-gateway/templates/configmap.yaml new file mode 100644 index 0000000000..917e01ac49 --- /dev/null +++ b/stable/express-gateway/templates/configmap.yaml @@ -0,0 +1,59 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "eg.fullname" . }}" + labels: + app: "{{ template "eg.name" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +data: + system.config.yml: |- + db: + redis: + emulate: {{ .Values.storage.emulate }} + sentinels: + - host: {{ template "eg.redis.fullname" . }}-master + port: 6379 + - host: {{ template "eg.redis.fullname" . }}-slave + port: 6379 + name: {{ template "eg.redis.fullname" . }}-master + password: express-gateway + namespace: {{ .Values.storage.namespace }} + + cli: + url: http://localhost:{{ .Values.admin.containerPort }} + + crypto: +{{ toYaml .Values.crypto | indent 6 }} + session: +{{ toYaml .Values.session | indent 6 }} + accessTokens: +{{ toYaml .Values.accessTokens | indent 6 }} + refreshTokens: +{{ toYaml .Values.refreshTokens | indent 6 }} + authorizationCodes: +{{ toYaml .Values.authorizationCodes | indent 6 }} + + gateway.config.yml: |- + admin: + port: {{ .Values.admin.containerPort }} + hostname: {{ .Values.admin.hostname }} + {{- if .Values.proxy.https }} + https: + port: {{ .Values.proxy.containerPort }} + tls: +{{ toYaml .Values.proxy.tls | indent 8 }} + {{- else }} + http: + port: {{ .Values.proxy.containerPort }} + {{- end }} + apiEndpoints: + serviceEndpoints: + policies: + - proxy + - cors + - expression + - jwt + - terminate + pipelines: diff --git a/stable/express-gateway/templates/deployment.yaml b/stable/express-gateway/templates/deployment.yaml new file mode 100644 index 0000000000..b1d4effbc7 --- /dev/null +++ b/stable/express-gateway/templates/deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "eg.fullname" . }}" + labels: + app: "{{ template "eg.name" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "eg.name" . }} + release: {{ .Release.Name }} + template: + metadata: + {{- if .Values.podAnnotations }} + annotations: +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + labels: + app: {{ template "eg.name" . }} + release: {{ .Release.Name }} + spec: + volumes: + - configMap: + name: "{{ template "eg.fullname" . }}" + name: config + containers: + - name: {{ template "eg.name" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - mountPath: /var/lib/eg/system.config.yml + name: config + subPath: system.config.yml + - mountPath: /var/lib/eg/gateway.config.yml + name: config + subPath: gateway.config.yml + ports: + - name: admin + containerPort: {{ .Values.admin.containerPort }} + protocol: TCP + - name: proxy + containerPort: {{ .Values.proxy.containerPort }} + protocol: TCP + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 10 }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 10 }} + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} diff --git a/stable/express-gateway/templates/service-eg-admin.yaml b/stable/express-gateway/templates/service-eg-admin.yaml new file mode 100644 index 0000000000..0c7cf21b4d --- /dev/null +++ b/stable/express-gateway/templates/service-eg-admin.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "eg.fullname" . }}-admin + annotations: + {{- range $key, $value := .Values.admin.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + app: {{ template "eg.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + type: {{ .Values.admin.type }} + {{- if and (eq .Values.admin.type "LoadBalancer") .Values.admin.loadBalancerIP }} + loadBalancerIP: {{ .Values.admin.loadBalancerIP }} + {{- end }} + ports: + - name: eg-admin + port: {{ .Values.admin.servicePort }} + targetPort: {{ .Values.admin.containerPort }} + {{- if (and (eq .Values.admin.type "NodePort") (not (empty .Values.admin.nodePort))) }} + nodePort: {{ .Values.admin.nodePort }} + {{- end }} + protocol: TCP + selector: + app: {{ template "eg.name" . }} + release: {{ .Release.Name }} diff --git a/stable/express-gateway/templates/service-eg-proxy.yaml b/stable/express-gateway/templates/service-eg-proxy.yaml new file mode 100644 index 0000000000..93afcee899 --- /dev/null +++ b/stable/express-gateway/templates/service-eg-proxy.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "eg.fullname" . }}-proxy + annotations: + {{- range $key, $value := .Values.proxy.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + app: {{ template "eg.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + type: {{ .Values.proxy.type }} + {{- if and (eq .Values.proxy.type "LoadBalancer") .Values.proxy.loadBalancerIP }} + loadBalancerIP: {{ .Values.proxy.loadBalancerIP }} + {{- end }} + ports: + - name: eg-proxy + port: {{ .Values.proxy.servicePort }} + targetPort: {{ .Values.proxy.containerPort }} + {{- if (and (eq .Values.proxy.type "NodePort") (not (empty .Values.proxy.nodePort))) }} + nodePort: {{ .Values.proxy.nodePort }} + {{- end }} + protocol: TCP + selector: + app: {{ template "eg.name" . }} + release: {{ .Release.Name }} diff --git a/stable/express-gateway/values.yaml b/stable/express-gateway/values.yaml new file mode 100644 index 0000000000..03d2aa609e --- /dev/null +++ b/stable/express-gateway/values.yaml @@ -0,0 +1,89 @@ +# Default values for Express Gateway. +# Declare variables to be passed into your templates. + +image: + repository: expressgateway/express-gateway + tag: v1.10.2 + pullPolicy: IfNotPresent + +# Specify Express Gateway Admin API +admin: + # HTTPS traffic on the admin port + https: true + hostname: 0.0.0.0 + servicePort: 9876 + containerPort: 9876 + # Admin Service type + type: NodePort + +# Specify Express Gateway main listening service +proxy: + # HTTPS traffic on the proxy port + https: true + tls: {} + servicePort: 8080 + containerPort: 8080 + type: NodePort + +# readinessProbe for EG pods +readinessProbe: + httpGet: + path: "/users" + port: admin + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 2 + +# livenessProbe for EG pods +livenessProbe: + httpGet: + path: "/users" + port: admin + scheme: HTTP + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 2 + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Annotation to be added to pods +podAnnotations: {} + +# pod count +replicaCount: 1 + +# Express Gateway has a choice of either run with with transactional data in memory or use Redis as +# backend database. Redis is used by default. + +redis: + password: express-gateway + +storage: + emulate: true + namespace: EG + +crypto: + cipherKey: sensitiveKey + algorithm: aes256 + saltRounds: 10 +session: + secret: keyboard cat + resave: false + saveUninitialized: false +accessTokens: + timeToExpiry: 7200000 +refreshTokens: + timeToExpiry: 7200000 +authorizationCodes: + timeToExpiry: 300000