refactor(suites): replace kind with k3d (#4553)
This change replaces Kind with a might lighter K8s variation K3D. Many of our manifests have also been consolidated. Other key changes have been highlighted below: * Utilise K3D Traefik Ingress * Automatically provision all manifests, removing the abundance of shell scripts * Expose Traefik and K8s dashboards through the Ingresspull/4556/head
parent
180620e519
commit
505a7e90b3
|
@ -3,7 +3,7 @@
|
|||
set +u
|
||||
|
||||
declare -A BUILDS=(["linux"]="amd64 arm arm64 amd64-musl arm-musl arm64-musl" ["freebsd"]="amd64")
|
||||
DOCKER_IMAGE=authelia/authelia
|
||||
DOCKER_IMAGE=authelia:dist
|
||||
|
||||
if [[ "${BUILDKITE_LABEL}" == ":hammer_and_wrench: Unit Test" ]]; then
|
||||
if [[ ! "${BUILDKITE_BRANCH}" =~ ^renovate/ ]]; then
|
||||
|
|
|
@ -30,10 +30,13 @@ fi
|
|||
|
||||
if [[ "${BUILDKITE_LABEL}" =~ ":selenium:" ]]; then
|
||||
DEFAULT_ARCH=coverage
|
||||
echo "--- :docker: Extract, load and tag build container"
|
||||
echo "--- :docker: Extract and load build container"
|
||||
buildkite-agent artifact download "authelia-image-${DEFAULT_ARCH}*" .
|
||||
zstdcat "authelia-image-${DEFAULT_ARCH}.tar.zst" | docker load
|
||||
docker tag authelia/authelia authelia:dist
|
||||
if [[ "${SUITE}" == "Kubernetes" ]]; then
|
||||
zstd -d authelia-image-coverage.tar.zst --stdout > ./internal/suites/example/kube/authelia-image-${DEFAULT_ARCH}.tar
|
||||
else
|
||||
zstdcat "authelia-image-${DEFAULT_ARCH}.tar.zst" | docker load
|
||||
fi
|
||||
|
||||
if [[ "${BUILD_DUO}" == "true" ]] && [[ "${SUITE}" == "DuoPush" ]]; then
|
||||
CONTAINER="integration-duo"
|
||||
|
|
|
@ -7,7 +7,11 @@ trim_trailing_whitespace = true
|
|||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[{.buildkite/hooks/**,*.sh,*.yml,*.yaml}]
|
||||
[*.{sh,yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[.buildkite/hooks/**]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
|
|
|
@ -1,50 +1,27 @@
|
|||
# IDE user configuration
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# NodeJs modules
|
||||
# Nodejs modules
|
||||
.pnpm-store/
|
||||
node_modules/
|
||||
|
||||
# npm debug logs
|
||||
npm-debug.log*
|
||||
|
||||
# Coverage reports
|
||||
coverage/
|
||||
.nyc_output/
|
||||
coverage.txt
|
||||
|
||||
.vscode/
|
||||
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# Directory used by example
|
||||
/notifications/
|
||||
|
||||
# VSCode user configuration
|
||||
.vscode/
|
||||
|
||||
# Generated by TypeScript compiler
|
||||
dist/
|
||||
|
||||
.nyc_output/
|
||||
|
||||
*.tgz
|
||||
|
||||
# Specific files
|
||||
/configuration.yml
|
||||
/config.yml
|
||||
/config.test.yml
|
||||
|
||||
internal/suites/example/ldap/private.ldif
|
||||
|
||||
Configuration.schema.json
|
||||
|
||||
.suite
|
||||
.kube
|
||||
.idea
|
||||
authelia-image-dev.tar
|
||||
|
||||
.authelia-interrupt
|
||||
|
||||
qemu-*-static
|
||||
|
||||
public_html.gen.go
|
||||
|
||||
authelia
|
||||
/authelia
|
||||
__debug_bin
|
||||
|
|
15
.renovaterc
15
.renovaterc
|
@ -14,12 +14,17 @@
|
|||
"workarounds:all"
|
||||
],
|
||||
"enabledManagers": [
|
||||
"bundler",
|
||||
"docker-compose",
|
||||
"dockerfile",
|
||||
"gomod",
|
||||
"kubernetes",
|
||||
"npm"
|
||||
],
|
||||
{
|
||||
"kubernetes": {
|
||||
"fileMatch": ["kube/.+\\.yml$"]
|
||||
}
|
||||
}
|
||||
"labels": [
|
||||
"dependencies"
|
||||
],
|
||||
|
@ -47,6 +52,14 @@
|
|||
"go"
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasources": [
|
||||
"kubernetes"
|
||||
],
|
||||
"addLabels": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasources": [
|
||||
"npm"
|
||||
|
|
|
@ -87,12 +87,19 @@ var hostEntries = []HostEntry{
|
|||
{Domain: "mail.example.com", IP: "192.168.240.100"},
|
||||
{Domain: "duo.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For Traefik suite.
|
||||
{Domain: "traefik.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For HAProxy suite.
|
||||
{Domain: "haproxy.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// Kubernetes dashboard.
|
||||
{Domain: "kubernetes.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// OIDC tester app.
|
||||
{Domain: "oidc.example.com", IP: "192.168.240.100"},
|
||||
{Domain: "oidc-public.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For Traefik suite.
|
||||
{Domain: "traefik.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For testing network ACLs.
|
||||
{Domain: "proxy-client1.example.com", IP: "192.168.240.201"},
|
||||
{Domain: "proxy-client2.example.com", IP: "192.168.240.202"},
|
||||
|
@ -107,12 +114,6 @@ var hostEntries = []HostEntry{
|
|||
{Domain: "redis-sentinel-0.example.com", IP: "192.168.240.120"},
|
||||
{Domain: "redis-sentinel-1.example.com", IP: "192.168.240.121"},
|
||||
{Domain: "redis-sentinel-2.example.com", IP: "192.168.240.122"},
|
||||
|
||||
// Kubernetes dashboard.
|
||||
{Domain: "kubernetes.example.com", IP: "192.168.240.110"},
|
||||
// OIDC tester app.
|
||||
{Domain: "oidc.example.com", IP: "192.168.240.100"},
|
||||
{Domain: "oidc-public.example.com", IP: "192.168.240.100"},
|
||||
}
|
||||
|
||||
func runCommand(cmd string, args ...string) {
|
||||
|
|
|
@ -58,6 +58,12 @@ const (
|
|||
testPassword = "password"
|
||||
)
|
||||
|
||||
const (
|
||||
namespaceAuthelia = "authelia"
|
||||
namespaceDashboard = "kubernetes-dashboard"
|
||||
namespaceKube = "kube-system"
|
||||
)
|
||||
|
||||
var (
|
||||
storageLocalTmpConfig = schema.Configuration{
|
||||
TOTP: schema.TOTPConfiguration{
|
||||
|
|
|
@ -58,6 +58,15 @@ func waitUntilAutheliaFrontendIsReady(dockerEnvironment *DockerEnvironment) erro
|
|||
[]string{"dev server running at", "ready in"})
|
||||
}
|
||||
|
||||
func waitUntilK3DIsReady(dockerEnvironment *DockerEnvironment) error {
|
||||
return waitUntilServiceLogDetected(
|
||||
5*time.Second,
|
||||
90*time.Second,
|
||||
dockerEnvironment,
|
||||
"k3d",
|
||||
[]string{"API listen on [::]:2376"})
|
||||
}
|
||||
|
||||
func waitUntilSambaIsReady(dockerEnvironment *DockerEnvironment) error {
|
||||
return waitUntilServiceLogDetected(
|
||||
5*time.Second,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
version: '3'
|
||||
services:
|
||||
k3d:
|
||||
image: ghcr.io/k3d-io/k3d:5.4.6-dind
|
||||
volumes:
|
||||
- './example/kube:/authelia'
|
||||
- './example/kube/authelia/configs/configuration.yml:/configmaps/authelia/configuration.yml'
|
||||
- './common/ssl:/configmaps/authelia/ssl'
|
||||
- './example/compose/ldap/ldif:/configmaps/ldap'
|
||||
- './example/compose/nginx/backend:/configmaps/nginx-backend'
|
||||
privileged: true
|
||||
networks:
|
||||
authelianet:
|
||||
aliases:
|
||||
- public.example.com
|
||||
- secure.example.com
|
||||
- login.example.com
|
||||
- admin.example.com
|
||||
- dev.example.com
|
||||
- mail.example.com
|
||||
- kubernetes.example.com
|
||||
- traefik.example.com
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.100
|
||||
...
|
|
@ -1,17 +0,0 @@
|
|||
FROM alpine:3.17.0
|
||||
|
||||
WORKDIR /kind
|
||||
|
||||
RUN apk add --no-cache bash curl docker && \
|
||||
curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.10.0/kind-linux-amd64 && chmod +x kind && \
|
||||
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.20.2/bin/linux/amd64/kubectl && chmod +x kubectl
|
||||
|
||||
ADD entrypoint.sh entrypoint.sh
|
||||
ADD patch-kubeconfig.sh patch-kubeconfig.sh
|
||||
|
||||
ENV HOME=/kind/config
|
||||
ENV KUBECONFIG=/kind/config/.kube/kind-config-kind
|
||||
|
||||
VOLUME /kind/config
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
containerdConfigPatches:
|
||||
# yamllint disable-line rule:indentation
|
||||
- |-
|
||||
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
|
||||
endpoint = ["http://registrycache.internal:5000"]
|
||||
...
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
version: '3'
|
||||
services:
|
||||
authelia-kind-proxy:
|
||||
build:
|
||||
context: ./example/compose/kind
|
||||
volumes:
|
||||
- 'kind-volume:/kind/config'
|
||||
- '/var/run/docker.sock:/var/run/docker.sock'
|
||||
- './example/kube:/authelia'
|
||||
- './example/compose/kind/config.yml:/etc/kind/config.yml'
|
||||
command: 'kubectl port-forward --address 0.0.0.0 -n authelia service/nginx-ingress-controller-service 8080:443'
|
||||
environment:
|
||||
- KIND_EXPERIMENTAL_DOCKER_NETWORK=authelia_authelianet
|
||||
networks:
|
||||
authelianet:
|
||||
aliases:
|
||||
- public.example.com
|
||||
- secure.example.com
|
||||
- login.example.com
|
||||
- admin.example.com
|
||||
- dev.example.com
|
||||
- mail.example.com
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.100
|
||||
|
||||
kube-dashboard:
|
||||
build:
|
||||
context: ./example/compose/kind
|
||||
volumes:
|
||||
- 'kind-volume:/kind/config'
|
||||
- './example/compose/kind/entrypoint-dashboard.sh:/entrypoint-dashboard.sh'
|
||||
command: '/entrypoint-dashboard.sh'
|
||||
environment:
|
||||
- KIND_EXPERIMENTAL_DOCKER_NETWORK=authelia_authelianet
|
||||
networks:
|
||||
authelianet:
|
||||
aliases:
|
||||
- kubernetes.example.com
|
||||
ipv4_address: 192.168.240.110
|
||||
|
||||
volumes:
|
||||
kind-volume: # yamllint disable-line rule:empty-values
|
||||
...
|
|
@ -1,25 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Retries a command on failure.
|
||||
# $1 - the max number of attempts
|
||||
# $2... - the command to run
|
||||
|
||||
retry() {
|
||||
local -r -i max_attempts="$1"; shift
|
||||
local -r cmd="$@"
|
||||
local -i attempt_num=1
|
||||
until $cmd
|
||||
do
|
||||
if ((attempt_num==max_attempts))
|
||||
then
|
||||
echo "Attempt $attempt_num failed and there are no more attempts left!"
|
||||
return 1
|
||||
else
|
||||
echo "Attempt $attempt_num failed! Trying again in 10 seconds..."
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
|
||||
retry 10 kubectl port-forward --address 0.0.0.0 -n kubernetes-dashboard service/kubernetes-dashboard 443:443
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
export PATH=/kind:$PATH
|
||||
|
||||
exec "$@"
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script patches the kubeconfig generated by Kind in order to access the cluster container via this container
|
||||
|
||||
echo "Patching Kubeconfig to target Kube container without link"
|
||||
sed -i "s/127.0.0.1:.*/$(docker inspect -f '{{(index .NetworkSettings.Networks "authelia_authelianet").IPAddress}}' kind-control-plane):6443/" ${KUBECONFIG}
|
|
@ -1,62 +0,0 @@
|
|||
# Authelia on Kubernetes
|
||||
|
||||
Authelia is now available on Kube in order to protect your most critical
|
||||
applications using 2-factor authentication and Single Sign-On.
|
||||
|
||||
This example leverages [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
to delegate authentication and authorization to Authelia within the cluster.
|
||||
|
||||
## Getting started
|
||||
|
||||
You can either try to install **Authelia** on your running instance of Kubernetes
|
||||
or deploy the dedicated [suite](/docs/suites.md) called *kubernetes*.
|
||||
|
||||
### Set up a Kube cluster
|
||||
|
||||
The simplest way to start a Kubernetes cluster is to deploy the *kubernetes* suite with
|
||||
|
||||
authelia-scripts suites setup kubernetes
|
||||
|
||||
This will take a few seconds (or minutes) to deploy the cluster.
|
||||
|
||||
## How does it work?
|
||||
|
||||
### Authentication via Authelia
|
||||
|
||||
In a Kube clusters, the routing logic of requests is handled by ingress
|
||||
controllers following rules provided by ingress configurations.
|
||||
|
||||
In this example, [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
controller has been installed to handle the incoming requests. Some of them
|
||||
(specified in the ingress configuration) are forwarded to Authelia so that
|
||||
it can verify whether they are allowed and should reach the protected endpoint.
|
||||
|
||||
The authentication is provided at the ingress level by an annotation called
|
||||
`nginx.ingress.kubernetes.io/auth-url` that is filled with the URL of
|
||||
Authelia's verification endpoint.
|
||||
The ingress controller also requires the URL to the
|
||||
authentication portal so that the user can be redirected if he is not
|
||||
yet authenticated. This annotation is as follows:
|
||||
`nginx.ingress.kubernetes.io/auth-signin: "https://login.example.com:8080/"`
|
||||
|
||||
Those annotations can be seen in `apps/apps.yml` configuration.
|
||||
|
||||
### Production grade infrastructure
|
||||
|
||||
What is great with using [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
is that it is compatible with [kube-lego](https://github.com/jetstack/kube-lego)
|
||||
which removes the usual pain of manually renewing SSL certificates. It uses
|
||||
letsencrypt to issue and renew certificates every three month without any
|
||||
manual intervention.
|
||||
|
||||
## What do I need to know to deploy it in my cluster?
|
||||
|
||||
Given your cluster already runs a LDAP server, a Redis, a SQL database,
|
||||
a SMTP server and a nginx ingress-controller, you can deploy **Authelia**
|
||||
and update your ingress configurations. An example is provided
|
||||
[here](authelia).
|
||||
|
||||
## Questions
|
||||
|
||||
If you have questions about the implementation, please post them on
|
||||
[![Gitter](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/authelia/general?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
|
|
@ -1,154 +0,0 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: test-app
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: test-app
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: test-app
|
||||
spec:
|
||||
containers:
|
||||
- name: test-app
|
||||
image: nginx:alpine
|
||||
command: ["/entrypoint.sh"]
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /entrypoint.sh
|
||||
subPath: entrypoint.sh
|
||||
- name: config-volume
|
||||
mountPath: /etc/nginx/nginx.conf
|
||||
subPath: nginx.conf
|
||||
- name: config-volume
|
||||
mountPath: /tmp/html.tar.gz
|
||||
subPath: html.tar.gz
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: nginx-config
|
||||
items:
|
||||
- key: entrypoint.sh
|
||||
path: entrypoint.sh
|
||||
mode: 0755 # yamllint disable-line rule:octal-values
|
||||
- key: nginx.conf
|
||||
path: nginx.conf
|
||||
- key: html.tar.gz
|
||||
path: html.tar.gz
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: test-app-service
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: test-app
|
||||
spec:
|
||||
selector:
|
||||
app: test-app
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
- port: 443
|
||||
name: https
|
||||
...
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: insecure-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
kubernetes.io/ingress.allow-http: "false"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: test-app-tls
|
||||
hosts:
|
||||
- home.example.com
|
||||
rules:
|
||||
- host: home.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
...
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: secure-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
kubernetes.io/ingress.allow-http: "false"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/auth-url: "https://authelia-service.authelia.svc.cluster.local/api/verify"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://login.example.com:8080/"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: test-app-tls
|
||||
hosts:
|
||||
- public.example.com
|
||||
- admin.example.com
|
||||
- dev.example.com
|
||||
- mx1.mail.example.com
|
||||
- mx2.mail.example.com
|
||||
- singlefactor.example.com
|
||||
rules:
|
||||
- host: public.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
- host: admin.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
- host: dev.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
- host: mx1.mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
- host: mx2.mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
- host: singlefactor.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-service
|
||||
servicePort: 80
|
||||
...
|
|
@ -1,5 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
rm -rf /usr/share/nginx/html && \
|
||||
tar xfz /tmp/html.tar.gz -C /usr/share/nginx/ && \
|
||||
nginx "-g daemon off;"
|
Binary file not shown.
|
@ -1,51 +0,0 @@
|
|||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/home;
|
||||
server_name home.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/public;
|
||||
server_name public.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/secure;
|
||||
server_name secure.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/admin;
|
||||
server_name admin.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/dev;
|
||||
server_name dev.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/mail;
|
||||
server_name mx1.mail.example.com mx2.mail.example.com;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html/singlefactor;
|
||||
server_name singlefactor.example.com;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-backend
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-backend
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-backend
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: nginx-config
|
||||
mountPath: /etc/nginx/nginx.conf
|
||||
- name: nginx-html
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: nginx-config
|
||||
hostPath:
|
||||
path: /configmaps/nginx-backend/nginx.conf
|
||||
type: File
|
||||
- name: nginx-html
|
||||
hostPath:
|
||||
path: /configmaps/nginx-backend/html
|
||||
type: Directory
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-backend-service
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-backend
|
||||
spec:
|
||||
selector:
|
||||
app: nginx-backend
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
- port: 443
|
||||
name: https
|
||||
...
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: nginx-backend-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.middlewares: authelia-forwardauth-authelia@kubernetescrd
|
||||
spec:
|
||||
rules:
|
||||
- host: home.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: public.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: admin.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: dev.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: mx1.mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: mx2.mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
- host: singlefactor.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: nginx-backend-service
|
||||
port:
|
||||
number: 80
|
||||
...
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDEzCCAfugAwIBAgIUJZXxXExVQPJhc8TnlD+uAAYHlvwwDQYJKoZIhvcNAQEL
|
||||
BQAwGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTAgFw0xOTA5MjYyMDAwMTBaGA8y
|
||||
MTE5MDkwMjIwMDAxMFowGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3DFTAdrxG6iOj5UjSeB5lMjMQQyeYm
|
||||
OxUvswwwBzmQYPUt0inAJ9QmXJ8i9Fbye8HHYUeqE5zsEfeHir81MiWfhi9oUzJt
|
||||
u3bmxGLDXYaApejd18hBKITX6MYogmK2lWrl/F9zPYxc2xM/fqWnGg2xwdrMmida
|
||||
hZjDUfh0rtoz8zqOzJaiiDoFMwNO+NTGmDbeOwBFYOF1OTkS3aJWwJCLZmINUG8h
|
||||
Z3YPR+SL8CpGGl0xhJYAwXD1AtMlYwAteTILqrqvo2XkGsvuj0mx0w/D0DDpC48g
|
||||
oSNsRIVTW3Ql3uu+kXDFtkf4I63Ctt85rZk1kX3QtYmS0pRzvmyY/b0CAwEAAaNT
|
||||
MFEwHQYDVR0OBBYEFMTozK79Kp813+8TstjXRFw1MTE5MB8GA1UdIwQYMBaAFMTo
|
||||
zK79Kp813+8TstjXRFw1MTE5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||
BQADggEBALf1bJf3qF3m54+q98E6lSE+34yi/rVdzB9reAW1QzvvqdJRtsfjt39R
|
||||
SznsbmrvCfK4SLyOj9Uhd8Z6bASPPNsUux1XAGN4AqaGmlYI8b7j3LhKCdRBZQ0I
|
||||
zWgPhocyWwp5VkFe68zR06NHme/2B6eBRFsdd/69DIOv9YnEGUHk3A/9v1zvolt9
|
||||
krW57Oz63zWGYXmtPPTD8of/Ya6NKqwonVx1MUQ5QzqH3WySYhRsIYqwUEXm9jt5
|
||||
GEM3Nx0phEltaOLXa71nqS/Rhg/5Kod0cFaNoSKb6N93I8bqKKTK0m5wMJ5Fisrm
|
||||
Pw5+AIar7RT5gHU2DD2/OTb9bXXww8I=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAvcMVMB2vEbqI6PlSNJ4HmUyMxBDJ5iY7FS+zDDAHOZBg9S3S
|
||||
KcAn1CZcnyL0VvJ7wcdhR6oTnOwR94eKvzUyJZ+GL2hTMm27dubEYsNdhoCl6N3X
|
||||
yEEohNfoxiiCYraVauX8X3M9jFzbEz9+pacaDbHB2syaJ1qFmMNR+HSu2jPzOo7M
|
||||
lqKIOgUzA0741MaYNt47AEVg4XU5ORLdolbAkItmYg1QbyFndg9H5IvwKkYaXTGE
|
||||
lgDBcPUC0yVjAC15Mguquq+jZeQay+6PSbHTD8PQMOkLjyChI2xEhVNbdCXe676R
|
||||
cMW2R/gjrcK23zmtmTWRfdC1iZLSlHO+bJj9vQIDAQABAoIBAEZvkP/JJOCJwqPn
|
||||
V3IcbmmilmV4bdi1vByDFgyiDyx4wOSA24+PubjvfFW9XcCgRPuKjDtTj/AhWBHv
|
||||
B7stfa2lZuNV7/u562mZArA+IAr62Zp0LdIxDV8x3T8gbjVB3HhPYbv0RJZDKTYd
|
||||
zV6jhfIrVu9mHpoY6ZnodhapCPYIyk/d49KBIHZuAc25CUjMXgTeaVtf0c996036
|
||||
UxW6ef33wAOJAvW0RCvbXAJfmBeEq2qQlkjTIlpYx71fhZWexHifi8Ouv3Zonc+1
|
||||
/P2Adq5uzYVBT92f9RKHg9QxxNzVrLjSMaxyvUtWQCAQfW0tFIRdqBGsHYsQrFtI
|
||||
F4yzv8ECgYEA7ntpyN9HD9Z9lYQzPCR73sFCLM+ID99aVij0wHuxK97bkSyyvkLd
|
||||
7MyTaym3lg1UEqWNWBCLvFULZx7F0Ah6qCzD4ymm3Bj/ADpWWPgljBI0AFml+HHs
|
||||
hcATmXUrj5QbLyhiP2gmJjajp1o/rgATx6ED66seSynD6JOH8wUhhZUCgYEAy7OA
|
||||
06PF8GfseNsTqlDjNF0K7lOqd21S0prdwrsJLiVzUlfMM25MLE0XLDUutCnRheeh
|
||||
IlcuDoBsVTxz6rkvFGD74N+pgXlN4CicsBq5ofK060PbqCQhSII3fmHobrZ9Cr75
|
||||
HmBjAxHx998SKaAAGbBbcYGUAp521i1pH5CEPYkCgYEAkUd1Zf0+2RMdZhwm6hh/
|
||||
rW+l1I6IoMK70YkZsLipccRNld7Y9LbfYwYtODcts6di9AkOVfueZJiaXbONZfIE
|
||||
Zrb+jkAteh9wGL9xIrnohbABJcV3Kiaco84jInUSmGDtPokncOENfHIEuEpuSJ2b
|
||||
bx1TuhmAVuGWivR0+ULC7RECgYEAgS0cDRpWc9Xzh9Cl7+PLsXEvdWNpPsL9OsEq
|
||||
0Ep7z9+/+f/jZtoTRCS/BTHUpDvAuwHglT5j3p5iFMt5VuiIiovWLwynGYwrbnNS
|
||||
qfrIrYKUaH1n1oDS+oBZYLQGCe9/7EifAjxtjYzbvSyg//SPG7tSwfBCREbpZXj2
|
||||
qSWkNsECgYA/mCDzCTlrrWPuiepo6kTmN+4TnFA+hJI6NccDVQ+jvbqEdoJ4SW4L
|
||||
zqfZSZRFJMNpSgIqkQNRPJqMP0jQ5KRtJrjMWBnYxktwKz9fDg2R2MxdFgMF2LH2
|
||||
HEMMhFHlv8NDjVOXh1KwRoltNGVWYsSrD9wKU9GhRCEfmNCGrvBcEg==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,153 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: authelia
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
containers:
|
||||
- name: authelia
|
||||
image: authelia:dist
|
||||
ports:
|
||||
- containerPort: 443
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
scheme: HTTPS
|
||||
path: /api/health
|
||||
port: 443
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 3
|
||||
volumeMounts:
|
||||
- name: authelia-config
|
||||
mountPath: /config/configuration.yml
|
||||
readOnly: true
|
||||
- name: authelia-ssl
|
||||
mountPath: /config/ssl
|
||||
readOnly: true
|
||||
- name: secrets
|
||||
mountPath: /config/secrets
|
||||
readOnly: true
|
||||
env:
|
||||
# We set secrets directly here for ease of deployment but all secrets
|
||||
# should be stored in the Kube Vault in production.
|
||||
- name: AUTHELIA_JWT_SECRET_FILE
|
||||
value: /config/secrets/jwt_secret
|
||||
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
|
||||
value: /config/secrets/ldap_password
|
||||
- name: AUTHELIA_SESSION_SECRET_FILE
|
||||
value: /config/secrets/session
|
||||
- name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE
|
||||
value: /config/secrets/sql_password
|
||||
- name: AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE
|
||||
value: /config/secrets/encryption_key
|
||||
- name: ENVIRONMENT
|
||||
value: dev
|
||||
volumes:
|
||||
- name: authelia-config
|
||||
hostPath:
|
||||
path: /configmaps/authelia/configuration.yml
|
||||
type: File
|
||||
- name: authelia-ssl
|
||||
hostPath:
|
||||
path: /configmaps/authelia/ssl
|
||||
type: Directory
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: authelia
|
||||
items:
|
||||
- key: jwt_secret
|
||||
path: jwt_secret
|
||||
- key: session
|
||||
path: session
|
||||
- key: sql_password
|
||||
path: sql_password
|
||||
- key: ldap_password
|
||||
path: ldap_password
|
||||
- key: encryption_key
|
||||
path: encryption_key
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: authelia-service
|
||||
namespace: authelia
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/service.serverstransport: authelia-skipverify@kubernetescrd
|
||||
spec:
|
||||
selector:
|
||||
app: authelia
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
targetPort: 443
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: authelia
|
||||
data:
|
||||
jwt_secret: YW5fdW5zZWN1cmVfc2VjcmV0 # an_unsecure_secret
|
||||
ldap_password: cGFzc3dvcmQ= # password
|
||||
session: dW5zZWN1cmVfcGFzc3dvcmQ= # unsecure_password
|
||||
sql_password: cGFzc3dvcmQ= # password
|
||||
encryption_key: YV9ub3Rfc29fc2VjdXJlX2VuY3J5cHRpb25fa2V5
|
||||
...
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: authelia-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
spec:
|
||||
rules:
|
||||
- host: login.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: authelia-service
|
||||
port:
|
||||
number: 443
|
||||
...
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: forwardauth-authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app.kubernetes.io/instance: authelia
|
||||
app.kubernetes.io/name: authelia
|
||||
spec:
|
||||
forwardAuth:
|
||||
address: https://authelia-service.authelia.svc.cluster.local/api/verify?rd=https://login.example.com:8080
|
||||
authResponseHeaders:
|
||||
- Remote-User
|
||||
- Remote-Name
|
||||
- Remote-Email
|
||||
- Remote-Groups
|
||||
tls:
|
||||
insecureSkipVerify: true
|
||||
...
|
|
@ -35,6 +35,8 @@ access_control:
|
|||
|
||||
rules:
|
||||
# Rules applied to everyone
|
||||
- domain: home.example.com
|
||||
policy: bypass
|
||||
- domain: public.example.com
|
||||
policy: bypass
|
||||
- domain: secure.example.com
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: authelia
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
containers:
|
||||
- name: authelia
|
||||
image: authelia:dist
|
||||
ports:
|
||||
- containerPort: 443
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /config
|
||||
- name: ssl-volume
|
||||
mountPath: /config/ssl
|
||||
- name: secrets
|
||||
mountPath: /app/secrets
|
||||
readOnly: true
|
||||
env:
|
||||
# We set secrets directly here for ease of deployment but all secrets
|
||||
# should be stored in the Kube Vault in production.
|
||||
- name: AUTHELIA_JWT_SECRET_FILE
|
||||
value: /app/secrets/jwt_secret
|
||||
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
|
||||
value: /app/secrets/ldap_password
|
||||
- name: AUTHELIA_SESSION_SECRET_FILE
|
||||
value: /app/secrets/session
|
||||
- name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE
|
||||
value: /app/secrets/sql_password
|
||||
- name: AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE
|
||||
value: /app/secrets/encryption_key
|
||||
- name: ENVIRONMENT
|
||||
value: dev
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: authelia-config
|
||||
items:
|
||||
- key: configuration.yml
|
||||
path: configuration.yml
|
||||
- name: ssl-volume
|
||||
configMap:
|
||||
name: authelia-ssl
|
||||
items:
|
||||
- key: cert.pem
|
||||
path: cert.pem
|
||||
- key: key.pem
|
||||
path: key.pem
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: authelia
|
||||
items:
|
||||
- key: jwt_secret
|
||||
path: jwt_secret
|
||||
- key: session
|
||||
path: session
|
||||
- key: sql_password
|
||||
path: sql_password
|
||||
- key: ldap_password
|
||||
path: ldap_password
|
||||
- key: encryption_key
|
||||
path: encryption_key
|
||||
...
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: authelia-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: authelia-tls
|
||||
hosts:
|
||||
- login.example.com
|
||||
rules:
|
||||
- host: login.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: authelia-service
|
||||
servicePort: 443
|
||||
...
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: authelia
|
||||
data:
|
||||
jwt_secret: YW5fdW5zZWN1cmVfc2VjcmV0 # an_unsecure_secret
|
||||
ldap_password: cGFzc3dvcmQ= # password
|
||||
session: dW5zZWN1cmVfcGFzc3dvcmQ= # unsecure_password
|
||||
sql_password: cGFzc3dvcmQ= # password
|
||||
encryption_key: YV9ub3Rfc29fc2VjdXJlX2VuY3J5cHRpb25fa2V5
|
||||
...
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: authelia-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: authelia
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
targetPort: 443
|
||||
...
|
|
@ -1,19 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC/jCCAeagAwIBAgIRAKF0IRxC55eee6icERVf6fgwDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAgFw0yMDAzMDExMjMzMzlaGA8yMTIwMDIwNjEy
|
||||
MzMzOVowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMi7/oSazFIxP3rHsSLjw5XPnpMKEaVwU1zLRzW6W80BDa/ER5to
|
||||
I3POGLv8lAhtUwB6WvyilrCZfs/D5lkcCxswafU/2LNppFuODnW+PG9eobgOy6Nv
|
||||
f+KbnZFPRV7PB2yK6DqMyb+tbTQ7F6rEf4i6n28DI0dNyNvUCk0ld3o93LZBvC/D
|
||||
/+Ulf3Vtdfsd2TckXvdA8lH4VGQJ+FIxhboTlbW8VJlk1V7FZef7+m867kOnPSaj
|
||||
zv5yygrIA0XPaMAZC/SZrXHMdhvcs43fgmmTel7JD4Sy/Z/pmFlrZr5Xa8jcWycJ
|
||||
ILLuPnXhgKstgq5wtDkTMZ6rpgMrKcjMKcMCAwEAAaNNMEswDgYDVR0PAQH/BAQD
|
||||
AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8w
|
||||
DYILZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBABdWkbipzPivAvvamMmQ
|
||||
5iPPeStfdr5MBxJGT9nPbeXdtS/13FJnspLBMMYOw/2AZk7VFrNjxkXc4NHZSlGz
|
||||
FcGMlSO40fyirdYaQTDtS230ucLB+LzfZx37y9dKpEKVmQ151kKJjJ4hAZ47LmAQ
|
||||
aFoDLRo7PA2HmnJ60GrI9wVp96uy1sQ6PcToIyMcVEQ/tLEEow+ykSeiZb9+qBKV
|
||||
K9GUcu2LorhBtUMmEWs0TJElaf6eKUoG6JXM2byulDg24w5b9gC26kAlHWc5WDU5
|
||||
pAXOjlN/OYHB0sDbYViWIL390376fYIfu2N5EDKY4QjEYsWEs4Wm9HVS9IgHP/Gi
|
||||
Xbo=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,28 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIu/6EmsxSMT96
|
||||
x7Ei48OVz56TChGlcFNcy0c1ulvNAQ2vxEebaCNzzhi7/JQIbVMAelr8opawmX7P
|
||||
w+ZZHAsbMGn1P9izaaRbjg51vjxvXqG4Dsujb3/im52RT0Vezwdsiug6jMm/rW00
|
||||
OxeqxH+Iup9vAyNHTcjb1ApNJXd6Pdy2Qbwvw//lJX91bXX7Hdk3JF73QPJR+FRk
|
||||
CfhSMYW6E5W1vFSZZNVexWXn+/pvOu5Dpz0mo87+csoKyANFz2jAGQv0ma1xzHYb
|
||||
3LON34Jpk3peyQ+Esv2f6ZhZa2a+V2vI3FsnCSCy7j514YCrLYKucLQ5EzGeq6YD
|
||||
KynIzCnDAgMBAAECggEAC13R0LJvRWwyewJZvm8FQTNreEoGq8aLgeKk2p792cLo
|
||||
gn5ry5n+/+y4q9RmkX+XRpynEE0omUFn09306jDTVCvOpCuEWsxtmR2XJgWqqGfE
|
||||
Yoa78zo6FJvZNUQ22mKAuh23frFAL1FjsKRz96B+1EA1DPUxhzUZXZFJMAsiE9LZ
|
||||
PxqPmnqXbPZsOb1XG33TAdCp6CC3H8KHICC+i4IC8prjKHGH/Q1saoNw8jmgwv0S
|
||||
DelQUbEtqfmE6BmyTGxdeu4uW2Nv/wcENwySAOPKi5gstlbSKTa4IpKGp7CdquWi
|
||||
stUW6pnSiEeDrDAzwC8uWdncOvnkAy2lRJkz/F9YoQKBgQDrCCqYdvGshecBBnfQ
|
||||
fowxak2YBfG2jhAKPMHzrvQn5FIb+11x/jeXPEfOB6FShIzZ97JpFIpH3tcONlj3
|
||||
OVzGCTD6WdRTcltzXVneJtNog7DliNFY4YmIPmQJ+y+EvJW1rSZTZAZI1Nbijg3n
|
||||
fSd0PTzvgOGHSl1//RI1mFx7MwKBgQDapIPPSF0yf1UJ6Hhzam5NHGZ9fSqV5Qs0
|
||||
Gi7uM08iDV5K7xiPglBkbN2EuMlgVnHaa5g8X897uwRSYR6nL4PRvcJiNSvnhWhe
|
||||
+K3x7iHewIPYVfcghoqzuPKsXH2Zm26usdXHxBBa3IBbKtGaHnAd9h65AOUYAmAx
|
||||
C2BzN90XMQKBgE2MjEFyPZunMulrsOziVG+Zm7ClhXOuvCwkj/pPp8/hzhXdgp+y
|
||||
ObV09lxMuDX59l+VExEI7fd414yg8gngq3PMZJS2PxCpkvMlwhlCxk6d5ShXVHv3
|
||||
LuH9dBS3BJ7PerZPQ24QeuJdF+n45S2UZgg8jHaaF9AEAYXRgsicVSdxAoGAJI0U
|
||||
K/bg/awjv0BJwqGsRt/Ukm32TJC5ysAF0HRrajnp5YULChKy9dbtQV7S63QIHIeY
|
||||
L5+kw/6DvnHV+gULeGjMsjZJXK8Ev7u6+JLivqZYZDYa1iknztvAVegwZxmA61t3
|
||||
bantQgNSwerql2U3QQsAH9Vydw0On6RTP2+7WkECgYBWD3u64hBKmAxPkqPotkgI
|
||||
w/jdOlv8FLHO79+oH1PtKvkzspcYaecKGDm/RNLIXLYnt0AmZEK4qQ4/zDFaR/rc
|
||||
AhoxK2cKTRltMrhp1ivtFfLggVGogtYNxEnjnsD4KMvH3SjSNdt06YgtZ92++fOp
|
||||
UsE8Mpf4/G5X7DmcHJHk+w==
|
||||
-----END PRIVATE KEY-----
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
start_authelia() {
|
||||
kubectl create configmap authelia-config --namespace=authelia --from-file=authelia/configs/configuration.yml
|
||||
kubectl create configmap authelia-ssl --namespace=authelia --from-file=authelia/ssl/cert.pem --from-file=authelia/ssl/key.pem
|
||||
kubectl apply -f authelia
|
||||
}
|
||||
|
||||
start_authelia
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
start_dashboard() {
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
|
||||
kubectl apply -f dashboard.yml
|
||||
|
||||
echo "Bearer token for UI user."
|
||||
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
|
||||
}
|
||||
|
||||
start_dashboard
|
|
@ -1,42 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
start_apps() {
|
||||
# Create TLS certificate and key for HTTPS termination
|
||||
kubectl create secret generic test-app-tls --namespace=authelia --from-file=apps/ssl/server.key --from-file=apps/ssl/server.cert
|
||||
kubectl create configmap nginx-config --namespace=authelia --from-file=apps/configs/entrypoint.sh --from-file=apps/configs/nginx.conf --from-file=apps/configs/html.tar.gz
|
||||
|
||||
# Spawn the applications
|
||||
kubectl apply -f apps
|
||||
}
|
||||
|
||||
start_ingress_controller() {
|
||||
kubectl apply -f ingress-controller
|
||||
}
|
||||
|
||||
# Spawn Redis and storage backend
|
||||
# Please note they are not configured to be distributed on several machines
|
||||
start_storage() {
|
||||
kubectl apply -f storage
|
||||
}
|
||||
|
||||
# Create a fake mailbox to catch emails sent by Authelia
|
||||
start_mail() {
|
||||
kubectl apply -f mail
|
||||
}
|
||||
|
||||
start_ldap() {
|
||||
kubectl create configmap ldap-config --namespace=authelia --from-file=ldap/base.ldif --from-file=ldap/access.rules
|
||||
kubectl apply -f ldap
|
||||
}
|
||||
|
||||
# Create the Authelia namespace in the cluster
|
||||
create_namespace() {
|
||||
kubectl apply -f namespace.yml
|
||||
}
|
||||
|
||||
create_namespace
|
||||
start_storage
|
||||
start_ldap
|
||||
start_mail
|
||||
start_ingress_controller
|
||||
start_apps
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: admin-user
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: admin-user
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: admin-user
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
|
@ -0,0 +1,346 @@
|
|||
# Kubernetes Dashboard
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 8443
|
||||
selector:
|
||||
k8s-app: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard-certs
|
||||
namespace: kubernetes-dashboard
|
||||
type: Opaque
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard-csrf
|
||||
namespace: kubernetes-dashboard
|
||||
type: Opaque
|
||||
data:
|
||||
csrf: ""
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard-key-holder
|
||||
namespace: kubernetes-dashboard
|
||||
type: Opaque
|
||||
...
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard-settings
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
rules:
|
||||
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
|
||||
verbs: ["get", "update", "delete"]
|
||||
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
resourceNames: ["kubernetes-dashboard-settings"]
|
||||
verbs: ["get", "update"]
|
||||
# Allow Dashboard to get metrics.
|
||||
- apiGroups: [""]
|
||||
resources: ["services"]
|
||||
resourceNames: ["heapster", "dashboard-metrics-scraper"]
|
||||
verbs: ["proxy"]
|
||||
- apiGroups: [""]
|
||||
resources: ["services/proxy"]
|
||||
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"] # yamllint disable-line rule:line-length
|
||||
verbs: ["get"]
|
||||
...
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
rules:
|
||||
# Allow Metrics Scraper to get metrics from the Metrics server
|
||||
- apiGroups: ["metrics.k8s.io"]
|
||||
resources: ["pods", "nodes"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: kubernetes-dashboard
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: kubernetes-dashboard
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: kubernetes-dashboard
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
name: kubernetes-dashboard
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
spec:
|
||||
securityContext:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: kubernetes-dashboard
|
||||
image: kubernetesui/dashboard:v2.7.0
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8443
|
||||
protocol: TCP
|
||||
args:
|
||||
- --auto-generate-certificates
|
||||
- --namespace=kubernetes-dashboard
|
||||
# Uncomment the following line to manually specify Kubernetes API server Host
|
||||
# If not specified, Dashboard will attempt to auto discover the API server and connect
|
||||
# to it. Uncomment only if the default does not work.
|
||||
# - --apiserver-host=http://my-address:port
|
||||
volumeMounts:
|
||||
- name: kubernetes-dashboard-certs
|
||||
mountPath: /certs
|
||||
# Create on-disk volume to store exec logs
|
||||
- mountPath: /tmp
|
||||
name: tmp-volume
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
scheme: HTTPS
|
||||
path: /
|
||||
port: 8443
|
||||
initialDelaySeconds: 30
|
||||
timeoutSeconds: 30
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 2001
|
||||
volumes:
|
||||
- name: kubernetes-dashboard-certs
|
||||
secret:
|
||||
secretName: kubernetes-dashboard-certs
|
||||
- name: tmp-volume
|
||||
emptyDir: {}
|
||||
serviceAccountName: kubernetes-dashboard
|
||||
nodeSelector:
|
||||
"kubernetes.io/os": linux
|
||||
# Comment the following tolerations if Dashboard must not be deployed on master
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
...
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: dashboard-metrics-scraper
|
||||
name: dashboard-metrics-scraper
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
selector:
|
||||
k8s-app: dashboard-metrics-scraper
|
||||
...
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: dashboard-metrics-scraper
|
||||
name: dashboard-metrics-scraper
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: dashboard-metrics-scraper
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: dashboard-metrics-scraper
|
||||
spec:
|
||||
securityContext:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: dashboard-metrics-scraper
|
||||
image: kubernetesui/metrics-scraper:v1.0.8
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
scheme: HTTP
|
||||
path: /
|
||||
port: 8000
|
||||
initialDelaySeconds: 30
|
||||
timeoutSeconds: 30
|
||||
volumeMounts:
|
||||
- mountPath: /tmp
|
||||
name: tmp-volume
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 2001
|
||||
serviceAccountName: kubernetes-dashboard
|
||||
nodeSelector:
|
||||
"kubernetes.io/os": linux
|
||||
# Comment the following tolerations if Dashboard must not be deployed on master
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
volumes:
|
||||
- name: tmp-volume
|
||||
emptyDir: {}
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: admin-user
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: admin-user
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: admin-user
|
||||
namespace: kubernetes-dashboard
|
||||
...
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRouteTCP
|
||||
metadata:
|
||||
name: kubernetes-dashboard-ingress
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- match: HostSNI(`kubernetes.example.com`)
|
||||
services:
|
||||
- name: kubernetes-dashboard
|
||||
port: 443
|
||||
tls:
|
||||
passthrough: true
|
||||
...
|
||||
# Traefik Dashboard
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: traefik-dashboard-ingress
|
||||
namespace: authelia
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- match: Host(`traefik.example.com`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: api@internal
|
||||
kind: TraefikService
|
||||
...
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: ServersTransport
|
||||
metadata:
|
||||
name: skipverify
|
||||
namespace: authelia
|
||||
spec:
|
||||
insecureSkipVerify: true
|
||||
...
|
|
@ -1,45 +0,0 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-ingress-controller
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx-ingress-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
annotations:
|
||||
prometheus.io/port: '10254'
|
||||
prometheus.io/scrape: 'true'
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
serviceAccountName: nginx-ingress-controller-serviceaccount
|
||||
containers:
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0
|
||||
name: nginx-ingress-controller
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 443
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --ingress-class=nginx
|
||||
- --election-id=ingress-controller-leader
|
||||
...
|
|
@ -1,141 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: nginx-ingress-controller-serviceaccount
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: nginx-ingress-controller-clusterrole
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- endpoints
|
||||
- nodes
|
||||
- pods
|
||||
- secrets
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
- apiGroups:
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- update
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: nginx-ingress-controller-role
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- pods
|
||||
- secrets
|
||||
- namespaces
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
resourceNames:
|
||||
# Defaults to "<election-id>-<ingress-class>"
|
||||
# Here: "<ingress-controller-leader>-<nginx>"
|
||||
# This has to be adapted if you change either parameter
|
||||
# when launching the nginx-ingress-controller.
|
||||
- "ingress-controller-leader-nginx"
|
||||
verbs:
|
||||
- get
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- endpoints
|
||||
verbs:
|
||||
- get
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: nginx-ingress-controller-role-nisa-binding
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: nginx-ingress-controller-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nginx-ingress-controller-serviceaccount
|
||||
namespace: authelia
|
||||
...
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: nginx-ingress-controller-clusterrole-nisa-binding
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: nginx-ingress-controller-clusterrole
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nginx-ingress-controller-serviceaccount
|
||||
namespace: authelia
|
||||
...
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-ingress-controller-service
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: nginx-ingress-controller
|
||||
spec:
|
||||
selector:
|
||||
app: nginx-ingress-controller
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
- port: 443
|
||||
name: https
|
||||
...
|
|
@ -1,7 +0,0 @@
|
|||
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou
|
||||
s auth by * none
|
||||
# olcAccess: {1}to dn.base="" by * read
|
||||
# olcAccess: {2}to * by * read
|
||||
|
||||
olcPasswordHash: {CRYPT}
|
||||
olcPasswordCryptSaltFormat: $6$rounds=50000$%.16s
|
|
@ -1,67 +0,0 @@
|
|||
dn: ou=groups,dc=example,dc=com
|
||||
objectClass: organizationalUnit
|
||||
objectClass: top
|
||||
ou: groups
|
||||
|
||||
dn: ou=users,dc=example,dc=com
|
||||
objectClass: organizationalUnit
|
||||
objectClass: top
|
||||
ou: users
|
||||
|
||||
dn: cn=dev,ou=groups,dc=example,dc=com
|
||||
cn: dev
|
||||
member: uid=john,ou=users,dc=example,dc=com
|
||||
member: uid=bob,ou=users,dc=example,dc=com
|
||||
objectClass: groupOfNames
|
||||
objectClass: top
|
||||
|
||||
dn: cn=admins,ou=groups,dc=example,dc=com
|
||||
cn: admins
|
||||
member: uid=john,ou=users,dc=example,dc=com
|
||||
objectClass: groupOfNames
|
||||
objectClass: top
|
||||
|
||||
dn: uid=john,ou=users,dc=example,dc=com
|
||||
uid: john
|
||||
cn: john
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: top
|
||||
mail: john.doe@authelia.com
|
||||
sn: John Doe
|
||||
userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
|
||||
dn: uid=harry,ou=users,dc=example,dc=com
|
||||
uid: harry
|
||||
cn: harry
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: top
|
||||
mail: harry.potter@authelia.com
|
||||
sn: Harry Potter
|
||||
userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
|
||||
dn: uid=bob,ou=users,dc=example,dc=com
|
||||
uid: bob
|
||||
cn: bob
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: top
|
||||
mail: bob.dylan@authelia.com
|
||||
sn: Bob Dylan
|
||||
userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
|
||||
dn: uid=james,ou=users,dc=example,dc=com
|
||||
uid: james
|
||||
cn: james
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: top
|
||||
mail: james.dean@authelia.com
|
||||
sn: James Dean
|
||||
userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
|
||||
dn: uid=blackhat,ou=users,dc=example,dc=com
|
||||
uid: blackhat
|
||||
cn: blackhat
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: top
|
||||
mail: billy.blackhat@authelia.com
|
||||
sn: Billy BlackHat
|
||||
userPassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
|
@ -41,19 +41,24 @@ spec:
|
|||
- name: LDAP_TLS_VERIFY_CLIENT
|
||||
value: try
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom/base.ldif
|
||||
subPath: base.ldif
|
||||
- name: config-volume
|
||||
mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom/access.rules
|
||||
subPath: access.rules
|
||||
- name: ldap-config
|
||||
mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: ldap-config
|
||||
items:
|
||||
- key: base.ldif
|
||||
path: base.ldif
|
||||
- key: access.rules
|
||||
path: access.rules
|
||||
- name: ldap-config
|
||||
hostPath:
|
||||
path: /configmaps/ldap
|
||||
type: Directory
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ldap-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: ldap
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 636
|
||||
...
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ldap-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: ldap
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 636
|
||||
...
|
|
@ -1,25 +0,0 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mailcatcher
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mailcatcher
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
containers:
|
||||
- name: mailcatcher
|
||||
image: schickling/mailcatcher
|
||||
ports:
|
||||
- containerPort: 1025
|
||||
- containerPort: 1080
|
||||
...
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: mailcatcher-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: mail-tls
|
||||
hosts:
|
||||
- mail.example.com
|
||||
rules:
|
||||
- host: mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: mailcatcher-service
|
||||
servicePort: 1080
|
||||
...
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mailcatcher
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mailcatcher
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
containers:
|
||||
- name: mailcatcher
|
||||
image: schickling/mailcatcher
|
||||
ports:
|
||||
- containerPort: 1025
|
||||
- containerPort: 1080
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mailcatcher-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: mailcatcher
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 1080
|
||||
name: ui
|
||||
- protocol: TCP
|
||||
port: 1025
|
||||
name: smtp
|
||||
...
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: mailcatcher-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
spec:
|
||||
rules:
|
||||
- host: mail.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: mailcatcher-service
|
||||
port:
|
||||
number: 1080
|
||||
...
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mailcatcher-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: mailcatcher
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 1080
|
||||
name: ui
|
||||
- protocol: TCP
|
||||
port: 1025
|
||||
name: smtp
|
||||
...
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
mirrors:
|
||||
"docker.io":
|
||||
endpoint:
|
||||
- http://registrycache.internal:5000
|
||||
...
|
|
@ -21,9 +21,11 @@ spec:
|
|||
image: mariadb:10.4.10
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: 3306
|
||||
periodSeconds: 1
|
||||
env:
|
||||
- name: SLAPD_ORGANISATION
|
||||
value: MyCompany
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: rootpassword
|
||||
- name: MYSQL_USER
|
||||
|
@ -32,13 +34,6 @@ spec:
|
|||
value: password
|
||||
- name: MYSQL_DATABASE
|
||||
value: authelia
|
||||
volumeMounts:
|
||||
- name: data-volume
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: data-volume
|
||||
hostPath:
|
||||
path: /data/storage/mysql
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
|
@ -21,6 +21,10 @@ spec:
|
|||
image: redis:3.2.11-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: 6379
|
||||
periodSeconds: 1
|
||||
...
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: test-app1
|
||||
namespace: kube-public
|
||||
labels:
|
||||
app: test-app1
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test-app1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: test-app1
|
||||
spec:
|
||||
containers:
|
||||
- name: test-app1
|
||||
image: authelia/authelia:kube
|
||||
imagePullPolicy: Never
|
||||
...
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
version: '3.4'
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia:latest
|
||||
# Used for Docker configs
|
||||
configs:
|
||||
- source: authelia
|
||||
target: /config/configuration.yml
|
||||
uid: '0'
|
||||
gid: '0'
|
||||
mode: 0444 # yamllint disable-line rule:octal-values
|
||||
environment:
|
||||
- NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||
# Where the authelia volume is to be mounted. To only use a single volume, the minimal config
|
||||
# needs to be changed to read the users_database.yml also from this subdirectory.
|
||||
# Otherwise a second volume will need to be configured here to mount the users_database.yml.
|
||||
volumes:
|
||||
- authelia:/config/storage
|
||||
networks:
|
||||
- overlay
|
||||
deploy:
|
||||
# Configure Authelia to automatically restart on failure.
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
window: 120s
|
||||
# Mode: global would start authelia on all available nodes,
|
||||
# replicated limits it to how many replicas are configured.
|
||||
mode: replicated
|
||||
# How many replicas are wanted. Can be any number >0 up to however many nodes are available.
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == worker
|
||||
|
||||
# The volume for authelia needs to be configured.
|
||||
# There are many drivers available. Such as local storage, ceph-rdb, nfs, cifs etc.
|
||||
volumes:
|
||||
authelia:
|
||||
driver: default
|
||||
name: volume-authelia
|
||||
|
||||
networks:
|
||||
overlay:
|
||||
external: true
|
||||
|
||||
# This is needed if Docker configs are being used to provide Authelia with its configuration.
|
||||
configs:
|
||||
authelia:
|
||||
external: true
|
||||
...
|
|
@ -3,53 +3,41 @@ package suites
|
|||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
||||
var kindImageName = "authelia-kind-proxy"
|
||||
var dockerCmdLine = fmt.Sprintf("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml run -T --rm %s", kindImageName)
|
||||
var k3dImageName = "k3d"
|
||||
var dockerCmdLine = fmt.Sprintf("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/k3d/docker-compose.yml exec -T %s", k3dImageName)
|
||||
|
||||
// Kind used for running kind commands.
|
||||
type Kind struct{}
|
||||
// K3D used for running kind commands.
|
||||
type K3D struct{}
|
||||
|
||||
func kindCommand(cmdline string) *exec.Cmd {
|
||||
func k3dCommand(cmdline string) *exec.Cmd {
|
||||
cmd := fmt.Sprintf("%s %s", dockerCmdLine, cmdline)
|
||||
return utils.Shell(cmd)
|
||||
}
|
||||
|
||||
// CreateCluster create a new Kubernetes cluster.
|
||||
func (k Kind) CreateCluster() error {
|
||||
cmd := kindCommand("kind create cluster --config /etc/kind/config.yml")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = kindCommand("patch-kubeconfig.sh")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This command is necessary to fix the coredns loop detected when using user-defined docker network.
|
||||
// In that case /etc/resolv.conf use 127.0.0.11 as DNS and CoreDNS thinks it is talking to itself which is wrong.
|
||||
// This IP is the docker internal DNS so it is safe to disable the loop check.
|
||||
cmd = kindCommand("sh -c 'kubectl -n kube-system get configmap/coredns -o yaml | grep -v loop | kubectl replace -f -'")
|
||||
func (k K3D) CreateCluster() error {
|
||||
cmd := k3dCommand("k3d cluster create --registry-config /authelia/registry.yml -v /authelia:/var/lib/rancher/k3s/server/manifests/custom -v /configmaps:/configmaps -p 8080:443")
|
||||
err := cmd.Run()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCluster delete a Kubernetes cluster.
|
||||
func (k Kind) DeleteCluster() error {
|
||||
cmd := kindCommand("kind delete cluster")
|
||||
func (k K3D) DeleteCluster() error {
|
||||
cmd := k3dCommand("k3d cluster delete")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// ClusterExists check whether a cluster exists.
|
||||
func (k Kind) ClusterExists() (bool, error) {
|
||||
cmd := kindCommand("kind get clusters")
|
||||
func (k K3D) ClusterExists() (bool, error) {
|
||||
cmd := k3dCommand("k3d cluster list")
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
output, err := cmd.Output()
|
||||
|
@ -58,63 +46,27 @@ func (k Kind) ClusterExists() (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
|
||||
return strings.Contains(string(output), "kind"), nil
|
||||
return strings.Contains(string(output), "k3s-default"), nil
|
||||
}
|
||||
|
||||
// LoadImage load an image in the Kubernetes container.
|
||||
func (k Kind) LoadImage(imageName string) error {
|
||||
cmd := kindCommand(fmt.Sprintf("kind load docker-image %s", imageName))
|
||||
func (k K3D) LoadImage(imageName string) error {
|
||||
cmd := k3dCommand(fmt.Sprintf("k3d image import %s", imageName))
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// Kubectl used for running kubectl commands.
|
||||
type Kubectl struct{}
|
||||
|
||||
// StartProxy start a proxy.
|
||||
func (k Kubectl) StartProxy() error {
|
||||
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d authelia-kind-proxy")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// StopProxy stop a proxy.
|
||||
func (k Kubectl) StopProxy() error {
|
||||
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f authelia-kind-proxy")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// StartDashboard start Kube dashboard.
|
||||
func (k Kubectl) StartDashboard() error {
|
||||
if err := kindCommand("sh -c 'cd /authelia && ./bootstrap-dashboard.sh'").Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d kube-dashboard").Run()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// StopDashboard stop kube dashboard.
|
||||
func (k Kubectl) StopDashboard() error {
|
||||
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f kube-dashboard")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// DeployThirdparties deploy thirdparty services (ldap, db, ingress controllers, etc...).
|
||||
func (k Kubectl) DeployThirdparties() error {
|
||||
cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap.sh'")
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// DeployAuthelia deploy Authelia application.
|
||||
func (k Kubectl) DeployAuthelia() error {
|
||||
cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap-authelia.sh'")
|
||||
return cmd.Run()
|
||||
// GetDashboardToken generates bearer token for Kube Dashboard.
|
||||
func (k Kubectl) GetDashboardToken() error {
|
||||
return k3dCommand("kubectl -n kubernetes-dashboard create token admin-user;echo ''").Run()
|
||||
}
|
||||
|
||||
// WaitPodsReady wait for all pods to be ready.
|
||||
func (k Kubectl) WaitPodsReady(timeout time.Duration) error {
|
||||
func (k Kubectl) WaitPodsReady(namespace string, timeout time.Duration) error {
|
||||
return utils.CheckUntil(5*time.Second, timeout, func() (bool, error) {
|
||||
cmd := kindCommand("kubectl get -n authelia pods --no-headers")
|
||||
cmd := k3dCommand(fmt.Sprintf("kubectl get -n %s pods --no-headers --field-selector=status.phase!=Succeeded", namespace))
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
output, _ := cmd.Output()
|
||||
|
@ -129,10 +81,12 @@ func (k Kubectl) WaitPodsReady(timeout time.Duration) error {
|
|||
}
|
||||
|
||||
for _, line := range nonEmptyLines {
|
||||
if !strings.Contains(line, "1/1") {
|
||||
re := regexp.MustCompile(`1/1|2/2`)
|
||||
if !re.MatchString(line) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package suites
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
|
@ -13,94 +12,87 @@ import (
|
|||
var kubernetesSuiteName = "Kubernetes"
|
||||
|
||||
func init() {
|
||||
kind := Kind{}
|
||||
dockerEnvironment := NewDockerEnvironment([]string{
|
||||
"internal/suites/docker-compose.yml",
|
||||
"internal/suites/example/compose/k3d/docker-compose.yml",
|
||||
})
|
||||
|
||||
k3d := K3D{}
|
||||
kubectl := Kubectl{}
|
||||
|
||||
setup := func(suitePath string) error {
|
||||
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml build")
|
||||
if err := cmd.Run(); err != nil {
|
||||
if err := dockerEnvironment.Up(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exists, err := kind.ClusterExists()
|
||||
err := waitUntilK3DIsReady(dockerEnvironment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exists, err := k3d.ClusterExists()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exists {
|
||||
log.Debug("Kubernetes cluster already exists")
|
||||
log.Info("Kubernetes cluster already exists")
|
||||
} else {
|
||||
err = kind.CreateCluster()
|
||||
|
||||
err = k3d.CreateCluster()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("Building authelia:dist image or use cache if already built...")
|
||||
log.Info("Building authelia:dist image or use cache if already built...")
|
||||
|
||||
if os.Getenv("CI") != t {
|
||||
if err := utils.Shell("authelia-scripts docker build").Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := utils.Shell("docker save authelia:dist -o internal/suites/example/kube/authelia-image-dev.tar").Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("Loading images into Kubernetes container...")
|
||||
log.Info("Loading images into Kubernetes container...")
|
||||
|
||||
if err := loadDockerImages(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Starting Kubernetes dashboard...")
|
||||
log.Info("Waiting for cluster to be ready...")
|
||||
|
||||
if err := kubectl.StartDashboard(); err != nil {
|
||||
if err := waitAllPodsAreReady(namespaceKube, 5*time.Minute); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Deploying thirdparties...")
|
||||
log.Info("Waiting for dashboard to be ready...")
|
||||
|
||||
if err := kubectl.DeployThirdparties(); err != nil {
|
||||
err = waitAllPodsAreReady(namespaceDashboard, 2*time.Minute)
|
||||
|
||||
log.Info("Bearer token for UI user:")
|
||||
|
||||
if err := kubectl.GetDashboardToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Waiting for services to be ready...")
|
||||
log.Info("Waiting for services to be ready...")
|
||||
|
||||
if err := waitAllPodsAreReady(5 * time.Minute); err != nil {
|
||||
if err := waitAllPodsAreReady(namespaceAuthelia, 5*time.Minute); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Deploying Authelia...")
|
||||
|
||||
if err = kubectl.DeployAuthelia(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Waiting for services to be ready...")
|
||||
|
||||
if err := waitAllPodsAreReady(2 * time.Minute); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("Starting proxy...")
|
||||
|
||||
err = kubectl.StartProxy()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
teardown := func(suitePath string) error {
|
||||
err := kubectl.StopDashboard()
|
||||
if err != nil {
|
||||
log.Errorf("Unable to stop Kubernetes dashboard: %s", err)
|
||||
if err := k3d.DeleteCluster(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = kubectl.StopProxy()
|
||||
if err != nil {
|
||||
log.Errorf("Unable to stop Kind proxy: %s", err)
|
||||
}
|
||||
|
||||
return kind.DeleteCluster()
|
||||
return dockerEnvironment.Down()
|
||||
}
|
||||
|
||||
GlobalRegistry.Register(kubernetesSuiteName, Suite{
|
||||
|
@ -109,16 +101,20 @@ func init() {
|
|||
TestTimeout: 2 * time.Minute,
|
||||
TearDown: teardown,
|
||||
TearDownTimeout: 2 * time.Minute,
|
||||
Description: "This suite has been created to test Authelia in a Kubernetes context and using nginx as the ingress controller.",
|
||||
Description: "This suite has been created to test Authelia in a Kubernetes context and using Traefik as the ingress controller.",
|
||||
})
|
||||
}
|
||||
|
||||
func loadDockerImages() error {
|
||||
kind := Kind{}
|
||||
images := []string{"authelia:dist"}
|
||||
k3d := K3D{}
|
||||
images := []string{"/authelia/authelia-image-coverage.tar"}
|
||||
|
||||
if os.Getenv("CI") != t {
|
||||
images = []string{"/authelia/authelia-image-dev.tar"}
|
||||
}
|
||||
|
||||
for _, image := range images {
|
||||
err := kind.LoadImage(image)
|
||||
err := k3d.LoadImage(image)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -128,17 +124,16 @@ func loadDockerImages() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func waitAllPodsAreReady(timeout time.Duration) error {
|
||||
func waitAllPodsAreReady(namespace string, timeout time.Duration) error {
|
||||
kubectl := Kubectl{}
|
||||
// Wait in case the deployment has just been done and some services do not appear in kubectl logs.
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Check services are running")
|
||||
|
||||
if err := kubectl.WaitPodsReady(timeout); err != nil {
|
||||
log.Infof("Checking services in %s namespace are running...", namespace)
|
||||
|
||||
if err := kubectl.WaitPodsReady(namespace, timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("All pods are ready")
|
||||
log.Info("All pods are ready")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue