Skip to content

Commit

Permalink
feat: add readiness policies
Browse files Browse the repository at this point in the history
Signed-off-by: Philippe Scorsolini <[email protected]>
  • Loading branch information
phisco committed May 24, 2023
1 parent 8ca9c1e commit c59dc2a
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 5 deletions.
24 changes: 24 additions & 0 deletions apis/object/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,30 @@ type ObjectSpec struct {
// +kubebuilder:default=Default
ManagementPolicy `json:"managementPolicy,omitempty"`
References []Reference `json:"references,omitempty"`
Readiness Readiness `json:"readiness,omitempty"`
}

// ReadinessPolicy defines how the Object's readiness condition should be computed.
type ReadinessPolicy string

const (
// ReadinessPolicySuccessfulCreate means the object is marked as ready when the
// underlying external resource is successfully created.
ReadinessPolicySuccessfulCreate ReadinessPolicy = "SuccessfulCreate"
// ReadinessPolicyDeriveFromObject means the object is marked as ready if and only if the underlying
// external resource is considered ready.
ReadinessPolicyDeriveFromObject ReadinessPolicy = "DeriveFromObject"
)

// Readiness defines how the object's readiness condition should be computed,
// if not specified it will be considered ready as soon as the underlying external
// resource is considered up-to-date.
type Readiness struct {
// Policy defines how the Object's readiness condition should be computed.
// +optional
// +kubebuilder:validation:Enum=SuccessfulCreate;DeriveFromObject
// +kubebuilder:default=SuccessfulCreate
Policy ReadinessPolicy `json:"policy,omitempty"`
}

// ConnectionDetail represents an entry in the connection secret for an Object
Expand Down
16 changes: 16 additions & 0 deletions apis/object/v1alpha1/zz_generated.deepcopy.go

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

42 changes: 37 additions & 5 deletions internal/controller/object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (c *external) Observe(ctx context.Context, mg resource.Managed) (managed.Ex
return managed.ExternalObservation{}, errors.Wrap(err, errGetObject)
}

if err = setObserved(cr, observed); err != nil {
if err = c.setObserved(cr, observed); err != nil {
return managed.ExternalObservation{}, err
}

Expand Down Expand Up @@ -270,7 +270,7 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
return managed.ExternalCreation{}, errors.Wrap(err, errCreateObject)
}

return managed.ExternalCreation{}, setObserved(cr, obj)
return managed.ExternalCreation{}, c.setObserved(cr, obj)
}

func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.ExternalUpdate, error) {
Expand Down Expand Up @@ -299,7 +299,7 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext
return managed.ExternalUpdate{}, errors.Wrap(err, errApplyObject)
}

return managed.ExternalUpdate{}, setObserved(cr, obj)
return managed.ExternalUpdate{}, c.setObserved(cr, obj)
}

func (c *external) Delete(ctx context.Context, mg resource.Managed) error {
Expand Down Expand Up @@ -353,11 +353,41 @@ func getLastApplied(obj *v1alpha1.Object, observed *unstructured.Unstructured) (
return last, nil
}

func setObserved(obj *v1alpha1.Object, observed *unstructured.Unstructured) error {
func (c *external) setObserved(obj *v1alpha1.Object, observed *unstructured.Unstructured) error {
var err error
if obj.Status.AtProvider.Manifest.Raw, err = observed.MarshalJSON(); err != nil {
return errors.Wrap(err, errFailedToMarshalExisting)
}

if err := c.updateConditionFromObserved(obj, observed); err != nil {
return err
}
return nil
}

func (c *external) updateConditionFromObserved(obj *v1alpha1.Object, observed *unstructured.Unstructured) error {
switch obj.Spec.Readiness.Policy {
case v1alpha1.ReadinessPolicyDeriveFromObject:
conditioned := xpv1.ConditionedStatus{}
err := fieldpath.Pave(observed.Object).GetValueInto("status", &conditioned)
if err != nil {
c.logger.Debug("Got error while getting conditions from observed object, setting it as Unavailable", "error", err, "observed", observed)
obj.SetConditions(xpv1.Unavailable())
return nil
}
if status := conditioned.GetCondition(xpv1.TypeReady).Status; status != v1.ConditionTrue {
c.logger.Debug("Observed object is not ready, setting it as Unavailable", "status", status, "observed", observed)
obj.SetConditions(xpv1.Unavailable())
return nil
}
obj.SetConditions(xpv1.Available())
case v1alpha1.ReadinessPolicySuccessfulCreate, "":
// do nothing, will be handled by c.handleLastApplied method
// "" should never happen, but just in case we will treat it as SuccessfulCreate for backward compatibility
default:
// should never happen
return errors.Errorf("unknown readiness policy %q", obj.Spec.Readiness.Policy)
}
return nil
}

Expand Down Expand Up @@ -453,7 +483,9 @@ func (c *external) handleLastApplied(ctx context.Context, obj *v1alpha1.Object,
if isUpToDate {
c.logger.Debug("Up to date!")

obj.Status.SetConditions(xpv1.Available())
if p := obj.Spec.Readiness.Policy; p == v1alpha1.ReadinessPolicySuccessfulCreate || p == "" {
obj.Status.SetConditions(xpv1.Available())
}

cd, err := connectionDetails(ctx, c.client, obj.Spec.ConnectionDetails)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions package/crds/kubernetes.crossplane.io_objects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,20 @@ spec:
required:
- name
type: object
readiness:
description: Readiness defines how the object's readiness condition
should be computed, if not specified it will be considered ready
as soon as the underlying external resource is considered up-to-date.
properties:
policy:
default: SuccessfulCreate
description: Policy defines how the Object's readiness condition
should be computed.
enum:
- SuccessfulCreate
- DeriveFromObject
type: string
type: object
references:
items:
description: Reference refers to an Object or arbitrary Kubernetes
Expand Down

0 comments on commit c59dc2a

Please sign in to comment.