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
48 changes: 48 additions & 0 deletions deploy/setup-auto-mtls.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env pwsh
#Requires -Version 5.1
$ErrorActionPreference = "Stop"

# ---- Config (overridable via env) ----
$CERT_MANAGER_VERSION = $env:CERT_MANAGER_VERSION
if ([string]::IsNullOrWhiteSpace($CERT_MANAGER_VERSION)) { $CERT_MANAGER_VERSION = "v1.18.2" }

$AUTO_MTLS_MANIFEST_URL = $env:AUTO_MTLS_MANIFEST_URL
if ([string]::IsNullOrWhiteSpace($AUTO_MTLS_MANIFEST_URL)) { $AUTO_MTLS_MANIFEST_URL = "https://raw.githubusercontent.com/kupher-tools/auto-mtls/refs/heads/main/deploy/auto-mtls-deploy.yaml" }

function Need($cmd) {
if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) {
Write-Error "Missing dependency: '$cmd' not found on PATH"
}
}

Write-Host "[*] Preflight checks"
Need "kubectl"
Need "helm"

Write-Host "[*] Install/upgrade cert-manager ($CERT_MANAGER_VERSION)"
helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager `
--version $CERT_MANAGER_VERSION `
--namespace cert-manager `
--create-namespace `
--set crds.enabled=true | Out-Host

Write-Host "[*] Waiting for cert-manager components..."
kubectl -n cert-manager rollout status deploy/cert-manager --timeout=180s | Out-Host
kubectl -n cert-manager rollout status deploy/cert-manager-webhook --timeout=180s | Out-Host
kubectl -n cert-manager rollout status deploy/cert-manager-cainjector --timeout=180s | Out-Host
Write-Host "[+] cert-manager ready"

Write-Host "[*] Deploy Auto-mTLS Operator"
kubectl apply -f $AUTO_MTLS_MANIFEST_URL | Out-Host

Write-Host "[*] Waiting for auto-mtls operator..."
kubectl -n auto-mtls rollout status deploy/auto-mtls-operator --timeout=180s | Out-Host
Write-Host "[✓] Auto-mTLS Operator ready"



# .\deploy\setup-auto-mtls.ps1
# or with overrides:
# $env:CERT_MANAGER_VERSION = "v1.18.2"
# $env:AUTO_MTLS_MANIFEST_URL = "https://raw.githubusercontent.com/kupher-tools/auto-mtls/refs/heads/main/deploy/auto-mtls-deploy.yaml"
# .\deploy\setup-auto-mtls.ps1
41 changes: 41 additions & 0 deletions deploy/setup-auto-mtls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env sh
set -eu

# ---- Config (overridable) ----
: "${CERT_MANAGER_VERSION:=v1.18.2}"
: "${AUTO_MTLS_MANIFEST_URL:=https://raw.githubusercontent.com/kupher-tools/auto-mtls/refs/heads/main/deploy/auto-mtls-deploy.yaml}"

need() { command -v "$1" >/dev/null 2>&1 || { echo "ERROR: missing '$1' on PATH"; exit 1; }; }

echo "[*] Preflight checks"
need kubectl
need helm

echo "[*] Install/upgrade cert-manager ($CERT_MANAGER_VERSION)"
helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--version "$CERT_MANAGER_VERSION" \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true

echo "[*] Waiting for cert-manager components..."
kubectl -n cert-manager rollout status deploy/cert-manager --timeout=180s
kubectl -n cert-manager rollout status deploy/cert-manager-webhook --timeout=180s
kubectl -n cert-manager rollout status deploy/cert-manager-cainjector --timeout=180s
echo "[+] cert-manager ready"

echo "[*] Deploy Auto-mTLS Operator"
kubectl apply -f "$AUTO_MTLS_MANIFEST_URL"

echo "[*] Waiting for auto-mtls operator..."
kubectl -n auto-mtls rollout status deploy/auto-mtls-operator --timeout=180s
echo "[✓] Auto-mTLS Operator ready"

# Execution

# chmod +x deploy/setup-auto-mtls.sh
# deploy/setup-auto-mtls.sh
# or with overrides:
# CERT_MANAGER_VERSION=v1.18.2 \
# AUTO_MTLS_MANIFEST_URL="https://raw.githubusercontent.com/kupher-tools/auto-mtls/refs/heads/main/deploy/auto-mtls-deploy.yaml" \
# deploy/setup-auto-mtls.sh
44 changes: 44 additions & 0 deletions docs/logging-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Auto-mTLS Operator Logging Format

## Overview
The auto-mTLS operator uses structured logging with consistent formatting across all components. All logs include contextual information such as timestamps, log levels, component names, and relevant Kubernetes resource details.

