diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index a36612b36f3c6..a2387676b9c5d 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -372,7 +372,7 @@ func TestFailedConversion(t *testing.T) { errors.FailOnErr(fixture.Run("", "kubectl", "delete", "apiservice", "v1beta1.metrics.k8s.io")) }() - testEdgeCasesApplicationResources(t, "failed-conversion", HealthStatusHealthy) + testEdgeCasesApplicationResources(t, "failed-conversion", HealthStatusProgressing) } func testEdgeCasesApplicationResources(t *testing.T, appPath string, statusCode HealthStatusCode) { diff --git a/util/health/health.go b/util/health/health.go index 4f746e9b1b793..c505a54b81652 100644 --- a/util/health/health.go +++ b/util/health/health.go @@ -10,6 +10,8 @@ import ( coreV1 "k8s.io/api/core/v1" extv1beta1 "k8s.io/api/extensions/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/kubectl/scheme" @@ -92,6 +94,11 @@ func GetResourceHealth(obj *unstructured.Unstructured, resourceOverrides map[str case "Application": health, err = getApplicationHealth(obj) } + case "apiregistration.k8s.io": + switch gvk.Kind { + case kube.APIServiceKind: + health, err = getAPIServiceHealth(obj) + } case "": switch gvk.Kind { case kube.ServiceKind: @@ -259,8 +266,10 @@ func getDeploymentHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, e func init() { _ = appv1.SchemeBuilder.AddToScheme(scheme.Scheme) - + _ = apiregistrationv1.SchemeBuilder.AddToScheme(scheme.Scheme) + _ = apiregistrationv1beta1.SchemeBuilder.AddToScheme(scheme.Scheme) } + func getApplicationHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { application := &appv1.Application{} err := scheme.Scheme.Convert(obj, application, nil) @@ -528,3 +537,32 @@ func getPodHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { Message: pod.Status.Message, }, nil } + +func getAPIServiceHealth(obj *unstructured.Unstructured) (*appv1.HealthStatus, error) { + apiservice := &apiregistrationv1.APIService{} + err := scheme.Scheme.Convert(obj, apiservice, nil) + if err != nil { + return nil, fmt.Errorf("failed to convert %T to %T: %v", obj, apiservice, err) + } + + for _, c := range apiservice.Status.Conditions { + switch c.Type { + case apiregistrationv1.Available: + if c.Status == apiregistrationv1.ConditionTrue { + return &appv1.HealthStatus{ + Status: appv1.HealthStatusHealthy, + Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), + }, nil + } else { + return &appv1.HealthStatus{ + Status: appv1.HealthStatusProgressing, + Message: fmt.Sprintf("%s: %s", c.Reason, c.Message), + }, nil + } + } + } + return &appv1.HealthStatus{ + Status: appv1.HealthStatusProgressing, + Message: "Waiting to be processed", + }, nil +} diff --git a/util/health/health_test.go b/util/health/health_test.go index c956309dea4c7..4b64a3b72db77 100644 --- a/util/health/health_test.go +++ b/util/health/health_test.go @@ -131,5 +131,11 @@ func TestSetApplicationHealth(t *testing.T) { }) assert.NoError(t, err) assert.Equal(t, appv1.HealthStatusHealthy, healthStatus.Status) +} +func TestAPIService(t *testing.T) { + assertAppHealth(t, "./testdata/apiservice-v1-true.yaml", appv1.HealthStatusHealthy) + assertAppHealth(t, "./testdata/apiservice-v1-false.yaml", appv1.HealthStatusProgressing) + assertAppHealth(t, "./testdata/apiservice-v1beta1-true.yaml", appv1.HealthStatusHealthy) + assertAppHealth(t, "./testdata/apiservice-v1beta1-false.yaml", appv1.HealthStatusProgressing) } diff --git a/util/health/testdata/apiservice-v1-false.yaml b/util/health/testdata/apiservice-v1-false.yaml new file mode 100644 index 0000000000000..38401f7f07b70 --- /dev/null +++ b/util/health/testdata/apiservice-v1-false.yaml @@ -0,0 +1,23 @@ +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1beta1.admission.certmanager.k8s.io + labels: + app: webhook + app.kubernetes.io/instance: external-dns +spec: + group: admission.certmanager.k8s.io + groupPriorityMinimum: 1000 + versionPriority: 15 + service: + name: cert-manager-webhook + namespace: external-dns + version: v1beta1 +status: + conditions: + - lastTransitionTime: "2019-06-26T07:17:09Z" + message: endpoints for service/cert-manager-webhook in "external-dns" have no + addresses + reason: MissingEndpoints + status: "False" + type: Available diff --git a/util/health/testdata/apiservice-v1-true.yaml b/util/health/testdata/apiservice-v1-true.yaml new file mode 100644 index 0000000000000..a86309ee78b04 --- /dev/null +++ b/util/health/testdata/apiservice-v1-true.yaml @@ -0,0 +1,22 @@ +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1beta1.admission.certmanager.k8s.io + labels: + app: webhook + app.kubernetes.io/instance: external-dns +spec: + group: admission.certmanager.k8s.io + groupPriorityMinimum: 1000 + versionPriority: 15 + service: + name: cert-manager-webhook + namespace: external-dns + version: v1beta1 +status: + conditions: + - lastTransitionTime: "2019-07-09T14:48:15Z" + message: all checks passed + reason: Passed + status: "True" + type: Available diff --git a/util/health/testdata/apiservice-v1beta1-false.yaml b/util/health/testdata/apiservice-v1beta1-false.yaml new file mode 100644 index 0000000000000..d3e271192cbcb --- /dev/null +++ b/util/health/testdata/apiservice-v1beta1-false.yaml @@ -0,0 +1,23 @@ +apiVersion: apiregistration.k8s.io/v1beta1 +kind: APIService +metadata: + name: v1beta1.admission.certmanager.k8s.io + labels: + app: webhook + app.kubernetes.io/instance: external-dns +spec: + group: admission.certmanager.k8s.io + groupPriorityMinimum: 1000 + versionPriority: 15 + service: + name: cert-manager-webhook + namespace: external-dns + version: v1beta1 +status: + conditions: + - lastTransitionTime: "2019-06-26T07:17:09Z" + message: endpoints for service/cert-manager-webhook in "external-dns" have no + addresses + reason: MissingEndpoints + status: "False" + type: Available diff --git a/util/health/testdata/apiservice-v1beta1-true.yaml b/util/health/testdata/apiservice-v1beta1-true.yaml new file mode 100644 index 0000000000000..d85e52be4cf8f --- /dev/null +++ b/util/health/testdata/apiservice-v1beta1-true.yaml @@ -0,0 +1,22 @@ +apiVersion: apiregistration.k8s.io/v1beta1 +kind: APIService +metadata: + name: v1beta1.admission.certmanager.k8s.io + labels: + app: webhook + app.kubernetes.io/instance: external-dns +spec: + group: admission.certmanager.k8s.io + groupPriorityMinimum: 1000 + versionPriority: 15 + service: + name: cert-manager-webhook + namespace: external-dns + version: v1beta1 +status: + conditions: + - lastTransitionTime: "2019-07-09T14:48:15Z" + message: all checks passed + reason: Passed + status: "True" + type: Available diff --git a/util/kube/kube.go b/util/kube/kube.go index cb1e538283d2e..97407c63e1b91 100644 --- a/util/kube/kube.go +++ b/util/kube/kube.go @@ -47,6 +47,7 @@ const ( PersistentVolumeClaimKind = "PersistentVolumeClaim" CustomResourceDefinitionKind = "CustomResourceDefinition" PodKind = "Pod" + APIServiceKind = "APIService" ) type ResourceKey struct {