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
2 changes: 1 addition & 1 deletion clm/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func newDeleteCmd() *cobra.Command {
return err
}

if ok, msg, err := reconciler.IsDeletionAllowed(context.TODO(), &release.Inventory); err != nil {
if ok, msg, err := reconciler.IsDeletionAllowed(context.TODO(), &release.Inventory, ownerId); err != nil {
return err
} else if !ok {
return fmt.Errorf(msg)
Expand Down
2 changes: 1 addition & 1 deletion clm/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func isEphmeralError(err error) bool {
}

func formatTimestamp(t time.Time) string {
d := time.Now().Sub(t)
d := time.Since(t)
if d > 24*time.Hour {
return fmt.Sprintf("%dd", d/24*time.Hour)
} else if d > time.Hour {
Expand Down
16 changes: 16 additions & 0 deletions pkg/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ func assertPolicyConfiguration[T Component](component T) (PolicyConfiguration, b
return nil, false
}

// Check if given component or its spec implements TypeConfiguration (and return it).
func assertTypeConfiguration[T Component](component T) (TypeConfiguration, bool) {
if typeConfiguration, ok := Component(component).(TypeConfiguration); ok {
return typeConfiguration, true
}
if typeConfiguration, ok := getSpec(component).(TypeConfiguration); ok {
return typeConfiguration, true
}
return nil, false
}

// Calculate digest of given component, honoring annotations, spec, and references.
func calculateComponentDigest[T Component](component T) string {
digestData := make(map[string]any)
Expand Down Expand Up @@ -218,6 +229,11 @@ func (s *PolicySpec) GetMissingNamespacesPolicy() reconciler.MissingNamespacesPo
return s.MissingNamespacesPolicy
}

// Implement the TypeConfiguration interface.
func (s *TypeSpec) GetAdditionalManagedTypes() []reconciler.TypeInfo {
return s.AdditionalManagedTypes
}

// Check if state is Ready.
func (s *Status) IsReady() bool {
// caveat: this operates only on the status, so it does not check that observedGeneration == generation
Expand Down
3 changes: 3 additions & 0 deletions pkg/component/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,5 +730,8 @@ func (r *Reconciler[T]) getOptionsForComponent(component T) reconciler.Reconcile
options.MissingNamespacesPolicy = &missingNamespacesPolicy
}
}
if typeConfiguration, ok := assertTypeConfiguration(component); ok {
options.AdditionalManagedTypes = typeConfiguration.GetAdditionalManagedTypes()
}
return options
}
3 changes: 2 additions & 1 deletion pkg/component/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ func (t *reconcileTarget[T]) Delete(ctx context.Context, component T) (bool, err

func (t *reconcileTarget[T]) IsDeletionAllowed(ctx context.Context, component T) (bool, string, error) {
// log := log.FromContext(ctx)
ownerId := t.reconcilerId + "/" + component.GetNamespace() + "/" + component.GetName()
status := component.GetStatus()

return t.reconciler.IsDeletionAllowed(ctx, &status.Inventory)
return t.reconciler.IsDeletionAllowed(ctx, &status.Inventory, ownerId)
}
21 changes: 21 additions & 0 deletions pkg/component/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ type PolicyConfiguration interface {
GetMissingNamespacesPolicy() reconciler.MissingNamespacesPolicy
}

// The TypeConfiguration interface is meant to be implemented by compoments (or their spec) which allow
// to specify additional managed types.
type TypeConfiguration interface {
// Get additional managed types; instances of these types are handled differently during
// apply and delete; foreign instances of these types will block deletion of the component.
// The fields of the returned TypeInfo structs can be concrete api groups, kinds,
// or wildcards ("*"); in addition, groups can be specified as a pattern of the form "*.<suffix>"",
// where the wildcard matches one or multiple dns labels.
GetAdditionalManagedTypes() []reconciler.TypeInfo
}

// +kubebuilder:object:generate=true

// Legacy placement spec. Components may include this into their spec.
Expand Down Expand Up @@ -201,6 +212,16 @@ var _ PolicyConfiguration = &PolicySpec{}

// +kubebuilder:object:generate=true

// TypeSpec allows to specify additional managed types, which are not explicitly part of the component's manifests.
// Components providing TypeConfiguration may include this into their spec.
type TypeSpec struct {
AdditionalManagedTypes []reconciler.TypeInfo `json:"additionalManagedTypes,omitempty"`
}

var _ TypeConfiguration = &TypeSpec{}

// +kubebuilder:object:generate=true

// Component Status. Components must include this into their status.
type Status struct {
ObservedGeneration int64 `json:"observedGeneration"`
Expand Down
20 changes: 20 additions & 0 deletions pkg/component/zz_generated.deepcopy.go

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

4 changes: 2 additions & 2 deletions pkg/reconciler/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ func (i *InventoryItem) GetObjectKind() schema.ObjectKind {

// Get inventory item's GroupVersionKind.
func (i InventoryItem) GroupVersionKind() schema.GroupVersionKind {
return schema.GroupVersionKind(i.TypeInfo)
return schema.GroupVersionKind(i.TypeVersionInfo)
}

// Set inventory item's GroupVersionKind.
func (i *InventoryItem) SetGroupVersionKind(gvk schema.GroupVersionKind) {
i.TypeInfo = TypeInfo(gvk)
i.TypeVersionInfo = TypeVersionInfo(gvk)
}

// Get inventory item's namespace.
Expand Down
Loading
Loading