## Log Format
```
2025-01-27T10:30:45Z INFO auto-mtls Starting auto-mTLS reconciliation {"service": "mtls-server", "namespace": "default"}
2025-01-27T10:30:45Z INFO auto-mtls Certificate created successfully {"certificate": "mtls-server-cert", "namespace": "default", "service": "mtls-server"}
2025-01-27T10:30:45Z INFO auto-mtls mTLS certificates mounted successfully {"service": "mtls-server", "namespace": "default"}
```

## Log Levels
- **INFO**: Normal operational messages
- **ERROR**: Error conditions that need attention
- **V(1)**: Verbose/debug information (use `-v=1` flag)

## Component Names
- `setup`: Main application setup and initialization
- `cert-mgr`: Certificate manager infrastructure
- `ca-cert-mount`: CA certificate mounting operations
- `auto-mtls`: Main auto-mTLS service reconciliation

## Key Fields
All log entries include relevant contextual fields:
- `service`: Kubernetes service name
- `namespace`: Kubernetes namespace
- `certificate`: Certificate resource name
- `secret`: Secret resource name
- `deployment`: Deployment resource name
- `issuer`: Certificate issuer name
- `volume`: Volume name

## Usage Examples

### Enable verbose logging
```bash
kubectl logs -f deployment/auto-mtls-controller-manager -n auto-mtls-system -- --v=1
```

### Filter logs by component
```bash
kubectl logs deployment/auto-mtls-controller-manager -n auto-mtls-system | grep "cert-mgr"
```
16 changes: 9 additions & 7 deletions internal/controller/caCertMount_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"sigs.k8s.io/controller-runtime/pkg/predicate"
)

// AutomtlsReconciler reconciles a Automtls object

Check failure on line 35 in internal/controller/caCertMount_controller.go

View workflow job for this annotation

GitHub Actions / build-and-deploy

comment on exported type DeploymentReconciler should be of the form "DeploymentReconciler ..." (with optional leading article)
type DeploymentReconciler struct {
client.Client
Scheme *runtime.Scheme
Expand All @@ -52,9 +52,9 @@
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/reconcile
func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := logf.FromContext(ctx)
log := logf.FromContext(ctx).WithName("ca-cert-mount")

log.Info("Reconciling Cert Mount Controller", "name", req.Name, "namespace", req.Namespace)
log.Info("Starting CA certificate mount reconciliation", "deployment", req.Name, "namespace", req.Namespace)

caCertSecret := &corev1.Secret{}

Expand All @@ -65,7 +65,7 @@

if err == nil {
// Secret already exists — skip
fmt.Println("CA secret already exists in", req.Namespace)
log.V(1).Info("CA secret already exists, skipping creation", "namespace", req.Namespace)

} else {
//Create secret for CA cert in namespace
Expand All @@ -75,13 +75,13 @@
Name: "auto-mtls-cluster-ca-cert-secret",
Namespace: "cert-manager",
}, src); err != nil {
log.Error(err, "failed to get source CA secret")
log.Error(err, "Failed to get source CA secret", "secret", "auto-mtls-cluster-ca-cert-secret", "namespace", "cert-manager")
return ctrl.Result{}, err
}

caData, ok := src.Data["ca.crt"]
if !ok {
log.Error(err, "Source secret missing ca.crt")
log.Error(nil, "Source secret missing ca.crt field", "secret", "auto-mtls-cluster-ca-cert-secret", "namespace", "cert-manager")
return ctrl.Result{}, fmt.Errorf("source secret missing ca.crt")

}
Expand All @@ -97,10 +97,11 @@
}

if err := r.Create(ctx, newSecret); err != nil {
log.Error(err, "Failed to create CA secret", "secret", newSecret.Name, "namespace", req.Namespace)
return ctrl.Result{}, fmt.Errorf("failed to create secret in %s: %w", req.Namespace, err)
}

fmt.Println("Created CA secret in", req.Namespace)
log.Info("CA secret created successfully", "secret", newSecret.Name, "namespace", req.Namespace)

}

Expand All @@ -122,6 +123,7 @@

