Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/release_sharing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Build sharing on release

on:
release:
types: [created]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/sharing
HUSKY: 0

jobs:
build:
name: Build and push image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=true
tags: |
type=semver,pattern={{version}}
type=sha,enable=false

- name: Build and push Docker image
id: push
uses: docker/build-push-action@v5
with:
context: ./sharing
file: ./sharing/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: false

edit-helm-version:
name: Edit Helm version
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: main
ssh-key: ${{ secrets.ACTIONS_DEPLOY_KEY }}

- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ACTIONS_DEPLOY_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts

- name: Update Helm app version
run: |
sed -i "s/appVersion: \".*\"/appVersion: \"${{ github.event.release.tag_name }}\"/g" sharing/helm/Chart.yaml
git add sharing/helm/Chart.yaml
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git commit -m "Update app version to ${{ github.event.release.tag_name }}"
git push origin main
119 changes: 119 additions & 0 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Infrastructure
---

This part detail how the polypass application is hosted.

## Requirements

You should have on you local machine:
- helm v3.13.1
- kubectl v1.29.0
- istioctl v1.24.3

## Vm

A virtual machine on Serdaigle Proxmox cluster has been deployed with:
- 24 go RAM
- 6 Cpu
- Debian 12

## Kubernetes cluster

The cluster has been deployed using [k3s](https://k3s.io/) and the default command:
```sh
curl -sfL https://get.k3s.io | sh -
```

## Service mesh and network

We will use Istio as a service mesh. Istio manage its own gateway service and k3s install by default traefik IngressController.
So we will begin by removing the helm chart:
```sh
helm uninstall traefik -n kube-system
```

The cluster is ready to host Istio. We will use the [default profile](https://istio.io/latest/docs/setup/additional-setup/config-profiles/#deployment-profiles) to install istio.
It will allow the install of [`istio-ingressgateway`](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/) and therefore we will be able to manage ingress traffic to our services.
You can use the [command](https://istio.io/latest/docs/setup/install/istioctl/):
```sh
istioctl install -f ./istio_operator.yaml
```

## Observability


[Jaeger install](https://istio.io/latest/docs/ops/integrations/jaeger/):
```sh
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/jaeger.yaml
kubectl apply -f jaeger.yaml
```

[Install Otel](https://istio.io/latest/docs/tasks/observability/distributed-tracing/opentelemetry/):
```sh
kubectl create namespace observability
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/open-telemetry/otel.yaml -n observability
kubectl apply -f otel.yaml
```

[Install Prometheus](https://istio.io/latest/docs/ops/integrations/prometheus/#configuration):
```sh
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/prometheus.yaml
```


[Install grafana](https://istio.io/latest/docs/ops/integrations/grafana/):
```sh
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/grafana.yaml
```


Install a mesh vizualizer [Kiali](https://istio.io/latest/docs/ops/integrations/kiali/):
```sh
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/addons/kiali.yaml
```


## Confluent

[Prepare the cluster](https://docs.confluent.io/operator/current/co-prepare.html#quick-easy-deployment-and-relaxed-permissions):
```sh
kubectl create namespace confluent
helm repo add confluentinc https://packages.confluent.io/helm
kubectl apply -f confluent/confluent-for-kubernetes/crds
# As this crd is too long you have to force it see
# https://docs.confluent.io/operator/current/co-troubleshooting.html#issue-an-error-returns-while-applying-a-crd-during-an-upgrade
kubectl apply --server-side=true --force-conflicts -f confluent/confluent-for-kubernetes/crds/platform.confluent.io_kafkas.yaml
```

Install confluent-for-kubernetes:
```sh
helm upgrade --install confluent-operator \
confluentinc/confluent-for-kubernetes \
--namespace confluent
```

Install confluent platform (Kafka, Schema registry and zookeeper):
```sh
kubectl apply -f confluent-platform.yaml
```

It can take up to 10 min to deploy.


## Deploy Authzed Operator


[Deploy the operator:](https://github.com/authzed/spicedb-operator?tab=readme-ov-file#getting-started)
```sh
kubectl apply --server-side -f https://github.com/authzed/spicedb-operator/releases/latest/download/bundle.yaml
```

Create a namespace for the authorization service:
```sh
kubectl create namespace authz
```

Deploy the spicedb cluster:
```sh
kubectl apply -f ./authzed/cluster-spicedb.yaml
```
23 changes: 23 additions & 0 deletions infrastructure/authn/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 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
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
6 changes: 6 additions & 0 deletions infrastructure/authn/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies:
- name: keycloak
repository: oci://registry-1.docker.io/bitnamicharts
version: 24.7.3
digest: sha256:54e85d57f49ef8ed6578f500febbcd381362efb937cef79e2d4687600c59ed1a
generated: "2025-06-11T12:24:21.079199303+02:00"
29 changes: 29 additions & 0 deletions infrastructure/authn/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: v2
name: authn
description: A keycloak Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.1"

dependencies:
- name: keycloak
version: 24.7.3
repository: oci://registry-1.docker.io/bitnamicharts
6 changes: 6 additions & 0 deletions infrastructure/authn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Requirements

- Cert Manager installed in the cluster
- A Kubernetes Cluster (tested on K3S)

This values are for the bitnami keycloak helm chart.
15 changes: 15 additions & 0 deletions infrastructure/authn/cert-manager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: polypass-prod
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: polypass-certificates
solvers:
- http01:
ingress:
class: traefik
12 changes: 12 additions & 0 deletions infrastructure/authn/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: polypass-certificates
namespace: default
spec:
secretName: auth.polypass.umontpelier.fr-tls
issuerRef:
name: polypass-prod
kind: ClusterIssuer
dnsNames:
- auth.polypass.umontpelier.fr
Binary file added infrastructure/authn/charts/keycloak-24.7.3.tgz
Binary file not shown.
22 changes: 22 additions & 0 deletions infrastructure/authn/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "authn.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 "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "authn.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "authn.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "authn.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
62 changes: 62 additions & 0 deletions infrastructure/authn/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "authn.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).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "authn.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

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

{{/*
Common labels
*/}}
{{- define "authn.labels" -}}
helm.sh/chart: {{ include "authn.chart" . }}
{{ include "authn.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "authn.selectorLabels" -}}
app.kubernetes.io/name: {{ include "authn.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "authn.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "authn.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
Loading