Skip to content

Commit ce7845d

Browse files
authored
Add support for multiple classes (#230)
Signed-off-by: Kevin Fox <[email protected]>
1 parent c1bc55a commit ce7845d

11 files changed

+67
-10
lines changed

api/v1alpha1/clusterfederatedtrustdomain_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ type ClusterFederatedTrustDomainSpec struct {
3737
// domain. This field is optional when the resource is created.
3838
// +kubebuilder:validation:Optional
3939
TrustDomainBundle string `json:"trustDomainBundle,omitempty"`
40+
41+
// Set which Controller Class will act on this object
42+
// +kubebuilder:validation:Optional
43+
ClassName string `json:"className,omitempty"`
4044
}
4145

4246
// BundleEndpointProfile is the profile for the federated trust domain

api/v1alpha1/clusterspiffeid_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ type ClusterSPIFFEIDSpec struct {
7777

7878
// AutoPopulateDNSNames indicates whether or not to auto populate service DNS names.
7979
AutoPopulateDNSNames bool `json:"autoPopulateDNSNames,omitempty"`
80+
81+
// Set which Controller Class will act on this object
82+
// +kubebuilder:validation:Optional
83+
ClassName string `json:"className,omitempty"`
8084
}
8185

8286
// ClusterSPIFFEIDStatus defines the observed state of ClusterSPIFFEID

api/v1alpha1/clusterstaticentry_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type ClusterStaticEntrySpec struct {
3535
Hint string `json:"hint,omitempty"`
3636
Admin bool `json:"admin,omitempty"`
3737
Downstream bool `json:"downstream,omitempty"`
38+
ClassName string `json:"className,omitempty"`
3839
}
3940

4041
// ClusterStaticEntryStatus defines the observed state of ClusterStaticEntry

api/v1alpha1/controllermanagerconfig_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ type ControllerManagerConfigurationSpec struct {
105105
// Webhook contains the controllers webhook configuration
106106
// +optional
107107
Webhook ControllerWebhook `json:"webhook,omitempty"`
108+
109+
// ClassName contains the name of a class to watch CRs for. Others will be ignored.
110+
// If unset all will be watched.
111+
// +optional
112+
ClassName string `json:"className,omitempty"`
113+
114+
// If WatchClassless is set and ClassName is set, any CR without a ClassName
115+
// specified will also be handled by this controller.
116+
// +optional
117+
WatchClassless bool `json:"watchClassless,omitempty"`
108118
}
109119

110120
// ControllerConfigurationSpec defines the global configuration for

config/crd/bases/spire.spiffe.io_clusterfederatedtrustdomains.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ spec:
6464
description: BundleEndpointURL is the URL of the bundle endpoint.
6565
It must be an HTTPS URL and cannot contain userinfo (i.e. username/password).
6666
type: string
67+
className:
68+
description: Set the class of controller to handle this object.
69+
type: string
6770
trustDomain:
6871
description: TrustDomain is the name of the trust domain to federate
6972
with (e.g. example.org)

config/crd/bases/spire.spiffe.io_clusterspiffeids.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ spec:
4444
description: AutoPopulateDNSNames indicates whether or not to auto
4545
populate service DNS names.
4646
type: boolean
47+
className:
48+
description: Set the class of controller to handle this object.
49+
type: string
4750
dnsNameTemplates:
4851
description: DNSNameTemplate represents templates for extra DNS names
4952
that are applicable to SVIDs minted for this ClusterSPIFFEID. The

config/crd/bases/spire.spiffe.io_clusterstaticentries.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ spec:
3838
properties:
3939
admin:
4040
type: boolean
41+
className:
42+
description: Set the class of controller to handle this object.
43+
type: string
4144
dnsNames:
4245
items:
4346
type: string

main.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ func parseConfig() (spirev1alpha1.ControllerManagerConfig, ctrl.Options, []*rege
158158
"trust domain", ctrlConfig.TrustDomain,
159159
"ignore namespaces", ctrlConfig.IgnoreNamespaces,
160160
"gc interval", ctrlConfig.GCInterval,
161-
"spire server socket path", ctrlConfig.SPIREServerSocketPath)
161+
"spire server socket path", ctrlConfig.SPIREServerSocketPath,
162+
"class name", ctrlConfig.ClassName,
163+
"handle crs without class name", ctrlConfig.WatchClassless)
162164

163165
switch {
164166
case ctrlConfig.TrustDomain == "":
@@ -266,12 +268,16 @@ func run(ctrlConfig spirev1alpha1.ControllerManagerConfig, options ctrl.Options,
266268
EntryClient: spireClient,
267269
IgnoreNamespaces: ignoreNamespacesRegex,
268270
GCInterval: ctrlConfig.GCInterval,
271+
ClassName: ctrlConfig.ClassName,
272+
WatchClassless: ctrlConfig.WatchClassless,
269273
})
270274

271275
federationRelationshipReconciler := spirefederationrelationship.Reconciler(spirefederationrelationship.ReconcilerConfig{
272276
K8sClient: mgr.GetClient(),
273277
TrustDomainClient: spireClient,
274278
GCInterval: ctrlConfig.GCInterval,
279+
ClassName: ctrlConfig.ClassName,
280+
WatchClassless: ctrlConfig.WatchClassless,
275281
})
276282

