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
13 changes: 4 additions & 9 deletions api/v1/clusterobjectset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,19 +664,14 @@ type ObjectStatus struct {
// +optional
Group string `json:"group,omitempty"`

// version is the API version of the object. Must be between 1 and
// 63 characters.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +required
Version string `json:"version,omitempty"`

// kind is the kind of the object. Must be between 1 and 63
// resource is the lowercase, plural resource type of the object
// (for example, "pods" or "configmaps"). Must be between 1 and 63
// characters.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:validation:XValidation:rule=`!format.dns1035Label().validate(self).hasValue()`,message="the value must consist of only lowercase alphanumeric characters and hyphens, must start with a letter, and must end with an alphanumeric character."
// +required
Kind string `json:"kind,omitempty"`
Resource string `json:"resource,omitempty"`

// namespace is the namespace of the object. Empty for cluster-scoped
// resources. At most 253 characters (DNS subdomain max).
Expand Down
26 changes: 8 additions & 18 deletions applyconfigurations/api/v1/objectstatus.go

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

7 changes: 2 additions & 5 deletions applyconfigurations/internal/internal.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.22.0
controller-gen.kubebuilder.io/version: v0.23.0
olm.operatorframework.io/generator: experimental
name: clusterobjectsets.olm.operatorframework.io
spec:
Expand Down Expand Up @@ -828,13 +828,6 @@ spec:
resources). At most 253 characters (DNS subdomain max).
maxLength: 253
type: string
kind:
description: |-
kind is the kind of the object. Must be between 1 and 63
characters.
maxLength: 63
minLength: 1
type: string
messages:
description: |-
messages lists the failure reasons for this object. The maximum
Expand All @@ -861,17 +854,22 @@ spec:
resources. At most 253 characters (DNS subdomain max).
maxLength: 253
type: string
version:
resource:
description: |-
version is the API version of the object. Must be between 1 and
63 characters.
resource is the lowercase, plural resource type of the object
(for example, "pods" or "configmaps"). Must be between 1 and 63
characters.
maxLength: 63
minLength: 1
type: string
x-kubernetes-validations:
- message: the value must consist of only lowercase alphanumeric
characters and hyphens, must start with a letter,
and must end with an alphanumeric character.
rule: '!format.dns1035Label().validate(self).hasValue()'
required:
- kind
- name
- version
- resource
type: object
maxItems: 50
type: array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (c *ClusterObjectSetReconciler) reconcile(ctx context.Context, cos *ocv1.Cl
reconcileTime := metav1.NewTime(c.Clock.Now())
// Set object counts and phase status
// TODO: refactor and move condition setting operations into status pkg
status.UpdateObservedPhasesForReconcile(cos, rres, reconcileTime)
status.UpdateObservedPhasesForReconcile(c.Client.RESTMapper(), cos, rres, reconcileTime)

// Report revision-level preflight validation failures and re-check on a flat timer:
// the dry-run can be rejected for reasons that clear without a spec change (e.g. RBAC
Expand Down Expand Up @@ -415,7 +415,7 @@ func (c *ClusterObjectSetReconciler) archive(ctx context.Context, revisionEngine
return ctrl.Result{}, fmt.Errorf("error archiving revision: %v", err)
}
teardownTime := metav1.NewTime(c.Clock.Now())
status.UpdateObservedPhasesForTeardown(cos, tdres, teardownTime)
status.UpdateObservedPhasesForTeardown(c.Client.RESTMapper(), cos, tdres, teardownTime)
if tdres != nil && !tdres.IsComplete() {
markAsArchiving(cos)
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
Expand Down
34 changes: 26 additions & 8 deletions internal/object-controller/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func sumObjectCounts(phases []ocv1.ObservedPhase) ocv1.ObjectCounts {
return counts
}

func UpdateObservedPhasesForReconcile(objSet *ocv1.ClusterObjectSet, rres machinery.RevisionResult, now metav1.Time) {
func UpdateObservedPhasesForReconcile(mapper apimeta.RESTMapper, objSet *ocv1.ClusterObjectSet, rres machinery.RevisionResult, now metav1.Time) {
if objSet == nil || rres == nil {
return
}
Expand Down Expand Up @@ -165,15 +165,15 @@ func UpdateObservedPhasesForReconcile(objSet *ocv1.ClusterObjectSet, rres machin
if obj.IsComplete() || obj.Action() == machinery.ActionProgressed {
continue
}
observedPhase.ObjectDetails = append(observedPhase.ObjectDetails, objectStatus(obj))
observedPhase.ObjectDetails = append(observedPhase.ObjectDetails, objectStatus(mapper, obj))
}
}
updateObservedPhaseStatus(objSet, observedPhase, now)
}
objSet.Status.ObjectCounts = sumObjectCounts(objSet.Status.ObservedPhases)
}

func UpdateObservedPhasesForTeardown(objSet *ocv1.ClusterObjectSet, tres machinery.RevisionTeardownResult, now metav1.Time) {
func UpdateObservedPhasesForTeardown(mapper apimeta.RESTMapper, objSet *ocv1.ClusterObjectSet, tres machinery.RevisionTeardownResult, now metav1.Time) {
if objSet == nil || tres == nil {
return
}
Expand Down Expand Up @@ -207,8 +207,7 @@ func UpdateObservedPhasesForTeardown(objSet *ocv1.ClusterObjectSet, tres machine
for _, ref := range pres.Waiting() {
observedPhase.ObjectDetails = append(observedPhase.ObjectDetails, ocv1.ObjectStatus{
Group: ref.Group,
Version: ref.Version,
Kind: ref.Kind,
Resource: resourceFor(mapper, ref),
Namespace: ref.Namespace,
Name: ref.Name,
Messages: []string{"awaiting deletion"},
Expand Down Expand Up @@ -269,13 +268,32 @@ func HasSupersededObject(pres machinery.PhaseResult) bool {
return false
}

// resourceFor returns the lowercase, plural resource name for ref's GroupVersionKind,
// as required by ObjectStatus.resource. It resolves the resource via the RESTMapper so
// that, e.g., a ConfigMap is reported as "configmaps" rather than the "ConfigMap" kind
// (which would fail the field's dns1035 label validation and cause the status update to
// be rejected). When the type is not yet known to the mapper (for example a CRD applied
// by an earlier phase whose discovery has not propagated), it falls back to the
// lowercased kind, which is still a dns1035-valid identifier for the type.
func resourceFor(mapper apimeta.RESTMapper, ref types.ObjectRef) string {
if mapper != nil {
var versions []string
if ref.Version != "" {
versions = []string{ref.Version}
}
if mapping, err := mapper.RESTMapping(ref.GroupKind(), versions...); err == nil {
return mapping.Resource.Resource
}
}
return strings.ToLower(ref.Kind)
}

// objectStatus returns details describing why obj is not yet complete.
func objectStatus(obj machinery.ObjectResult) ocv1.ObjectStatus {
func objectStatus(mapper apimeta.RESTMapper, obj machinery.ObjectResult) ocv1.ObjectStatus {
ref := types.ToObjectRef(obj.Object())
objStatus := ocv1.ObjectStatus{
Group: ref.Group,
Version: ref.Version,
Kind: ref.Kind,
Resource: resourceFor(mapper, ref),
Namespace: ref.Namespace,
Name: ref.Name,
}
Expand Down
Loading
Loading