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

Large diffs are not rendered by default.

66 changes: 36 additions & 30 deletions api/operator/v1alpha1/trustmanager_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ type TrustManagerConfig struct {
// +optional
TrustNamespace string `json:"trustNamespace,omitempty"`

// targetNamespaces limits where trust-manager writes Bundle targets
// (ConfigMaps, and Secrets when secretTargets is enabled).
// When empty or omitted, trust-manager writes targets in all namespaces
// (default behavior).
// When set, Bundle targets are written only in the listed namespaces.
// Trust sources are still read from trustNamespace.
// Removing a namespace from this list does not delete existing target
// ConfigMaps or Secrets in that namespace.
// +listType=set
// +kubebuilder:validation:MinItems:=0
// +kubebuilder:validation:MaxItems:=50
// +kubebuilder:validation:items:MinLength:=1
// +kubebuilder:validation:items:MaxLength:=63
// +kubebuilder:validation:items:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
// +kubebuilder:validation:Optional
// +optional
TargetNamespaces []string `json:"targetNamespaces,omitempty"`

// secretTargets configures whether trust-manager can write trust bundles to Secrets.
// +kubebuilder:validation:Optional
// +optional
Expand All @@ -118,6 +136,17 @@ type TrustManagerConfig struct {
// +optional
FilterExpiredCertificates FilterExpiredCertificatesPolicy `json:"filterExpiredCertificates,omitempty"`

// filterNonCACerts controls whether trust-manager filters out
// non-CA certificates from trust bundles before distributing them.
// When set to "Enabled", only certificates with the X.509 basicConstraints
// CA bit set are included in bundles.
// When set to "Disabled", non-CA certificates are included (default behavior).
// +kubebuilder:default:="Disabled"
// +kubebuilder:validation:Enum:=Enabled;Disabled
// +kubebuilder:validation:Optional
// +optional
FilterNonCACerts FilterNonCACertsPolicy `json:"filterNonCACerts,omitempty"`

// defaultCAPackage configures the default CA package for trust-manager.
// When enabled, the operator will use OpenShift's trusted CA bundle injection mechanism.
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -215,15 +244,13 @@ type TrustManagerControllerConfig struct {
Annotations map[string]string `json:"annotations,omitempty"`
}

// FilterExpiredCertificatesPolicy defines the policy for filtering expired certificates.
// FilterExpiredCertificatesPolicy controls whether expired certificates are filtered from bundles.
// Allowed values are Enabled and Disabled.
type FilterExpiredCertificatesPolicy string

const (
// FilterExpiredCertificatesPolicyEnabled filters out expired certificates from bundles.
FilterExpiredCertificatesPolicyEnabled FilterExpiredCertificatesPolicy = "Enabled"
// FilterExpiredCertificatesPolicyDisabled includes expired certificates in bundles.
FilterExpiredCertificatesPolicyDisabled FilterExpiredCertificatesPolicy = "Disabled"
)
// FilterNonCACertsPolicy controls whether non-CA certificates are filtered from bundles.
// Allowed values are Enabled and Disabled.
type FilterNonCACertsPolicy string

// SecretTargetsPolicy defines the policy for writing trust bundles to Secrets.
type SecretTargetsPolicy string
Expand All @@ -236,36 +263,15 @@ const (
SecretTargetsPolicyCustom SecretTargetsPolicy = "Custom"
)

// DefaultCAPackagePolicy defines the policy for the default CA package feature.
// DefaultCAPackagePolicy controls whether the default CA package feature is enabled.
// Allowed values are Enabled and Disabled.
type DefaultCAPackagePolicy string

const (
// DefaultCAPackagePolicyEnabled enables the default CA package feature.
DefaultCAPackagePolicyEnabled DefaultCAPackagePolicy = "Enabled"
// DefaultCAPackagePolicyDisabled disables the default CA package feature.
DefaultCAPackagePolicyDisabled DefaultCAPackagePolicy = "Disabled"
)

// TrustManagerStatus defines the observed state of TrustManager.
type TrustManagerStatus struct {
// conditions holds information about the current state of the trust-manager deployment.
ConditionalStatus `json:",inline,omitempty"`

// trustManagerImage is the container image (name:tag) used for trust-manager.
TrustManagerImage string `json:"trustManagerImage,omitempty"`

// trustNamespace is the namespace where trust-manager looks for trust sources.
TrustNamespace string `json:"trustNamespace,omitempty"`

// secretTargetsPolicy indicates the current secret targets policy.
// +kubebuilder:validation:Enum:=Disabled;Custom
SecretTargetsPolicy SecretTargetsPolicy `json:"secretTargetsPolicy,omitempty"`

// defaultCAPackagePolicy indicates the current default CA package policy.
// +kubebuilder:validation:Enum:=Enabled;Disabled
DefaultCAPackagePolicy DefaultCAPackagePolicy `json:"defaultCAPackagePolicy,omitempty"`

// filterExpiredCertificatesPolicy indicates the current policy for filtering expired certificates.
// +kubebuilder:validation:Enum:=Enabled;Disabled
FilterExpiredCertificatesPolicy FilterExpiredCertificatesPolicy `json:"filterExpiredCertificatesPolicy,omitempty"`
}
5 changes: 5 additions & 0 deletions api/operator/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 31 additions & 25 deletions bundle/manifests/operator.openshift.io_trustmanagers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,18 @@ spec:
- Enabled
- Disabled
type: string
filterNonCACerts:
default: Disabled
description: |-
filterNonCACerts controls whether trust-manager filters out
non-CA certificates from trust bundles before distributing them.
When set to "Enabled", only certificates with the X.509 basicConstraints
CA bit set are included in bundles.
When set to "Disabled", non-CA certificates are included (default behavior).
enum:
- Enabled
- Disabled
type: string
logFormat:
default: text
description: |-
Expand Down Expand Up @@ -1163,6 +1175,25 @@ spec:
Custom
rule: self.policy == 'Custom' || !has(self.authorizedSecrets)
|| size(self.authorizedSecrets) == 0
targetNamespaces:
description: |-
targetNamespaces limits where trust-manager writes Bundle targets
(ConfigMaps, and Secrets when secretTargets is enabled).
When empty or omitted, trust-manager writes targets in all namespaces
(default behavior).
When set, Bundle targets are written only in the listed namespaces.
Trust sources are still read from trustNamespace.
Removing a namespace from this list does not delete existing target
ConfigMaps or Secrets in that namespace.
items:
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 50
minItems: 0
type: array
x-kubernetes-list-type: set
tolerations:
description: |-
tolerations allows the trust-manager pod to be scheduled on tainted nodes.
Expand Down Expand Up @@ -1290,35 +1321,10 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
defaultCAPackagePolicy:
description: defaultCAPackagePolicy indicates the current default
CA package policy.
enum:
- Enabled
- Disabled
type: string
filterExpiredCertificatesPolicy:
description: filterExpiredCertificatesPolicy indicates the current
policy for filtering expired certificates.
enum:
- Enabled
- Disabled
type: string
secretTargetsPolicy:
description: secretTargetsPolicy indicates the current secret targets
policy.
enum:
- Disabled
- Custom
type: string
trustManagerImage:
description: trustManagerImage is the container image (name:tag) used
for trust-manager.
type: string
trustNamespace:
description: trustNamespace is the namespace where trust-manager looks
for trust sources.
type: string
type: object
required:
- metadata
Expand Down
56 changes: 31 additions & 25 deletions config/crd/bases/operator.openshift.io_trustmanagers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,18 @@ spec:
- Enabled
- Disabled
type: string
filterNonCACerts:
default: Disabled
description: |-
filterNonCACerts controls whether trust-manager filters out
non-CA certificates from trust bundles before distributing them.
When set to "Enabled", only certificates with the X.509 basicConstraints
CA bit set are included in bundles.
When set to "Disabled", non-CA certificates are included (default behavior).
enum:
- Enabled
- Disabled
type: string
logFormat:
default: text
description: |-
Expand Down Expand Up @@ -1163,6 +1175,25 @@ spec:
Custom
rule: self.policy == 'Custom' || !has(self.authorizedSecrets)
|| size(self.authorizedSecrets) == 0
targetNamespaces:
description: |-
targetNamespaces limits where trust-manager writes Bundle targets
(ConfigMaps, and Secrets when secretTargets is enabled).
When empty or omitted, trust-manager writes targets in all namespaces
(default behavior).
When set, Bundle targets are written only in the listed namespaces.
Trust sources are still read from trustNamespace.
Removing a namespace from this list does not delete existing target
ConfigMaps or Secrets in that namespace.
items:
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
maxItems: 50
minItems: 0
type: array
x-kubernetes-list-type: set
tolerations:
description: |-
tolerations allows the trust-manager pod to be scheduled on tainted nodes.
Expand Down Expand Up @@ -1290,35 +1321,10 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
defaultCAPackagePolicy:
description: defaultCAPackagePolicy indicates the current default
CA package policy.
enum:
- Enabled
- Disabled
type: string
filterExpiredCertificatesPolicy:
description: filterExpiredCertificatesPolicy indicates the current
policy for filtering expired certificates.
enum:
- Enabled
- Disabled
type: string
secretTargetsPolicy:
description: secretTargetsPolicy indicates the current secret targets
policy.
enum:
- Disabled
- Custom
type: string
trustManagerImage:
description: trustManagerImage is the container image (name:tag) used
for trust-manager.
type: string
trustNamespace:
description: trustNamespace is the namespace where trust-manager looks
for trust sources.
type: string
type: object
required:
- metadata
Expand Down
18 changes: 9 additions & 9 deletions pkg/controller/trustmanager/configmaps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
}{
{
name: "skips when policy is Disabled",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyDisabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Disabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
},
wantExistsCount: 0,
Expand All @@ -175,7 +175,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "returns error when injection ConfigMap is not found",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
return errTestClient
Expand All @@ -185,7 +185,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "returns error when CA bundle key is missing",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -198,7 +198,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "returns error when CA bundle is empty",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -211,7 +211,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "creates ConfigMap and returns hash when bundle is available",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -229,7 +229,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "skips patch when existing ConfigMap matches desired",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -251,7 +251,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "patches when existing ConfigMap data differs",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -271,7 +271,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "propagates Exists error",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand All @@ -288,7 +288,7 @@ func TestDefaultCAPackageConfigMapReconciliation(t *testing.T) {
},
{
name: "propagates Patch error",
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicyEnabled),
tm: testTrustManager().WithDefaultCAPackage(v1alpha1.DefaultCAPackagePolicy(v1alpha1.Enabled)),
preReq: func(r *Reconciler, m *fakes.FakeCtrlClient) {
m.GetCalls(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
cm := obj.(*corev1.ConfigMap)
Expand Down
5 changes: 5 additions & 0 deletions pkg/controller/trustmanager/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ const (
trustManagerRoleName = trustManagerCommonResourceName
trustManagerRoleBindingName = trustManagerCommonResourceName

// Namespaced RBAC used when targetNamespaces is set. Distinct from
// trustManagerRoleName, which is the trust-namespace source-secret Role.
trustManagerTargetRoleName = trustManagerCommonResourceName + "-target"
trustManagerTargetRoleBindingName = trustManagerCommonResourceName + "-target"

trustManagerLeaderElectionRoleName = trustManagerCommonResourceName + ":leaderelection"
trustManagerLeaderElectionRoleBindingName = trustManagerCommonResourceName + ":leaderelection"

Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/trustmanager/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Reconciler struct {
// +kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates;issuers,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=trust.cert-manager.io,resources=bundles,verbs=get;list;watch
Expand Down
Loading