Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mTLS support #1000

Merged
merged 10 commits into from
Feb 13, 2025
35 changes: 31 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
corev1 "k8s.io/api/core/v1"
k8spoliciesv1 "k8s.io/api/policy/v1"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -79,6 +80,7 @@ func main() {
var enableOtelSidecar bool
var openTelemetryClientCertificateSecret string
var openTelemetryCertificateSecret string
var clientCAConfigMapName string

flag.StringVar(&metricsAddr, "metrics-bind-address", ":8088", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
Expand All @@ -105,6 +107,7 @@ func main() {
"always-accept-admission-reviews-on-deployments-namespace",
false,
"Always accept admission reviews targeting the deployments-namespace.")
flag.StringVar(&clientCAConfigMapName, "client-ca-configmap-name", "", "The name of the ConfigMap containing the client CA certificate. If provided, mTLS will be enabled.")

opts := zap.Options{}
opts.BindFlags(flag.CommandLine)
Expand Down Expand Up @@ -134,7 +137,7 @@ func main() {
}()
}

mgr, err := setupManager(deploymentsNamespace, metricsAddr, probeAddr, enableLeaderElection)
mgr, err := setupManager(deploymentsNamespace, metricsAddr, probeAddr, enableLeaderElection, clientCAConfigMapName != "")
if err != nil {
setupLog.Error(err, "unable to start manager")
retcode = 1
Expand All @@ -153,7 +156,14 @@ func main() {
OtelCertificateSecret: openTelemetryCertificateSecret,
OtelClientCertificateSecret: openTelemetryClientCertificateSecret,
}
if err = setupReconcilers(mgr, deploymentsNamespace, webhookServiceName, alwaysAcceptAdmissionReviewsOnDeploymentsNamespace, featureGateAdmissionWebhookMatchConditions, otelConfiguration); err != nil {
if err = setupReconcilers(mgr,
deploymentsNamespace,
webhookServiceName,
alwaysAcceptAdmissionReviewsOnDeploymentsNamespace,
featureGateAdmissionWebhookMatchConditions,
otelConfiguration,
clientCAConfigMapName,
); err != nil {
setupLog.Error(err, "unable to create controllers")
retcode = 1
return
Expand Down Expand Up @@ -181,10 +191,16 @@ func main() {
}
}

func setupManager(deploymentsNamespace string, metricsAddr string, probeAddr string, enableLeaderElection bool) (ctrl.Manager, error) {
func setupManager(deploymentsNamespace string, metricsAddr string, probeAddr string, enableLeaderElection bool, enableMutualTLS bool) (ctrl.Manager, error) {
namespaceSelector := cache.ByObject{
Field: fields.ParseSelectorOrDie("metadata.namespace=" + deploymentsNamespace),
}

clientCAName := ""
if enableMutualTLS {
clientCAName = constants.ClientCACert
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
Expand Down Expand Up @@ -227,6 +243,9 @@ func setupManager(deploymentsNamespace string, metricsAddr string, probeAddr str
&appsv1.Deployment{}: namespaceSelector,
},
},
WebhookServer: webhook.NewServer(webhook.Options{
ClientCAName: clientCAName,
}),
})
return mgr, err
}
Expand All @@ -241,14 +260,22 @@ func setupProbes(mgr ctrl.Manager) error {
return nil
}

func setupReconcilers(mgr ctrl.Manager, deploymentsNamespace, webhookServiceName string, alwaysAcceptAdmissionReviewsOnDeploymentsNamespace, featureGateAdmissionWebhookMatchConditions bool, otelConfiguration controller.TelemetryConfiguration) error {
func setupReconcilers(mgr ctrl.Manager,
deploymentsNamespace,
webhookServiceName string,
alwaysAcceptAdmissionReviewsOnDeploymentsNamespace,
featureGateAdmissionWebhookMatchConditions bool,
otelConfiguration controller.TelemetryConfiguration,
clientCAConfigMapName string,
) error {
if err := (&controller.PolicyServerReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Log: ctrl.Log.WithName("policy-server-reconciler"),
DeploymentsNamespace: deploymentsNamespace,
AlwaysAcceptAdmissionReviewsInDeploymentsNamespace: alwaysAcceptAdmissionReviewsOnDeploymentsNamespace,
TelemetryConfiguration: otelConfiguration,
ClientCAConfigMapName: clientCAConfigMapName,
}).SetupWithManager(mgr); err != nil {
return errors.Join(errors.New("unable to create PolicyServer controller"), err)
}
Expand Down
4 changes: 4 additions & 0 deletions internal/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
PolicyServerPort = 8443
PolicyServerMetricsPortEnvVar = "KUBEWARDEN_POLICY_SERVER_SERVICES_METRICS_PORT"
PolicyServerMetricsPort = 8080
PolicyServerReadinessProbePort = 8081
PolicyServerReadinessProbe = "/readiness"
PolicyServerLogFmtEnvVar = "KUBEWARDEN_LOG_FMT"

Expand Down Expand Up @@ -72,6 +73,9 @@ const (
CARootPrivateKey = "ca.key"
OldCARootCert = "old-ca.crt"

// Client CA ConfigMap.
ClientCACert = "client-ca.crt"
flavio marked this conversation as resolved.
Show resolved Hide resolved

// Certs.
CertExpirationYears = 10
CACertExpiration = 10 * 365 * 24 * time.Hour
Expand Down
2 changes: 0 additions & 2 deletions internal/controller/admissionpolicy_controller_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testing

/*
Copyright 2022.

Expand Down
2 changes: 0 additions & 2 deletions internal/controller/admissionpolicygroup_controller_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testing

/*
Copyright 2022.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testing

/*
Copyright 2022.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testing

/*
Copyright 2022.

Expand Down
2 changes: 2 additions & 0 deletions internal/controller/policyserver_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type PolicyServerReconciler struct {
Scheme *runtime.Scheme
DeploymentsNamespace string
AlwaysAcceptAdmissionReviewsInDeploymentsNamespace bool
ClientCAConfigMapName string
}

// TelemetryConfiguration is a struct that contains the configuration for the
Expand Down Expand Up @@ -261,6 +262,7 @@ func (r *PolicyServerReconciler) enqueueAdmissionPolicyGroup(_ context.Context,
},
}
}

func (r *PolicyServerReconciler) enqueueClusterAdmissionPolicy(_ context.Context, object client.Object) []reconcile.Request {
// The watch will trigger twice per object change; once with the old
// object, and once the new object. We need to be mindful when doing
Expand Down
Loading
Loading