// patchDeployment adds a volume and volumeMount if missing
func patchDeployment(ctx context.Context, c client.Client, deploy *appsv1.Deployment) error {
log := logf.FromContext(ctx)
volumeName := "auto-mtls-ca-cert"
secretName := "auto-mtls-ca-cert"
patched := deploy.DeepCopy()
Expand All @@ -131,7 +133,7 @@
foundVol := false
for _, v := range patched.Spec.Template.Spec.Volumes {
if v.Name == volumeName {
fmt.Println("Skipping auto-mtls-ca-cert volume to deployment", "deployment", deploy.Name)
log.V(1).Info("CA certificate volume already exists, skipping", "deployment", deploy.Name, "volume", volumeName)
foundVol = true
return nil
}
Expand Down
32 changes: 17 additions & 15 deletions internal/controller/certMgr_Controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import (
"context"
"fmt"
"time"

certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
Expand All @@ -33,7 +32,7 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// AutomtlsReconciler reconciles a Automtls object

Check failure on line 35 in internal/controller/certMgr_Controller.go

View workflow job for this annotation

GitHub Actions / build-and-deploy

comment on exported type CertMgrReconciler should be of the form "CertMgrReconciler ..." (with optional leading article)
type CertMgrReconciler struct {
client.Client
Scheme *runtime.Scheme
Expand All @@ -53,9 +52,9 @@
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/reconcile
func (r *CertMgrReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := logf.FromContext(ctx)
log := logf.FromContext(ctx).WithName("cert-mgr")

log.Info("Reconciling Cert Mgr Infra")
log.Info("Starting certificate manager infrastructure reconciliation")

if err := createSelfSignedIssuer(ctx, r.Client); err != nil {
return ctrl.Result{}, err
Expand All @@ -74,14 +73,14 @@
}

func createSelfSignedIssuer(ctx context.Context, c client.Client) error {

log := logf.FromContext(ctx)
selfSignedIssuer := "auto-mtls-cluster-selfsigned-issuer"

// Check if it already exists
existing := &certmanagerv1.ClusterIssuer{}
err := c.Get(ctx, client.ObjectKey{Name: selfSignedIssuer}, existing)
if err == nil {
ctrl.Log.Info("SelfSigned Issuer already exists, skipping creation", "name", selfSignedIssuer)
log.Info("Self-signed issuer already exists, skipping creation", "issuer", selfSignedIssuer)
return nil
}

Expand All @@ -103,16 +102,17 @@

// Create if not exists
if err := c.Create(ctx, clusterIssuer); err != nil {
ctrl.Log.Info("Failed to create SelfSigned Issuer as its already available", "name", clusterIssuer.Name)
log.Error(err, "Failed to create self-signed issuer", "issuer", clusterIssuer.Name)
return err
}

ctrl.Log.Info("SelfSigned Issuer created successfully", "name", clusterIssuer.Name)
log.Info("Self-signed issuer created successfully", "issuer", clusterIssuer.Name)
return nil

}

func createCACert(ctx context.Context, c client.Client) error {
log := logf.FromContext(ctx)
caCertName := "auto-mtls-cluster-ca-cert"
caCertNamespace := "cert-manager"
caCertSecret := "auto-mtls-cluster-ca-cert-secret"
Expand All @@ -122,7 +122,7 @@
// Check if it already exists
err := c.Get(ctx, client.ObjectKey{Name: caCertName, Namespace: caCertNamespace}, existing)
if err == nil {
ctrl.Log.Info("ClusterIssuer already exists, skipping creation", "name", caCertName)
log.Info("CA certificate already exists, skipping creation", "certificate", caCertName, "namespace", caCertNamespace)
return nil
}

Expand All @@ -144,21 +144,22 @@
}

if err := c.Create(ctx, caCert); err != nil {
ctrl.Log.Error(err, "Failed to create CA Certificate", "name", caCert.Name)
log.Error(err, "Failed to create CA certificate", "certificate", caCert.Name, "namespace", caCert.Namespace)
return err
}
log.Info("CA certificate created successfully", "certificate", caCert.Name, "namespace", caCert.Namespace)
return nil
}

func createClusterCAIssuer(ctx context.Context, c client.Client) error {

log := logf.FromContext(ctx)
caIssuer := "auto-mtls-cluster-ca-issuer"

// Check if it already exists
existing := &certmanagerv1.ClusterIssuer{}
err := c.Get(ctx, client.ObjectKey{Name: caIssuer}, existing)
if err == nil {
ctrl.Log.Info("ClusterIssuer already exists, skipping creation", "name", caIssuer)
log.Info("CA cluster issuer already exists, skipping creation", "issuer", caIssuer)
return nil
}

Expand All @@ -182,11 +183,11 @@

// Create if not exists
if err := c.Create(ctx, clusterIssuer); err != nil {
ctrl.Log.Error(err, "Failed to create CA ClusterIssuer", "name", clusterIssuer.Name)
log.Error(err, "Failed to create CA cluster issuer", "issuer", clusterIssuer.Name)
return err
}

ctrl.Log.Info("CA ClusterIssuer created successfully", "name", clusterIssuer.Name)
log.Info("CA cluster issuer created successfully", "issuer", clusterIssuer.Name)
return nil

}
Expand All @@ -200,10 +201,11 @@
for {
select {
case <-ticker.C:
fmt.Println("Periodic run of CertMgrReconciler...")
log := logf.FromContext(ctx)
log.V(1).Info("Running periodic certificate manager reconciliation")
// Call your existing Reconcile logic
if _, err := r.Reconcile(ctx, ctrl.Request{}); err != nil {
fmt.Println("Error in periodic reconcile:", err)
log.Error(err, "Error in periodic certificate manager reconciliation")
}
case <-ctx.Done():
return nil
Expand Down
Loading
Loading