diff --git a/internal/generator/deployment.go b/internal/generator/deployment.go index 51e2697..ac01c71 100644 --- a/internal/generator/deployment.go +++ b/internal/generator/deployment.go @@ -309,21 +309,21 @@ func (d *Deployment) dependsOnLegacy(to *Deployment, servicename string) error { func (d *Deployment) dependsOnK8sAPI(to *Deployment) error { script := `NAMESPACE=${NAMESPACE:-default} -SERVICE=%s +DEPLOYMENT_NAME=%s KUBERNETES_SERVICE_HOST=${KUBERNETES_SERVICE_HOST:-kubernetes.default.svc} KUBERNETES_SERVICE_PORT=${KUBERNETES_SERVICE_PORT:-443} -until wget -q -O- --header="Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ +until curl -s -o- --header="Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ --cacert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ - "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/endpoints/${SERVICE}" \ - | grep -q '"ready":.*true'; do + "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/apis/apps/v1/namespaces/${NAMESPACE}/deployments/${DEPLOYMENT_NAME}" \ + | grep -q '"readyReplicas":\s*[1-9][0-9]*'; do sleep 2 done` command := []string{shCommand, "-c", fmt.Sprintf(script, to.Name)} d.Spec.Template.Spec.InitContainers = append(d.Spec.Template.Spec.InitContainers, corev1.Container{ Name: "wait-for-" + to.service.Name, - Image: "busybox:latest", + Image: "quay.io/curl/curl:latest", Command: command, Env: []corev1.EnvVar{ { diff --git a/internal/generator/deployment_test.go b/internal/generator/deployment_test.go index 7dbd146..c94981c 100644 --- a/internal/generator/deployment_test.go +++ b/internal/generator/deployment_test.go @@ -146,21 +146,25 @@ services: } initContainer := dt.Spec.Template.Spec.InitContainers[0] - if !strings.Contains(initContainer.Image, "busybox") { - t.Errorf("Expected busybox image, got %s", initContainer.Image) + if !strings.Contains(initContainer.Image, "quay.io/curl/curl") { + t.Errorf("Expected quay.io/curl/curl image, got %s", initContainer.Image) } fullCommand := strings.Join(initContainer.Command, " ") - if !strings.Contains(fullCommand, "wget") { - t.Errorf("Expected wget command (K8s API method), got %s", fullCommand) + if !strings.Contains(fullCommand, "curl") { + t.Errorf("Expected curl command (K8s API method), got %s", fullCommand) } if !strings.Contains(fullCommand, "/api/v1/namespaces/") { t.Errorf("Expected Kubernetes API call to /api/v1/namespaces/, got %s", fullCommand) } - if !strings.Contains(fullCommand, "/endpoints/") { - t.Errorf("Expected Kubernetes API call to /endpoints/, got %s", fullCommand) + if !strings.Contains(fullCommand, "/deployments/") { + t.Errorf("Expected Kubernetes API call to /deployments/, got %s", fullCommand) + } + + if !strings.Contains(fullCommand, "readyReplicas") { + t.Errorf("Expected readyReplicas check, got %s", fullCommand) } if len(initContainer.Env) == 0 { @@ -718,8 +722,8 @@ services: if !contains(rule.APIGroups, "") { t.Error("Expected APIGroup to include core API ('')") } - if !contains(rule.Resources, "endpoints") { - t.Errorf("Expected Resource to include 'endpoints', got %v", rule.Resources) + if !contains(rule.Resources, "deployments") { + t.Errorf("Expected Resource to include 'deployments', got %v", rule.Resources) } for _, res := range rule.Resources { @@ -800,14 +804,17 @@ services: } fullCommand := strings.Join(initContainer.Command, " ") - if !strings.Contains(fullCommand, "wget") { - t.Error("Expected init container to use wget for K8s API calls") + if !strings.Contains(fullCommand, "curl") { + t.Error("Expected init container to use curl for K8s API calls") } if !strings.Contains(fullCommand, "/api/v1/namespaces/") { t.Error("Expected init container to call /api/v1/namespaces/ endpoint") } - if !strings.Contains(fullCommand, "/endpoints/") { - t.Error("Expected init container to access /endpoints/ resource") + if !strings.Contains(fullCommand, "/deployments/") { + t.Error("Expected init container to access /deployments/ resource") + } + if !strings.Contains(fullCommand, "readyReplicas") { + t.Error("Expected init container to check readyReplicas") } hasNamespace := false diff --git a/internal/generator/labels/katenaryLabelsDoc.yaml b/internal/generator/labels/katenaryLabelsDoc.yaml index d30cbaa..f1a3742 100644 --- a/internal/generator/labels/katenaryLabelsDoc.yaml +++ b/internal/generator/labels/katenaryLabelsDoc.yaml @@ -366,9 +366,9 @@ When a service uses `depends_on`, Katenary creates an initContainer to wait for the dependent service to be ready. - By default, Katenary uses the Kubernetes API to check if the service endpoint - has ready addresses. This method does not require the service to expose a port - and does not create a Kubernetes Service automatically. + By default, Katenary uses the Kubernetes API to check if the deployment's + `readyReplicas` status is greater than 0. This method does not require the + service to expose a port and does not create a Kubernetes Service automatically. If you need to create a Kubernetes Service for external access, use the `katenary.v3/ports` label instead. diff --git a/internal/generator/rbac.go b/internal/generator/rbac.go index 36b088c..8be8f8c 100644 --- a/internal/generator/rbac.go +++ b/internal/generator/rbac.go @@ -137,7 +137,7 @@ func NewServiceAccount(service types.ServiceConfig, appName string) *ServiceAcco APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: utils.TplName(service.Name, appName), + Name: utils.TplName(service.Name, appName, "dependency"), Labels: GetLabels(service.Name, appName), Annotations: Annotations, }, @@ -161,9 +161,9 @@ func NewRestrictedRole(service types.ServiceConfig, appName string) *Role { }, Rules: []rbacv1.PolicyRule{ { - APIGroups: []string{""}, - Resources: []string{"endpoints"}, - Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"apps"}, + Resources: []string{"deployments"}, + Verbs: []string{"get"}, }, }, },