Change kind ref in health checks to group kind

This commit is contained in:
Philip Laine 2020-09-06 20:43:00 +02:00
parent 9c54e2cb30
commit ca80431ef8
6 changed files with 56 additions and 54 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1
import (
"fmt"
"time"
corev1 "k8s.io/api/core/v1"
@ -82,10 +83,9 @@ type KustomizationSpec struct {
// WorkloadReference defines a reference to a Deployment, DaemonSet or StatefulSet.
type WorkloadReference struct {
// Kind is the type of resource being referenced.
// +kubebuilder:validation:Enum=Deployment;DaemonSet;StatefulSet
// GroupKind is the type of resource being referenced.
// +required
Kind string `json:"kind"`
GroupKind metav1.GroupKind `json:"groupKind"`
// Name is the name of resource being referenced.
// +required
@ -96,6 +96,10 @@ type WorkloadReference struct {
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.
type ServiceAccount struct {
// Name is the name of the service account being referenced.

View File

@ -267,6 +267,7 @@ func (in *SnapshotEntry) DeepCopy() *SnapshotEntry {
// 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.

View File

@ -82,13 +82,17 @@ spec:
description: WorkloadReference defines a reference to a Deployment,
DaemonSet or StatefulSet.
properties:
kind:
description: Kind is the type of resource being referenced.
enum:
- Deployment
- DaemonSet
- StatefulSet
type: string
groupKind:
description: GroupKind is the type of resource being referenced.
properties:
group:
type: string
kind:
type: string
required:
- group
- kind
type: object
name:
description: Name is the name of resource being referenced.
type: string
@ -96,7 +100,7 @@ spec:
description: Namespace is the namespace of resource being referenced.
type: string
required:
- kind
- groupKind
- name
- namespace
type: object

View File

@ -621,39 +621,37 @@ func (r *KustomizationReconciler) prune(kustomization kustomizev1.Kustomization,
return nil
}
func toObjMetadata(ww []kustomizev1.WorkloadReference) []object.ObjMetadata {
objects := []object.ObjMetadata{}
for _, w := range ww {
object := object.ObjMetadata{
GroupKind: schema.GroupKind{
Group: "apps",
Kind: w.Kind,
},
func toObjMetadata(wr []kustomizev1.WorkloadReference) []object.ObjMetadata {
oo := []object.ObjMetadata{}
for _, w := range wr {
oo = append(oo, object.ObjMetadata{
Name: w.Name,
Namespace: w.Namespace,
}
objects = append(objects, object)
GroupKind: schema.GroupKind{
Group: w.GroupKind.Group,
Kind: w.GroupKind.Kind,
},
})
}
return objects
return oo
}
func toCompleteCheck(oo []object.ObjMetadata) map[string]bool {
check := map[string]bool{}
for _, o := range oo {
check[o.String()] = false
func toHealthySet(wr []kustomizev1.WorkloadReference) map[string]bool {
hs := map[string]bool{}
for _, w := range wr {
hs[w.String()] = false
}
return check
return hs
}
func hasCompleted(cc map[string]bool) bool {
for _, v := range cc {
if v == false {
return false
func filterHealthSet(hs map[string]bool, healthy bool) []string {
res := []string{}
for k, v := range hs {
if v == healthy {
res = append(res, k)
}
}
return true
return res
}
func (r *KustomizationReconciler) checkHealth(kustomization kustomizev1.Kustomization, revision string) error {
@ -666,31 +664,26 @@ func (r *KustomizationReconciler) checkHealth(kustomization kustomizev1.Kustomiz
defer cancel()
opts := polling.Options{PollInterval: 500 * time.Millisecond, UseCache: true}
objMetadata := toObjMetadata(kustomization.Spec.HealthChecks)
completeCheck := toCompleteCheck(objMetadata)
eventsChan := r.Poller.Poll(ctx, objMetadata, opts)
healthySet := toHealthySet(kustomization.Spec.HealthChecks)
eventsChan := r.Poller.Poll(ctx, toObjMetadata(kustomization.Spec.HealthChecks), opts)
var alerts string
for {
select {
case <-ctx.Done():
return errors.New("health check timeout")
notHealthy := filterHealthSet(healthySet, false)
return fmt.Errorf("Health check timeout for [%v]", strings.Join(notHealthy, ", "))
case e := <-eventsChan:
switch e.EventType {
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 {
completeCheck[e.Resource.Identifier.String()] = true
msg := fmt.Sprintf("Health check passed for %s '%s/%s'",
e.Resource.Identifier.GroupKind.String(),
e.Resource.Identifier.Namespace,
e.Resource.Identifier.Name)
healthySet[id] = true
r.Log.WithValues(
strings.ToLower(kustomization.Kind),
fmt.Sprintf("%s/%s", kustomization.GetNamespace(), kustomization.GetName()),
).Info(msg)
alerts += msg + "\n"
).Info(fmt.Sprintf("Health check passed for %s", id))
} else {
completeCheck[e.Resource.Identifier.String()] = false
healthySet[id] = false
}
case event.ErrorEvent:
return e.Error
@ -703,9 +696,10 @@ func (r *KustomizationReconciler) checkHealth(kustomization kustomizev1.Kustomiz
return nil*/
}
if hasCompleted(completeCheck) {
if alerts != "" && kustomization.Status.LastAppliedRevision != revision {
r.event(kustomization, revision, recorder.EventSeverityInfo, alerts)
if len(filterHealthSet(healthySet, false)) == 0 {
if kustomization.Status.LastAppliedRevision != revision {
healthy := filterHealthSet(healthySet, true)
r.event(kustomization, revision, recorder.EventSeverityInfo, "Health check passed for "+strings.Join(healthy, ", "))
}
return nil
}

2
go.mod
View File

@ -25,7 +25,7 @@ require (
k8s.io/apimachinery v0.18.8
k8s.io/cli-runtime v0.18.8 // indirect
k8s.io/client-go v0.18.8
sigs.k8s.io/cli-utils v0.18.0
sigs.k8s.io/cli-utils v0.19.2
sigs.k8s.io/controller-runtime v0.6.2
sigs.k8s.io/kustomize/api v0.6.0
sigs.k8s.io/yaml v1.2.0

5
go.sum
View File

@ -973,8 +973,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jC
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
sigs.k8s.io/cli-utils v0.18.0 h1:PPFUhhwKsdMiYYm1DY9lZursNWSAEj8FYgMCZKVvOkQ=
sigs.k8s.io/cli-utils v0.18.0/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
sigs.k8s.io/cli-utils v0.19.2 h1:BwidWPZ3Qop4RBOl27MU8uN/BSEZPQ8rw1mwsNofXfw=
sigs.k8s.io/cli-utils v0.19.2/go.mod h1:ulIQPERYwkYksNriRknJRbGECDR/ZZROpkiThlXBtB4=
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
sigs.k8s.io/controller-runtime v0.6.2 h1:jkAnfdTYBpFwlmBn3pS5HFO06SfxvnTZ1p5PeEF/zAA=
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
@ -982,7 +982,6 @@ sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbL
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/api v0.6.0 h1:Gj+MH9uEPh7tBHKCGGwA+fHgg9th55StaU+ZT05+8bY=
sigs.k8s.io/kustomize/api v0.6.0/go.mod h1:M7410E0ULUFQlxRskB//n5G0MPwGvs9HG6K8Sf8gw+M=
sigs.k8s.io/kustomize/kyaml v0.6.0/go.mod h1:bEzbO5pN9OvlEeCLvFHo8Pu7SA26Herc2m60UeWZBdI=
sigs.k8s.io/kustomize/kyaml v0.7.1 h1:Ih6SJPvfKYfZaIFWUa2YAyg/0ZSTpA3LFjR/hv7+8ao=
sigs.k8s.io/kustomize/kyaml v0.7.1/go.mod h1:ne3F9JPhW2wrVaLslxBsEe6MQJQ9YK5rUutrdhBWXwI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ=