Skip to content

Commit

Permalink
Add PVC healthcheck to controller (#501) (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
dthomson25 authored Aug 28, 2018
1 parent b54a5a3 commit 4da779c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 7 deletions.
26 changes: 26 additions & 0 deletions util/health/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func GetAppHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) {
health, err = getReplicaSetHealth(obj)
case kube.DaemonSetKind:
health, err = getDaemonSetHealth(obj)
case kube.PersistentVolumeClaimKind:
health, err = getPvcHealth(obj)
default:
health = &appv1.HealthStatus{Status: appv1.HealthStatusHealthy}
}
Expand Down Expand Up @@ -68,6 +70,29 @@ func IsWorse(current, new appv1.HealthStatusCode) bool {
return newIndex > currentIndex
}

func getPvcHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) {
obj, err := kube.ConvertToVersion(obj, "", "v1")
if err != nil {
return nil, err
}
var pvc coreV1.PersistentVolumeClaim
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &pvc)
if err != nil {
return nil, err
}

switch pvc.Status.Phase {
case coreV1.ClaimLost:
return &appv1.HealthStatus{Status: appv1.HealthStatusDegraded}, nil
case coreV1.ClaimPending:
return &appv1.HealthStatus{Status: appv1.HealthStatusProgressing}, nil
case coreV1.ClaimBound:
return &appv1.HealthStatus{Status: appv1.HealthStatusHealthy}, nil
default:
return &appv1.HealthStatus{Status: appv1.HealthStatusUnknown}, nil
}
}

func getIngressHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) {
obj, err := kube.ConvertToVersion(obj, "extensions", "v1beta1")
if err != nil {
Expand Down Expand Up @@ -122,6 +147,7 @@ func getDeploymentHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, e
if err != nil {
return nil, err
}

// Borrowed at kubernetes/kubectl/rollout_status.go https://github.com/kubernetes/kubernetes/blob/5232ad4a00ec93942d0b2c6359ee6cd1201b46bc/pkg/kubectl/rollout_status.go#L80
if deployment.Generation <= deployment.Status.ObservedGeneration {
cond := getDeploymentCondition(deployment.Status, v1.DeploymentProgressing)
Expand Down
24 changes: 24 additions & 0 deletions util/health/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,27 @@ func TestStatefulSetHealth(t *testing.T) {
assert.NotNil(t, health)
assert.Equal(t, appv1.HealthStatusHealthy, health.Status)
}

func TestPvcHealthy(t *testing.T) {
yamlBytes, err := ioutil.ReadFile("./testdata/pvc-bound.yaml")
assert.Nil(t, err)
var obj unstructured.Unstructured
err = yaml.Unmarshal(yamlBytes, &obj)
assert.Nil(t, err)
health, err := GetAppHealth(&obj)
assert.Nil(t, err)
assert.NotNil(t, health)
assert.Equal(t, appv1.HealthStatusHealthy, health.Status)
}

func TestPvcPending(t *testing.T) {
yamlBytes, err := ioutil.ReadFile("./testdata/pvc-pending.yaml")
assert.Nil(t, err)
var obj unstructured.Unstructured
err = yaml.Unmarshal(yamlBytes, &obj)
assert.Nil(t, err)
health, err := GetAppHealth(&obj)
assert.Nil(t, err)
assert.NotNil(t, health)
assert.Equal(t, appv1.HealthStatusProgressing, health.Status)
}
34 changes: 34 additions & 0 deletions util/health/testdata/pvc-bound.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"e57a9040-a984-11e8-836b-c4b301c4d0d1","leaseDurationSeconds":15,"acquireTime":"2018-08-27T23:00:54Z","renewTime":"2018-08-27T23:00:56Z","leaderTransitions":0}'
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"applications.argoproj.io/app-name":"working-pvc"},"name":"testpvc","namespace":"argocd"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"2Gi"}}}}
pv.kubernetes.io/bind-completed: "yes"
pv.kubernetes.io/bound-by-controller: "yes"
volume.beta.kubernetes.io/storage-provisioner: docker.io/hostpath
creationTimestamp: 2018-08-27T23:00:54Z
finalizers:
- kubernetes.io/pvc-protection
labels:
applications.argoproj.io/app-name: working-pvc
name: testpvc
namespace: argocd
resourceVersion: "323170"
selfLink: /api/v1/namespaces/argocd/persistentvolumeclaims/testpvc
uid: 0cedda2c-aa4d-11e8-a271-025000000001
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: hostpath
volumeName: pvc-0cedda2c-aa4d-11e8-a271-025000000001
status:
accessModes:
- ReadWriteOnce
capacity:
storage: 2Gi
phase: Bound
26 changes: 26 additions & 0 deletions util/health/testdata/pvc-pending.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"applications.argoproj.io/app-name":"working-pvc"},"name":"testpvc-2","namespace":"argocd"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"2Gi"}},"storageClassName":"slow"}}
volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/aws-ebs
creationTimestamp: 2018-08-27T23:00:54Z
finalizers:
- kubernetes.io/pvc-protection
labels:
applications.argoproj.io/app-name: working-pvc
name: testpvc-2
namespace: argocd
resourceVersion: "323141"
selfLink: /api/v1/namespaces/argocd/persistentvolumeclaims/testpvc-2
uid: 0cedfc44-aa4d-11e8-a271-025000000001
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: slow
status:
phase: Pending
15 changes: 8 additions & 7 deletions util/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ const (
)

const (
ServiceKind = "Service"
EndpointsKind = "Endpoints"
DeploymentKind = "Deployment"
ReplicaSetKind = "ReplicaSet"
StatefulSetKind = "StatefulSet"
DaemonSetKind = "DaemonSet"
IngressKind = "Ingress"
ServiceKind = "Service"
EndpointsKind = "Endpoints"
DeploymentKind = "Deployment"
ReplicaSetKind = "ReplicaSet"
StatefulSetKind = "StatefulSet"
DaemonSetKind = "DaemonSet"
IngressKind = "Ingress"
PersistentVolumeClaimKind = "PersistentVolumeClaim"
)

const (
Expand Down

0 comments on commit 4da779c

Please sign in to comment.