Skip to content
Merged
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
4 changes: 4 additions & 0 deletions api/v1alpha1/clusterfederatedtrustdomain_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ type ClusterFederatedTrustDomainSpec struct {
// domain. This field is optional when the resource is created.
// +kubebuilder:validation:Optional
TrustDomainBundle string `json:"trustDomainBundle,omitempty"`

// Set which Controller Class will act on this object
// +kubebuilder:validation:Optional
ClassName string `json:"className,omitempty"`
}

// BundleEndpointProfile is the profile for the federated trust domain
Expand Down
4 changes: 4 additions & 0 deletions api/v1alpha1/clusterspiffeid_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ type ClusterSPIFFEIDSpec struct {

// AutoPopulateDNSNames indicates whether or not to auto populate service DNS names.
AutoPopulateDNSNames bool `json:"autoPopulateDNSNames,omitempty"`

// Set which Controller Class will act on this object
// +kubebuilder:validation:Optional
ClassName string `json:"className,omitempty"`
}

// ClusterSPIFFEIDStatus defines the observed state of ClusterSPIFFEID
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/clusterstaticentry_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type ClusterStaticEntrySpec struct {
Hint string `json:"hint,omitempty"`
Admin bool `json:"admin,omitempty"`
Downstream bool `json:"downstream,omitempty"`
ClassName string `json:"className,omitempty"`
}

// ClusterStaticEntryStatus defines the observed state of ClusterStaticEntry
Expand Down
10 changes: 10 additions & 0 deletions api/v1alpha1/controllermanagerconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ type ControllerManagerConfigurationSpec struct {
// Webhook contains the controllers webhook configuration
// +optional
Webhook ControllerWebhook `json:"webhook,omitempty"`

// ClassName contains the name of a class to watch CRs for. Others will be ignored.
// If unset all will be watched.
// +optional
ClassName string `json:"className,omitempty"`

// If WatchClassless is set and ClassName is set, any CR without a ClassName
// specified will also be handled by this controller.
// +optional
WatchClassless bool `json:"watchClassless,omitempty"`
}

// ControllerConfigurationSpec defines the global configuration for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ spec:
description: BundleEndpointURL is the URL of the bundle endpoint.
It must be an HTTPS URL and cannot contain userinfo (i.e. username/password).
type: string
className:
description: Set the class of controller to handle this object.
type: string
trustDomain:
description: TrustDomain is the name of the trust domain to federate
with (e.g. example.org)
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/spire.spiffe.io_clusterspiffeids.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ spec:
description: AutoPopulateDNSNames indicates whether or not to auto
populate service DNS names.
type: boolean
className:
description: Set the class of controller to handle this object.
type: string
dnsNameTemplates:
description: DNSNameTemplate represents templates for extra DNS names
that are applicable to SVIDs minted for this ClusterSPIFFEID. The
Expand Down
3 changes: 3 additions & 0 deletions config/crd/bases/spire.spiffe.io_clusterstaticentries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ spec:
properties:
admin:
type: boolean
className:
description: Set the class of controller to handle this object.
type: string
dnsNames:
items:
type: string
Expand Down
8 changes: 7 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ func parseConfig() (spirev1alpha1.ControllerManagerConfig, ctrl.Options, []*rege
"trust domain", ctrlConfig.TrustDomain,
"ignore namespaces", ctrlConfig.IgnoreNamespaces,
"gc interval", ctrlConfig.GCInterval,
"spire server socket path", ctrlConfig.SPIREServerSocketPath)
"spire server socket path", ctrlConfig.SPIREServerSocketPath,
"class name", ctrlConfig.ClassName,
"handle crs without class name", ctrlConfig.WatchClassless)

switch {
case ctrlConfig.TrustDomain == "":
Expand Down Expand Up @@ -266,12 +268,16 @@ func run(ctrlConfig spirev1alpha1.ControllerManagerConfig, options ctrl.Options,
EntryClient: spireClient,
IgnoreNamespaces: ignoreNamespacesRegex,
GCInterval: ctrlConfig.GCInterval,
ClassName: ctrlConfig.ClassName,
WatchClassless: ctrlConfig.WatchClassless,
})

federationRelationshipReconciler := spirefederationrelationship.Reconciler(spirefederationrelationship.ReconcilerConfig{
K8sClient: mgr.GetClient(),
TrustDomainClient: spireClient,
GCInterval: ctrlConfig.GCInterval,
ClassName: ctrlConfig.ClassName,
WatchClassless: ctrlConfig.WatchClassless,
})

