Skip to content
Draft
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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,14 @@ FodyWeavers.xsd
.idea/
*.sln.iml
*launchSettings.json

# integrationtest state files and generated directories
/integration_tests/terraform/*/.terraform/
/integration_tests/terraform/*/terraform.tfstate*
/integration_tests/terraform/*/.terraform.lock.hcl

# codegen temporary files
pkg/openapi.json*

# integration tsts dependency charts
/integration_tests/helm/setup/charts/*.tgz
23 changes: 23 additions & 0 deletions integration_tests/helm/setup/.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/
12 changes: 12 additions & 0 deletions integration_tests/helm/setup/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dependencies:
- name: boxer-crd
repository: oci://ghcr.io/sneaksanddata/helm
version: v0.0.5
- name: boxer-issuer
repository: oci://ghcr.io/sneaksanddata/helm
version: v0.0.14
- name: boxer-validator-nginx
repository: oci://ghcr.io/sneaksanddata/helm
version: v0.0.15
digest: sha256:5f1192696ab1c7824862f2024e691105b705b0a34bfaa8075b2873ecaa595b06
generated: "2025-10-24T14:53:24.367292+02:00"
18 changes: 18 additions & 0 deletions integration_tests/helm/setup/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: setup
description: Integration test setup chart for terraform-provider-boxer
type: application
version: 0.0.1
appVersion: "0.0.1"
dependencies:
- name: boxer-crd
version: "v0.0.5"
repository: "oci://ghcr.io/sneaksanddata/helm"
- name: boxer-issuer
version: "v0.0.14"
repository: "oci://ghcr.io/sneaksanddata/helm"
- name: boxer-validator-nginx
version: "v0.0.15"
repository: "oci://ghcr.io/sneaksanddata/helm"


4 changes: 4 additions & 0 deletions integration_tests/helm/setup/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
IMPORTANT NOTE:
This chart is designed to be used in integration tests and is not intended for production use.
If you want to install the Boxer Issuer application, please use the Boxer Issuer chart instead.
The boxer issuer chart can be found at: https://github.com/SneaksAndData/boxer-crd/pkgs/container/helm%2Fboxer-crd
62 changes: 62 additions & 0 deletions integration_tests/helm/setup/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "integration_tests.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 "integration_tests.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 "integration_tests.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

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

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

{{/*
Create the name of the service account to use
*/}}
{{- define "integration_tests.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "integration_tests.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
Empty file.
13 changes: 13 additions & 0 deletions integration_tests/keycloak.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
command:
- "/opt/keycloak/bin/kc.sh"
- "start"
- "--http-port=8080"
- "--hostname-strict=false"
extraEnv: |
- name: KEYCLOAK_ADMIN
value: admin
- name: KEYCLOAK_ADMIN_PASSWORD
value: admin
- name: JAVA_OPTS_APPEND
value: >-
-Djgroups.dns.query={{ include "keycloak.fullname" . }}-headless
44 changes: 44 additions & 0 deletions integration_tests/manifests/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,47 @@ spec:
name: nexus
port:
number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: boxer-ingress
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- http:
paths:
- pathType: ImplementationSpecific
path: /issuer(/|$)(.*)
backend:
service:
name: boxer-issuer
port:
number: 80
- pathType: ImplementationSpecific
path: /validator(/|$)(.*)
backend:
service:
name: boxer-validator-nginx
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- pathType: Prefix
path: /auth
backend:
service:
name: keycloak-keycloakx-http
port:
number: 80
62 changes: 62 additions & 0 deletions integration_tests/terraform/keycloak/keycloak.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
terraform {
required_providers {
keycloak = {
source = "keycloak/keycloak"
version = "= 5.0.0"
}
}
}

provider "keycloak" {
client_id = "admin-cli"
username = "admin"
password = "admin"
url = "http://localhost:5555/auth"
}

data "keycloak_realm" "master" {
realm = "master"
}

resource "keycloak_openid_client" "test_client" {
name = "test_client"
access_type = "PUBLIC"
client_id = "test_client"
client_secret = "test_client_secret"
realm_id = data.keycloak_realm.master.id
enabled = true
direct_access_grants_enabled = true
}

resource "keycloak_openid_client_default_scopes" "client_default_scopes" {
realm_id = data.keycloak_realm.master.id
client_id = keycloak_openid_client.test_client.id

default_scopes = [
"profile",
"email",
"roles",
"web-origins",
]
}

resource "keycloak_user" "test_user" {
realm_id = data.keycloak_realm.master.id
username = "test_user"
enabled = true

initial_password {
value = "test-user-password"
}
}

resource "keycloak_user" "test_root" {
realm_id = data.keycloak_realm.master.id
username = "test_root"
enabled = true

initial_password {
value = "test-root-password"
}
}

40 changes: 39 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ default:
fresh: stop up

up: start-kind-cluster \
build-deps \
install-ingress-controller \
create-ingress \
scylla \
Expand All @@ -15,14 +16,20 @@ up: start-kind-cluster \
receiver \
supervisor \
minio \
wait-for-services
boxer \
keycloak \
wait-for-services \
keycloak-configuration

stop:
kind delete cluster

start-kind-cluster:
kind create cluster --config=integration_tests/kind.yaml

build-deps:
helm dependency build ./integration_tests/helm/setup

install-ingress-controller:
kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/deploy-ingress-nginx.yaml
kubectl rollout status deployment/ingress-nginx-controller -n ingress-nginx --timeout=180s
Expand Down Expand Up @@ -88,11 +95,42 @@ supervisor:
--set 'supervisor.config.cqlStore.secretRefEnabled=true' \
--set 'supervisor.config.cqlStore.secretName=cassandra-credentials' \
--set 'supervisor.config.resourceNamespace=default'


key := `openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1`
boxer:
helm upgrade --install --namespace default integration-tests integration_tests/helm/setup \
--set boxer-issuer.issuer.replicas=1 \
--set-literal 'boxer-validator-nginx.validator.config.tokenSettings.keys={"default": "{{key}}"}' \
--set 'boxer-issuer.issuer.config.listenIp=0.0.0.0' \
--set 'boxer-issuer.issuer.config.logLevel=debug' \
--set 'boxer-issuer.issuer.config.backend.kubernetes.resourceOwnerLabel=application/boxer-issuer' \
--set 'boxer-validator-nginx.validator.config.listenIp=0.0.0.0' \
--set 'boxer-validator-nginx.validator.config.backend.kubernetes.resourceOwnerLabel=application/boxer-validator-nginx' \
--set boxer-validator-nginx.validator.replicas=1

keycloak:
helm upgrade --install keycloak oci://ghcr.io/codecentric/helm-charts/keycloakx \
--set keycloak.username=admin \
--set keycloak.password=admin \
--values ./integration_tests/keycloak.yaml

wait-for-services:
kubectl rollout status deployment/nexus --timeout=180s
kubectl rollout status deployment/nexus-receiver --timeout=180s
kubectl rollout status deployment/nexus-supervisor --timeout=180s
kubectl rollout status deployment/boxer-issuer --timeout=180s
kubectl rollout status deployment/boxer-validator-nginx --timeout=180s

keycloak-configuration:
# Wait a bit for Keycloak to be ready to accept admin commands
sleep 10

# Create realm, client, and user for tests
docker run --rm --network=host -v $(pwd)/integration_tests/terraform/keycloak:/tofu --workdir /tofu ghcr.io/opentofu/opentofu:latest init
docker run --rm --network=host -v $(pwd)/integration_tests/terraform/keycloak:/tofu --workdir /tofu ghcr.io/opentofu/opentofu:latest plan
docker run --rm --network=host -v $(pwd)/integration_tests/terraform/keycloak:/tofu --workdir /tofu ghcr.io/opentofu/opentofu:latest apply -auto-approve


dbschema:
docker run --rm -v $(pwd)/integration_tests/storage:/opt/storage --network=host --entrypoint /opt/storage/prepare-scylla.sh scylladb/scylla:5.0.1
2 changes: 1 addition & 1 deletion src/SnD.ApiClient/Boxer/BoxerTokenProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class BoxerTokenProvider : IJwtTokenExchangeProvider
{
private readonly Uri authProvider;
private readonly Uri baseUri;
private string token;
private string? token;
private readonly HttpClient httpClient;
private readonly ILogger logger;
private readonly Func<CancellationToken, Task<string>> getExternalTokenAsync;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ public NexusAcceptanceTests()
.AddSingleton<HttpClient>()
.AddLogging(conf => conf.AddConsole())
.Configure<NexusClientOptions>(configurationRoot.GetSection(nameof(NexusClientOptions)))
.AddNexusRetryPolicy(sp => new RetryAllErrors(sp.GetRequiredService<ILogger<RetryAllErrors>>(),
sp.GetRequiredService<IOptions<NexusClientOptions>>()))
.AddNexusRetryPolicy(sp => new RetryAllErrors(sp.GetRequiredService<ILogger<RetryAllErrors>>(), sp.GetRequiredService<IOptions<NexusClientOptions>>()))
.AddNexusClient();

serviceCollection = configuration.UseBoxerTokenProviderOnAzure
Expand Down