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

Add Fallback flag to ClusterSPIFFEIDs #415

Merged
merged 15 commits into from
Oct 1, 2024
4 changes: 4 additions & 0 deletions api/v1alpha1/clusterspiffeid_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ type ClusterSPIFFEIDSpec struct {
// +kubebuilder:validation:Optional
ClassName string `json:"className,omitempty"`

// Apply this ID only if there are no other matching non fallback ClusterSPIFFEIDs.
// +kubebuilder:validation:Optional
Fallback bool `json:"fallback,omitempty"`

// Set the entry hint
// +kubebuilder:validation:Optional
Hint string `json:"hint,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions config/crd/bases/spire.spiffe.io_clusterspiffeids.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ spec:
className:
description: Set which Controller Class will act on this object
type: string
fallback:
description: |-
Apply this ID only if there are no other matching non fallback
ClusterSPIFFEIDs
type: boolean
dnsNameTemplates:
description: |-
DNSNameTemplate represents templates for extra DNS names that are
Expand Down
1 change: 1 addition & 0 deletions docs/clusterspiffeid-crd.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The definition can be found [here](../api/v1alpha1/clusterspiffeid_types.go).
| `admin` | OPTIONAL | Indicates whether the target workload is an admin workload (i.e. can access SPIRE administrative APIs) |
| `downstream` | OPTIONAL | Indicates that the entry describes a downstream SPIRE server. |
| `autoPopulateDNSNames` | OPTIONAL | Indicates whether or not to auto populate service DNS names. |
| `fallback` | OPTIONAL | Apply this ID only if there are no other matching non fallback ClusterSPIFFEIDs. |

## ClusterSPIFFEIDStatus

Expand Down
18 changes: 18 additions & 0 deletions pkg/spireentry/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"io"
"regexp"
"slices"
"sort"
"strings"
"text/template"
Expand Down Expand Up @@ -358,6 +359,17 @@ func (r *entryReconciler) addClusterStaticEntryEntriesState(ctx context.Context,

func (r *entryReconciler) addClusterSPIFFEIDEntriesState(ctx context.Context, state entriesState, clusterSPIFFEIDs []*ClusterSPIFFEID) {
log := log.FromContext(ctx)
podsWithNonFallbackApplied := make(map[types.UID]struct{})
// Process all the fallback clusterSPIFFEIDs last.
slices.SortStableFunc(clusterSPIFFEIDs, func(x, y *ClusterSPIFFEID) int {
if x.Spec.Fallback == y.Spec.Fallback {
return 0
}
if x.Spec.Fallback {
return 1
}
return -1
})
for _, clusterSPIFFEID := range clusterSPIFFEIDs {
log := log.WithValues(clusterSPIFFEIDLogKey, objectName(clusterSPIFFEID))

Expand Down Expand Up @@ -399,6 +411,9 @@ func (r *entryReconciler) addClusterSPIFFEIDEntriesState(ctx context.Context, st
clusterSPIFFEID.NextStatus.Stats.PodsSelected += len(pods)
for i := range pods {
log := log.WithValues(podLogKey, objectName(&pods[i]))
if _, ok := podsWithNonFallbackApplied[pods[i].UID]; ok && clusterSPIFFEID.Spec.Fallback {
continue
}

entry, err := r.renderPodEntry(ctx, spec, &pods[i])
switch {
Expand All @@ -409,6 +424,9 @@ func (r *entryReconciler) addClusterSPIFFEIDEntriesState(ctx context.Context, st
// renderPodEntry will return a nil entry if requisite k8s
// objects disappeared from underneath.
state.AddDeclared(*entry, clusterSPIFFEID)
if !clusterSPIFFEID.Spec.Fallback {
podsWithNonFallbackApplied[pods[i].UID] = struct{}{}
}
}
}
}
Expand Down