if err = (&controllers.ClusterSPIFFEIDReconciler{
Expand Down
22 changes: 16 additions & 6 deletions pkg/spireentry/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type ReconcilerConfig struct {
K8sClient client.Client
IgnoreNamespaces []*regexp.Regexp
AutoPopulateDNSNames bool
ClassName string
WatchClassless bool

// GCInterval how long to sit idle (i.e. untriggered) before doing
// another reconcile.
Expand Down Expand Up @@ -190,6 +192,10 @@ func (r *entryReconciler) reconcile(ctx context.Context) {
}
}

func (r *entryReconciler) reconcileClass(className string) bool {
return (className == "" && r.config.WatchClassless) || className == r.config.ClassName
}

func (r *entryReconciler) recalculateUnsupportFields(ctx context.Context, log logr.Logger) {
unsupportedFields, err := r.getUnsupportedFields(ctx)
if err != nil {
Expand Down Expand Up @@ -239,9 +245,11 @@ func (r *entryReconciler) listClusterStaticEntries(ctx context.Context) ([]*Clus
}
out := make([]*ClusterStaticEntry, 0, len(clusterStaticEntries))
for _, clusterStaticEntry := range clusterStaticEntries {
out = append(out, &ClusterStaticEntry{
ClusterStaticEntry: clusterStaticEntry,
})
if r.reconcileClass(clusterStaticEntry.Spec.ClassName) {
out = append(out, &ClusterStaticEntry{
ClusterStaticEntry: clusterStaticEntry,
})
}
}
return out, nil
}
Expand All @@ -253,9 +261,11 @@ func (r *entryReconciler) listClusterSPIFFEIDs(ctx context.Context) ([]*ClusterS
}
out := make([]*ClusterSPIFFEID, 0, len(clusterSPIFFEIDs))
for _, clusterSPIFFEID := range clusterSPIFFEIDs {
out = append(out, &ClusterSPIFFEID{
ClusterSPIFFEID: clusterSPIFFEID,
})
if r.reconcileClass(clusterSPIFFEID.Spec.ClassName) {
out = append(out, &ClusterSPIFFEID{
ClusterSPIFFEID: clusterSPIFFEID,
})
}
}
return out, nil
}
Expand Down
17 changes: 15 additions & 2 deletions pkg/spirefederationrelationship/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
type ReconcilerConfig struct {
TrustDomainClient spireapi.TrustDomainClient
K8sClient client.Client
ClassName string
WatchClassless bool

// GCInterval how long to sit idle (i.e. untriggered) before doing
// another reconcile.
Expand All @@ -44,23 +46,27 @@ func Reconciler(config ReconcilerConfig) reconciler.Reconciler {
return reconciler.New(reconciler.Config{
Kind: "federation relationship",
Reconcile: func(ctx context.Context) {
Reconcile(ctx, config.TrustDomainClient, config.K8sClient)
Reconcile(ctx, config.TrustDomainClient, config.K8sClient, config.ClassName, config.WatchClassless)
},
GCInterval: config.GCInterval,
})
}

func Reconcile(ctx context.Context, trustDomainClient spireapi.TrustDomainClient, k8sClient client.Client) {
func Reconcile(ctx context.Context, trustDomainClient spireapi.TrustDomainClient, k8sClient client.Client, className string, watchClassless bool) {
r := &federationRelationshipReconciler{
trustDomainClient: trustDomainClient,
k8sClient: k8sClient,
className: className,
watchClassless: watchClassless,
}
r.reconcile(ctx)
}

type federationRelationshipReconciler struct {
trustDomainClient spireapi.TrustDomainClient
k8sClient client.Client
className string
watchClassless bool
}

func (r *federationRelationshipReconciler) reconcile(ctx context.Context) {
Expand Down Expand Up @@ -110,6 +116,10 @@ func (r *federationRelationshipReconciler) reconcile(ctx context.Context) {
// TODO: Status updates
}

func (r *federationRelationshipReconciler) reconcileClass(className string) bool {
return (className == "" && r.watchClassless) || className == r.className
}

func (r *federationRelationshipReconciler) listFederationRelationships(ctx context.Context) (map[spiffeid.TrustDomain]spireapi.FederationRelationship, error) {
federationRelationships, err := r.trustDomainClient.ListFederationRelationships(ctx)
if err != nil {
Expand Down Expand Up @@ -138,6 +148,9 @@ func (r *federationRelationshipReconciler) listClusterFederatedTrustDomains(ctx

out := make(map[spiffeid.TrustDomain]*clusterFederatedTrustDomainState, len(clusterFederatedTrustDomains))
for i := range clusterFederatedTrustDomains {
if !(r.reconcileClass(clusterFederatedTrustDomains[i].Spec.ClassName)) {
continue
}
log := log.WithValues(clusterFederatedTrustDomainLogKey, objectName(&clusterFederatedTrustDomains[i]))

federationRelationship, err := spirev1alpha1.ParseClusterFederatedTrustDomainSpec(&clusterFederatedTrustDomains[i].Spec)
Expand Down
2 changes: 1 addition & 1 deletion pkg/spirefederationrelationship/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func TestReconcile(t *testing.T) {
ctx := log.IntoContext(context.Background(), logrtesting.NewTestLogger(t))

k8sClient := k8stest.NewClientBuilder(t).WithRuntimeObjects(tt.withObjects...).Build()
spirefederationrelationship.Reconcile(ctx, tdc, k8sClient)
spirefederationrelationship.Reconcile(ctx, tdc, k8sClient, "", false)
assert.Equal(t, tt.expectFRs, tdc.getFederationRelationships())
})
}
Expand Down