Skip to content

Commit

Permalink
Merge pull request #6 from codecentric/new-ui-integration
Browse files Browse the repository at this point in the history
Kubernetes: New UI integration
  • Loading branch information
denniseffing authored May 20, 2022
2 parents 1f5ddf1 + e26cb77 commit 3719886
Show file tree
Hide file tree
Showing 10 changed files with 356 additions and 6 deletions.
6 changes: 3 additions & 3 deletions infrastructure/keycloak/realm.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@
"baseUrl": "/",
"secret": "password",
"redirectUris": [
"http://habitcentric.demo/ui/auth/callback",
"https://habitcentric.demo/ui/auth/callback",
"http://localhost:9004/auth/callback"
"http://habitcentric.demo/ui/overview",
"https://habitcentric.demo/ui/overview",
"http://localhost:9004/overview"
]
},
{
Expand Down
13 changes: 13 additions & 0 deletions services/ui/helm/ui/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v2
name: ui
version: 1.0.0
appVersion: v1
description: Chart for the ui service of habitcentric, a service to deliver the frontend web app
keywords:
- habitcentric
- ui
- microservices
home: https://github.com/codecentric/habitcentric/tree/main/services/ui/helm/ui
sources:
- https://github.com/codecentric/habitcentric
engine: gotpl
91 changes: 91 additions & 0 deletions services/ui/helm/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# habitcentric ui service

The [habitcentric](https://confluence.codecentric.de/display/HAB/habitcentric) ui service
delivers the habitcentric web app

## TL;DR;

```console
$ helm install .
```

## Introduction

This chart bootstraps a [habitcentric ui](https://github.com/codecentric/habitcentric/tree/main/services/ui) deployment
on a Kubernetes cluster using the Helm package manager.

## Prerequisites

- Kubernetes 1.10+

## Installing the Chart

To install the chart with the release name `habitcentric`:

```console
$ helm install --name habitcentric .
```

The command deploys habitcentric ui on the Kubernetes cluster in the default configuration.
The [configuration](#configuration) section lists the parameters that can be configured during
installation.

> **Tip**: List all releases using `helm list`
## Uninstalling the Chart

To uninstall/delete the `habitcentric` deployment:

```console
$ helm delete --purge habitcentric
```

The command removes all the Kubernetes components associated with the chart and deletes the release.

## Configuration

The following table lists the configurable parameters of the habitcentric ui chart and their
default values.

| Parameter | Description | Default |
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
| `appVersionOverride` | Overrides value of `app.kubernetes.io/version` label | `nil` |
| `global.imageRegistry` | Global Docker image registry | `nil` |
| `image.registry` | habitcentric ui image registry | `ghcr.io` |
| `image.repository` | habitcentric ui image name | `codecentric/habitcentric/ui` |
| `image.tag` | habitcentric ui image tag | `latest` |
| `image.pullPolicy` | habitcentric ui pull policy | `Always` |
| `service.type` | The service type | `ClusterIP` |
| `service.port` | The service port | `9004` |
| `service.nodePort` | The node port used if the service is of type `NodePort` | `nil` |
| `service.annotations` | Annotations for the habitcentric ui service | `{}` |
| `serviceAccount.enabled` | Enable service account (Note: Service Account will only be automatically created if `serviceAccount.name` is not set) | `false` |
| `serviceAcccount.name` | Name of existing service account | `nil` |
| `readinessProbe.enabled` | If `true`, Kubernetes readiness probe is enabled | `true` |
| `readinessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 20 |
| `readinessProbe.periodSeconds` | How often to perform the probe | 120 |
| `readinessProbe.timeoutSeconds` | When the probe times out | 5 |
| `readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 |
| `readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `livenessProbe.enabled` | If `true`, Kubernetes liveness probe is enabled | `true` |
| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | 40 |
| `livenessProbe.periodSeconds` | How often to perform the probe | 120 |
| `livenessProbe.timeoutSeconds` | When the probe times out | 5 |
| `livenessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 6 |
| `livenessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed | 1 |
| `oidc.enabled` | If `true`, UI uses OpenID connect to authenticate and authorize the user | `true` |
| `replicas` | Number of gateway instances | 1 |
| `podLabels` | Map of labels to add to the habitcentric ui pods | `{}` |
| `podAnnotations` | Map of annotations to add to the habitcentric ui pods | `{}` |
| `updateStrategyType` | Update strategy type | `RollingUpdate` |

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.

Alternatively, a YAML file that specifies the values for the parameters can be provided while
installing the chart. For example,

```console
$ helm install --name my-release -f values.yaml .
```

> **Tip**: You can use the default [values.yaml](helm/ui/values.yaml)
21 changes: 21 additions & 0 deletions services/ui/helm/ui/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

The ui service can be accessed:

* Within your cluster, at the following DNS name at port {{ .Values.service.port }}:

{{ template "ui.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local

* From outside the cluster, run these commands in the same shell:

{{- if contains "NodePort" .Values.service.type }}

export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "ui.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT

{{- else if contains "ClusterIP" .Values.service.type }}

export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l app={{ template "ui.name" . }},release={{ .Release.Name }} -o jsonpath="{.items[0].metadata.name}")
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 8080

{{- end }}
67 changes: 67 additions & 0 deletions services/ui/helm/ui/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "ui.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
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 "ui.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- printf .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "ui.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Return the proper habitcentric ui image name
*/}}
{{- define "ui.image" -}}
{{- $registryName := .Values.image.registry -}}
{{- $repositoryName := .Values.image.repository -}}
{{- $tag := .Values.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imageRegistry }}
{{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}

{{/*
Common labels
*/}}
{{- define "ui.labels" -}}
helm.sh/chart: {{ include "ui.chart" . }}
{{ include "ui.selectorLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{/*
Selector labels
*/}}
{{- define "ui.selectorLabels" -}}
app.kubernetes.io/name: ui
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
62 changes: 62 additions & 0 deletions services/ui/helm/ui/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "ui.fullname" . }}
labels:
{{- include "ui.labels" . | nindent 4 }}
app.kubernetes.io/version: {{ .Values.appVersionOverride | default .Chart.AppVersion | quote }}
spec:
replicas: {{ .Values.replicas }}
strategy:
type: {{ .Values.updateStrategyType }}
selector:
matchLabels:
{{- include "ui.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "ui.labels" . | nindent 8 }}
app.kubernetes.io/version: {{ .Values.appVersionOverride | default .Chart.AppVersion | quote }}
{{- with .Values.podLabels -}}
{{- toYaml . | nindent 8 }}
{{- end -}}
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- if .Values.serviceAccount.enabled }}
serviceAccountName: {{ default (include "ui.fullname" . ) .Values.serviceAccount.name }}
{{- end }}
containers:
- name: {{ template "ui.fullname" . }}
image: {{ template "ui.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http-ui
containerPort: 9004
env:
- name: PUBLIC_URL
value: {{ .Values.publicUrl | quote }}
{{- if .Values.oidc.enabled }}
- name: OIDC_ENABLED
value: "true"
{{- end }}
readinessProbe:
httpGet:
path: /ui
port: http-ui
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
livenessProbe:
httpGet:
path: /ui
port: {{ .Values.service.port }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
18 changes: 18 additions & 0 deletions services/ui/helm/ui/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "ui.fullname" . }}
labels:
{{- include "ui.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- name: http-ui
port: {{ .Values.service.port }}
targetPort: http-ui
selector:
{{- include "ui.selectorLabels" . | nindent 4 }}
8 changes: 8 additions & 0 deletions services/ui/helm/ui/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{- if and (.Values.serviceAccount.enabled) (not .Values.serviceAccount.name) }}
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
{{- include "ui.labels" . | nindent 4 }}
name: {{ template "ui.fullname" . }}
{{- end }}
71 changes: 71 additions & 0 deletions services/ui/helm/ui/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# appVersionOverride:

image:
registry: ghcr.io
repository: codecentric/habitcentric/ui
tag: latest
## Specifies an imagePullPolicy
## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
pullPolicy: Always

## habitcentric ui service configuration
service:
## Additional service annotations which may be required
annotations: {}

## ServiceType
## ref: https://kubernetes.io/docs/user-guide/services/#publishing-services---service-types
type: ClusterIP

## Internal service port
port: 9004

## nodePort value for the LoadBalancer and NodePort service types
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
# nodePort:

## Pod Service Account
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
serviceAccount:
enabled: false

## Name of an already existing service account. Setting this value disables the automatic service account creation.
# name:

## Configure extra options for liveness and readiness probes
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)
readinessProbe:
enabled: true
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1

livenessProbe:
enabled: true
initialDelaySeconds: 40
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1

## OpenID Connect configuration
oidc:
enabled: true

publicUrl: /ui

## Number of service instances
replicas: 1

## Additional pod labels which may be required
podLabels: {}

## Additional pod annotations which may be required
podAnnotations: {}

## updateStrategyType for habitcentric ui Deployment
## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategyType: RollingUpdate
5 changes: 2 additions & 3 deletions services/ui/src/auth/getUser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { User } from "oidc-client-ts";
import { oidc } from "./config/oidc";

export function getUser() {
const oidcStorage = sessionStorage.getItem(
"oidc.user:http://localhost:8080/auth/realms/habitcentric:ui"
);
const oidcStorage = sessionStorage.getItem(`oidc.user:${oidc.authority}:ui`);
if (!oidcStorage) {
return null;
}
Expand Down

0 comments on commit 3719886

Please sign in to comment.