diff --git a/lib/kubernetes-deploy/kubernetes_resource/service.rb b/lib/kubernetes-deploy/kubernetes_resource/service.rb index 350efcb97..d95152fea 100644 --- a/lib/kubernetes-deploy/kubernetes_resource/service.rb +++ b/lib/kubernetes-deploy/kubernetes_resource/service.rb @@ -19,6 +19,8 @@ def sync(cache) def status if !exists? "Not found" + elsif requires_publishing? && !published? + "LoadBalancer IP address is not provisioned yet" elsif !requires_endpoints? "Doesn't require any endpoints" elsif selects_some_pods? @@ -30,6 +32,7 @@ def status def deploy_succeeded? return false unless exists? + return published? if requires_publishing? return exists? unless requires_endpoints? # We can't use endpoints if we want the service to be able to fail fast when the pods are down exposes_zero_replica_workload? || selects_some_pods? @@ -89,5 +92,14 @@ def related_replica_count def external_name_svc? @definition["spec"]["type"] == "ExternalName" end + + def requires_publishing? + @definition["spec"]["type"] == "LoadBalancer" + end + + def published? + ingresses = @instance_data.dig('status', 'loadBalancer', 'ingress') + ingresses && ingresses.size > 0 + end end end diff --git a/test/fixtures/for_unit_tests/service_test.yml b/test/fixtures/for_unit_tests/service_test.yml index 427fb542c..915b17190 100644 --- a/test/fixtures/for_unit_tests/service_test.yml +++ b/test/fixtures/for_unit_tests/service_test.yml @@ -200,3 +200,12 @@ spec: containers: - name: app image: busybox +--- +apiVersion: v1 +kind: Service +metadata: + name: standard-lb +spec: + type: LoadBalancer + selector: + type: standard diff --git a/test/unit/kubernetes-deploy/kubernetes_resource/service_test.rb b/test/unit/kubernetes-deploy/kubernetes_resource/service_test.rb index c1e40bcb7..f8d8b185d 100644 --- a/test/unit/kubernetes-deploy/kubernetes_resource/service_test.rb +++ b/test/unit/kubernetes-deploy/kubernetes_resource/service_test.rb @@ -151,6 +151,39 @@ def test_service_finds_deployment_with_different_pod_and_workload_labels assert_equal("Doesn't require any endpoints", svc.status) end + def test_ensures_populated_status_for_load_balancers + svc_def = service_fixture('standard-lb') + svc = build_service(svc_def) + + stub_kind_get("Service", items: [svc_def]) + stub_kind_get("Deployment", items: deployment_fixtures) + stub_kind_get("Pod", items: pod_fixtures) + stub_kind_get("StatefulSet", items: []) + svc.sync(build_resource_cache) + + assert_includes(svc.to_yaml, 'type: LoadBalancer') + assert(svc.exists?) + refute(svc.deploy_succeeded?) + assert_equal("LoadBalancer IP address is not provisioned yet", svc.status) + + svc_def = svc_def.deep_merge('status' => { + 'loadBalancer' => { + 'ingress' => { + 'ip' => '146.148.47.155', + }, + }, + }) + stub_kind_get("Service", items: [svc_def]) + stub_kind_get("Deployment", items: deployment_fixtures) + stub_kind_get("Pod", items: pod_fixtures) + stub_kind_get("StatefulSet", items: []) + svc.sync(build_resource_cache) + + assert(svc.exists?) + assert(svc.deploy_succeeded?) + assert_equal("Selects at least 1 pod", svc.status) + end + private def build_service(definition)