277283
if err = (&controllers.ClusterSPIFFEIDReconciler{

pkg/spireentry/reconciler.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ type ReconcilerConfig struct {
5151
K8sClient client.Client
5252
IgnoreNamespaces []*regexp.Regexp
5353
AutoPopulateDNSNames bool
54+
ClassName string
55+
WatchClassless bool
5456

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

195+
func (r *entryReconciler) reconcileClass(className string) bool {
196+
return (className == "" && r.config.WatchClassless) || className == r.config.ClassName
197+
}
198+
193199
func (r *entryReconciler) recalculateUnsupportFields(ctx context.Context, log logr.Logger) {
194200
unsupportedFields, err := r.getUnsupportedFields(ctx)
195201
if err != nil {
@@ -239,9 +245,11 @@ func (r *entryReconciler) listClusterStaticEntries(ctx context.Context) ([]*Clus
239245
}
240246
out := make([]*ClusterStaticEntry, 0, len(clusterStaticEntries))
241247
for _, clusterStaticEntry := range clusterStaticEntries {
242-
out = append(out, &ClusterStaticEntry{
243-
ClusterStaticEntry: clusterStaticEntry,
244-
})
248+
if r.reconcileClass(clusterStaticEntry.Spec.ClassName) {
249+
out = append(out, &ClusterStaticEntry{
250+
ClusterStaticEntry: clusterStaticEntry,
251+
})
252+
}
245253
}
246254
return out, nil
247255
}
@@ -253,9 +261,11 @@ func (r *entryReconciler) listClusterSPIFFEIDs(ctx context.Context) ([]*ClusterS
253261
}
254262
out := make([]*ClusterSPIFFEID, 0, len(clusterSPIFFEIDs))
255263
for _, clusterSPIFFEID := range clusterSPIFFEIDs {
256-
out = append(out, &ClusterSPIFFEID{
257-
ClusterSPIFFEID: clusterSPIFFEID,
258-
})
264+
if r.reconcileClass(clusterSPIFFEID.Spec.ClassName) {
265+
out = append(out, &ClusterSPIFFEID{
266+
ClusterSPIFFEID: clusterSPIFFEID,
267+
})
268+
}
259269
}
260270
return out, nil
261271
}

pkg/spirefederationrelationship/reconciler.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import (
3434
type ReconcilerConfig struct {
3535
TrustDomainClient spireapi.TrustDomainClient
3636
K8sClient client.Client
37+
ClassName string
38+
WatchClassless bool
3739

3840
// GCInterval how long to sit idle (i.e. untriggered) before doing
3941
// another reconcile.
@@ -44,23 +46,27 @@ func Reconciler(config ReconcilerConfig) reconciler.Reconciler {
4446
return reconciler.New(reconciler.Config{
4547
Kind: "federation relationship",
4648
Reconcile: func(ctx context.Context) {
47-
Reconcile(ctx, config.TrustDomainClient, config.K8sClient)
49+
Reconcile(ctx, config.TrustDomainClient, config.K8sClient, config.ClassName, config.WatchClassless)
4850
},
4951
GCInterval: config.GCInterval,
5052
})
5153
}
5254

53-
func Reconcile(ctx context.Context, trustDomainClient spireapi.TrustDomainClient, k8sClient client.Client) {
55+
func Reconcile(ctx context.Context, trustDomainClient spireapi.TrustDomainClient, k8sClient client.Client, className string, watchClassless bool) {
5456
r := &federationRelationshipReconciler{
5557
trustDomainClient: trustDomainClient,
5658
k8sClient: k8sClient,
59+
className: className,
60+
watchClassless: watchClassless,
5761
}
5862
r.reconcile(ctx)
5963
}
6064

6165
type federationRelationshipReconciler struct {
6266
trustDomainClient spireapi.TrustDomainClient
6367
k8sClient client.Client
68+
className string
69+
watchClassless bool
6470
}
6571

6672
func (r *federationRelationshipReconciler) reconcile(ctx context.Context) {
@@ -110,6 +116,10 @@ func (r *federationRelationshipReconciler) reconcile(ctx context.Context) {
110116
// TODO: Status updates
111117
}
112118

119+
func (r *federationRelationshipReconciler) reconcileClass(className string) bool {
120+
return (className == "" && r.watchClassless) || className == r.className
121+
}
122+
113123
func (r *federationRelationshipReconciler) listFederationRelationships(ctx context.Context) (map[spiffeid.TrustDomain]spireapi.FederationRelationship, error) {
114124
federationRelationships, err := r.trustDomainClient.ListFederationRelationships(ctx)
115125
if err != nil {
@@ -138,6 +148,9 @@ func (r *federationRelationshipReconciler) listClusterFederatedTrustDomains(ctx
138148

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

143156
federationRelationship, err := spirev1alpha1.ParseClusterFederatedTrustDomainSpec(&clusterFederatedTrustDomains[i].Spec)

0 commit comments

Comments
 (0)