Skip to content

Commit

Permalink
Add Kibana observedGeneration.
Browse files Browse the repository at this point in the history
Update observedGeneration description.
Defer status updates to kibana to ensure status gets updated regardless of reconcilation outcome.
Add common generation steps for e2e tests to use.
  • Loading branch information
naemono committed Feb 23, 2022
1 parent 65999b3 commit 783a536
Show file tree
Hide file tree
Showing 8 changed files with 559 additions and 16 deletions.
9 changes: 9 additions & 0 deletions config/crds/v1/all-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7303,6 +7303,15 @@ spec:
description: MonitoringAssociationStatus is the status of any auto-linking
to monitoring Elasticsearch clusters.
type: object
observedGeneration:
description: ObservedGeneration is the most recent generation observed
for this Kibana instance. It corresponds to the metadata generation,
which is updated on mutation by the API Server. If the generation
observed in status diverges from the generation in metadata, the
Kibana controller has not yet processed the changes contained in
the Kibana specification.
format: int64
type: integer
selector:
description: Selector is the label selector used to find all pods.
type: string
Expand Down
9 changes: 9 additions & 0 deletions config/crds/v1/bases/kibana.k8s.elastic.co_kibanas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7748,6 +7748,15 @@ spec:
description: MonitoringAssociationStatus is the status of any auto-linking
to monitoring Elasticsearch clusters.
type: object
observedGeneration:
description: ObservedGeneration is the most recent generation observed
for this Kibana instance. It corresponds to the metadata generation,
which is updated on mutation by the API Server. If the generation
observed in status diverges from the generation in metadata, the
Kibana controller has not yet processed the changes contained in
the Kibana specification.
format: int64
type: integer
selector:
description: Selector is the label selector used to find all pods.
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7345,6 +7345,15 @@ spec:
description: MonitoringAssociationStatus is the status of any auto-linking
to monitoring Elasticsearch clusters.
type: object
observedGeneration:
description: ObservedGeneration is the most recent generation observed
for this Kibana instance. It corresponds to the metadata generation,
which is updated on mutation by the API Server. If the generation
observed in status diverges from the generation in metadata, the
Kibana controller has not yet processed the changes contained in
the Kibana specification.
format: int64
type: integer
selector:
description: Selector is the label selector used to find all pods.
type: string
Expand Down
10 changes: 10 additions & 0 deletions pkg/apis/kibana/v1/kibana_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,25 @@ type LogsMonitoring struct {
// KibanaStatus defines the observed state of Kibana
type KibanaStatus struct {
commonv1.DeploymentStatus `json:",inline"`

// AssociationStatus is the status of any auto-linking to Elasticsearch clusters.
// This field is deprecated and will be removed in a future release. Use ElasticsearchAssociationStatus instead.
AssociationStatus commonv1.AssociationStatus `json:"associationStatus,omitempty"`

// ElasticsearchAssociationStatus is the status of any auto-linking to Elasticsearch clusters.
ElasticsearchAssociationStatus commonv1.AssociationStatus `json:"elasticsearchAssociationStatus,omitempty"`

// EnterpriseSearchAssociationStatus is the status of any auto-linking to Enterprise Search.
EnterpriseSearchAssociationStatus commonv1.AssociationStatus `json:"enterpriseSearchAssociationStatus,omitempty"`

// MonitoringAssociationStatus is the status of any auto-linking to monitoring Elasticsearch clusters.
MonitoringAssociationStatus commonv1.AssociationStatusMap `json:"monitoringAssociationStatus,omitempty"`

// ObservedGeneration is the most recent generation observed for this Kibana instance.
// It corresponds to the metadata generation, which is updated on mutation by the API Server.
// If the generation observed in status diverges from the generation in metadata, the Kibana
// controller has not yet processed the changes contained in the Kibana specification.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

// IsMarkedForDeletion returns true if the Kibana is going to be deleted
Expand Down
42 changes: 27 additions & 15 deletions pkg/controller/kibana/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ func Add(mgr manager.Manager, params operator.Parameters) error {

// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager, params operator.Parameters) *ReconcileKibana {
client := mgr.GetClient()
return &ReconcileKibana{
Client: client,
Client: mgr.GetClient(),
recorder: mgr.GetEventRecorderFor(controllerName),
dynamicWatches: watches.NewDynamicWatches(),
params: params,
Expand Down Expand Up @@ -162,29 +161,40 @@ func (r *ReconcileKibana) Reconcile(ctx context.Context, request reconcile.Reque
}

func (r *ReconcileKibana) doReconcile(ctx context.Context, request reconcile.Request, kb *kbv1.Kibana) (reconcile.Result, error) {
var (
err error
result reconcile.Result
)
state := NewState(request, kb)

// defer the updating of status to ensure that the status is updated regardless of the outcome of the reconciliation.
defer func() {
statusErr := r.updateStatus(ctx, state)
if statusErr != nil && apierrors.IsConflict(statusErr) {
log.V(1).Info("Conflict while updating status", "namespace", kb.Namespace, "kibana_name", kb.Name)
result = reconcile.Result{Requeue: true}
} else if statusErr != nil {
log.Error(statusErr, "Error while updating status", "namespace", kb.Namespace, "kibana_name", kb.Name)
err = statusErr
}
}()

// Run validation in case the webhook is disabled
if err := r.validate(ctx, kb); err != nil {
return reconcile.Result{}, err
return result, err
}

driver, err := newDriver(r, r.dynamicWatches, r.recorder, kb, r.params.IPFamily)
var driver *driver
driver, err = newDriver(r, r.dynamicWatches, r.recorder, kb, r.params.IPFamily)
if err != nil {
return reconcile.Result{}, tracing.CaptureError(ctx, err)
}

state := NewState(request, kb)
results := driver.Reconcile(ctx, &state, kb, r.params)

// update status
err = r.updateStatus(ctx, state)
if err != nil && apierrors.IsConflict(err) {
log.V(1).Info("Conflict while updating status", "namespace", kb.Namespace, "kibana_name", kb.Name)
return reconcile.Result{Requeue: true}, nil
}

res, err := results.WithError(err).Aggregate()
result, err = results.WithError(err).Aggregate()
k8s.EmitErrorEvent(r.recorder, err, kb, events.EventReconciliationError, "Reconciliation error: %v", err)
return res, err
return result, err
}

func (r *ReconcileKibana) validate(ctx context.Context, kb *kbv1.Kibana) error {
Expand Down Expand Up @@ -240,5 +250,7 @@ type State struct {
// NewState creates a new reconcile state based on the given request and Kibana resource with the resource
// state reset to empty.
func NewState(request reconcile.Request, kb *kbv1.Kibana) State {
return State{Request: request, Kibana: kb, originalKibana: kb.DeepCopy()}
newKibana := kb.DeepCopy()
newKibana.Status.ObservedGeneration = kb.Generation
return State{Request: request, Kibana: newKibana, originalKibana: kb.DeepCopy()}
}
Loading

0 comments on commit 783a536

Please sign in to comment.