Change health check from WorkloadReference to CrossNamespaceObjectReference
This commit is contained in:
parent
d711b699bb
commit
ea627e3448
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -54,7 +53,7 @@ type KustomizationSpec struct {
|
||||||
// A list of workloads (Deployments, DaemonSets and StatefulSets)
|
// A list of workloads (Deployments, DaemonSets and StatefulSets)
|
||||||
// to be included in the health assessment.
|
// to be included in the health assessment.
|
||||||
// +optional
|
// +optional
|
||||||
HealthChecks []WorkloadReference `json:"healthChecks,omitempty"`
|
HealthChecks []CrossNamespaceObjectReference `json:"healthChecks,omitempty"`
|
||||||
|
|
||||||
// The Kubernetes service account used for applying the kustomization.
|
// The Kubernetes service account used for applying the kustomization.
|
||||||
// +optional
|
// +optional
|
||||||
|
@ -81,25 +80,6 @@ type KustomizationSpec struct {
|
||||||
Validation string `json:"validation,omitempty"`
|
Validation string `json:"validation,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorkloadReference defines a reference to a Deployment, DaemonSet or StatefulSet.
|
|
||||||
type WorkloadReference struct {
|
|
||||||
// GroupKind is the type of resource being referenced.
|
|
||||||
// +required
|
|
||||||
GroupKind metav1.GroupKind `json:"groupKind"`
|
|
||||||
|
|
||||||
// Name is the name of resource being referenced.
|
|
||||||
// +required
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Namespace is the namespace of resource being referenced.
|
|
||||||
// +required
|
|
||||||
Namespace string `json:"namespace"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WorkloadReference) String() string {
|
|
||||||
return fmt.Sprintf("%s/%s/%s", w.GroupKind.String(), w.Namespace, w.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceAccount defines a reference to a Kubernetes service account.
|
// ServiceAccount defines a reference to a Kubernetes service account.
|
||||||
type ServiceAccount struct {
|
type ServiceAccount struct {
|
||||||
// Name is the name of the service account being referenced.
|
// Name is the name of the service account being referenced.
|
||||||
|
|
|
@ -24,7 +24,6 @@ type CrossNamespaceObjectReference struct {
|
||||||
APIVersion string `json:"apiVersion,omitempty"`
|
APIVersion string `json:"apiVersion,omitempty"`
|
||||||
|
|
||||||
// Kind of the referent
|
// Kind of the referent
|
||||||
// +kubebuilder:validation:Enum=GitRepository
|
|
||||||
// +required
|
// +required
|
||||||
Kind string `json:"kind"`
|
Kind string `json:"kind"`
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) {
|
||||||
out.Interval = in.Interval
|
out.Interval = in.Interval
|
||||||
if in.HealthChecks != nil {
|
if in.HealthChecks != nil {
|
||||||
in, out := &in.HealthChecks, &out.HealthChecks
|
in, out := &in.HealthChecks, &out.HealthChecks
|
||||||
*out = make([]WorkloadReference, len(*in))
|
*out = make([]CrossNamespaceObjectReference, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
if in.ServiceAccount != nil {
|
if in.ServiceAccount != nil {
|
||||||
|
@ -263,19 +263,3 @@ func (in *SnapshotEntry) DeepCopy() *SnapshotEntry {
|
||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *WorkloadReference) DeepCopyInto(out *WorkloadReference) {
|
|
||||||
*out = *in
|
|
||||||
out.GroupKind = in.GroupKind
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadReference.
|
|
||||||
func (in *WorkloadReference) DeepCopy() *WorkloadReference {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(WorkloadReference)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
|
@ -79,30 +79,24 @@ spec:
|
||||||
description: A list of workloads (Deployments, DaemonSets and StatefulSets)
|
description: A list of workloads (Deployments, DaemonSets and StatefulSets)
|
||||||
to be included in the health assessment.
|
to be included in the health assessment.
|
||||||
items:
|
items:
|
||||||
description: WorkloadReference defines a reference to a Deployment,
|
description: CrossNamespaceObjectReference contains enough information
|
||||||
DaemonSet or StatefulSet.
|
to let you locate the typed referenced object at cluster level
|
||||||
properties:
|
properties:
|
||||||
groupKind:
|
apiVersion:
|
||||||
description: GroupKind is the type of resource being referenced.
|
description: API version of the referent
|
||||||
properties:
|
type: string
|
||||||
group:
|
kind:
|
||||||
type: string
|
description: Kind of the referent
|
||||||
kind:
|
type: string
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- group
|
|
||||||
- kind
|
|
||||||
type: object
|
|
||||||
name:
|
name:
|
||||||
description: Name is the name of resource being referenced.
|
description: Name of the referent
|
||||||
type: string
|
type: string
|
||||||
namespace:
|
namespace:
|
||||||
description: Namespace is the namespace of resource being referenced.
|
description: Namespace of the referent
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- groupKind
|
- kind
|
||||||
- name
|
- name
|
||||||
- namespace
|
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
interval:
|
interval:
|
||||||
|
@ -139,8 +133,6 @@ spec:
|
||||||
type: string
|
type: string
|
||||||
kind:
|
kind:
|
||||||
description: Kind of the referent
|
description: Kind of the referent
|
||||||
enum:
|
|
||||||
- GitRepository
|
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
description: Name of the referent
|
description: Name of the referent
|
||||||
|
|
|
@ -621,25 +621,34 @@ func (r *KustomizationReconciler) prune(kustomization kustomizev1.Kustomization,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toObjMetadata(wr []kustomizev1.WorkloadReference) []object.ObjMetadata {
|
func toObjMetadata(cr []kustomizev1.CrossNamespaceObjectReference) ([]object.ObjMetadata, error) {
|
||||||
oo := []object.ObjMetadata{}
|
oo := []object.ObjMetadata{}
|
||||||
for _, w := range wr {
|
for _, c := range cr {
|
||||||
oo = append(oo, object.ObjMetadata{
|
// For backwards compatibility
|
||||||
Name: w.Name,
|
if c.APIVersion == "" {
|
||||||
Namespace: w.Namespace,
|
c.APIVersion = "apps/v1"
|
||||||
GroupKind: schema.GroupKind{
|
}
|
||||||
Group: w.GroupKind.Group,
|
|
||||||
Kind: w.GroupKind.Kind,
|
gv, err := schema.ParseGroupVersion(c.APIVersion)
|
||||||
},
|
if err != nil {
|
||||||
})
|
return []object.ObjMetadata{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gk := schema.GroupKind{Group: gv.Group, Kind: c.Kind}
|
||||||
|
o, err := object.CreateObjMetadata(c.Namespace, c.Name, gk)
|
||||||
|
if err != nil {
|
||||||
|
return []object.ObjMetadata{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oo = append(oo, o)
|
||||||
}
|
}
|
||||||
return oo
|
return oo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toHealthySet(wr []kustomizev1.WorkloadReference) map[string]bool {
|
func toHealthySet(oo []object.ObjMetadata) map[string]bool {
|
||||||
hs := map[string]bool{}
|
hs := map[string]bool{}
|
||||||
for _, w := range wr {
|
for _, o := range oo {
|
||||||
hs[w.String()] = false
|
hs[o.String()] = false
|
||||||
}
|
}
|
||||||
return hs
|
return hs
|
||||||
}
|
}
|
||||||
|
@ -659,31 +668,35 @@ func (r *KustomizationReconciler) checkHealth(kustomization kustomizev1.Kustomiz
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
objMetadata, err := toObjMetadata(kustomization.Spec.HealthChecks)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
timeout := kustomization.GetTimeout() + (time.Second * 1)
|
timeout := kustomization.GetTimeout() + (time.Second * 1)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
opts := polling.Options{PollInterval: 500 * time.Millisecond, UseCache: true}
|
opts := polling.Options{PollInterval: 500 * time.Millisecond, UseCache: true}
|
||||||
healthySet := toHealthySet(kustomization.Spec.HealthChecks)
|
healthySet := toHealthySet(objMetadata)
|
||||||
eventsChan := r.Poller.Poll(ctx, toObjMetadata(kustomization.Spec.HealthChecks), opts)
|
eventsChan := r.Poller.Poll(ctx, objMetadata, opts)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
notHealthy := filterHealthSet(healthySet, false)
|
notHealthy := filterHealthSet(healthySet, false)
|
||||||
return fmt.Errorf("Health check timeout for [%v]", strings.Join(notHealthy, ", "))
|
return fmt.Errorf("Health check timed out for [%v]", strings.Join(notHealthy, ", "))
|
||||||
case e := <-eventsChan:
|
case e := <-eventsChan:
|
||||||
switch e.EventType {
|
switch e.EventType {
|
||||||
case event.ResourceUpdateEvent:
|
case event.ResourceUpdateEvent:
|
||||||
id := fmt.Sprintf("%s/%s/%s", e.Resource.Identifier.GroupKind.String(), e.Resource.Identifier.Namespace, e.Resource.Identifier.Name)
|
|
||||||
if e.Resource.Status == status.CurrentStatus {
|
if e.Resource.Status == status.CurrentStatus {
|
||||||
healthySet[id] = true
|
healthySet[e.Resource.Identifier.String()] = true
|
||||||
r.Log.WithValues(
|
r.Log.WithValues(
|
||||||
strings.ToLower(kustomization.Kind),
|
strings.ToLower(kustomization.Kind),
|
||||||
fmt.Sprintf("%s/%s", kustomization.GetNamespace(), kustomization.GetName()),
|
fmt.Sprintf("%s/%s", kustomization.GetNamespace(), kustomization.GetName()),
|
||||||
).Info(fmt.Sprintf("Health check passed for %s", id))
|
).Info(fmt.Sprintf("Health check passed for %s", e.Resource.Identifier.String()))
|
||||||
} else {
|
} else {
|
||||||
healthySet[id] = false
|
healthySet[e.Resource.Identifier.String()] = false
|
||||||
}
|
}
|
||||||
case event.ErrorEvent:
|
case event.ErrorEvent:
|
||||||
return e.Error
|
return e.Error
|
||||||
|
|
Loading…
Reference in New Issue