fix: Auto-install Istio in e2e tests when missing

- Add InstallIstio() function with auto-detection
- Modify WaitIstioAvailable() to install if istio-system namespace missing
- Improve Istio/istioctl installation checks
- Fix cert-manager "Stdout already set" error

Resolves "istio-system namespace not found" test failures.

Signed-off-by: Yash Pal <yashpal2104@gmail.com>
This commit is contained in:
Yash Pal 2025-09-13 16:34:59 +05:30
parent 1caea0fa25
commit 633c52afd8
3 changed files with 107 additions and 60 deletions

View File

@ -78,22 +78,7 @@ test-e2e: manifests generate fmt vet ## Run the e2e tests. Expected an isolated
echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \
exit 1; \
}
@echo "Installing CertManager..."
@if [ "$(CERT_MANAGER_INSTALL_SKIP)" != "true" ]; then \
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml; \
echo "Waiting for CertManager deployments to be ready..."; \
kubectl wait --for=condition=Available --timeout=300s deployment/cert-manager -n cert-manager; \
kubectl wait --for=condition=Available --timeout=300s deployment/cert-manager-cainjector -n cert-manager; \
kubectl wait --for=condition=Available --timeout=300s deployment/cert-manager-webhook -n cert-manager; \
echo "CertManager is ready!"; \
fi
@echo "Installing Istio..."
@if [ "$(ISTIO_INSTALL_SKIP)" != "true" ]; then \
echo "Istio installation will be handled by the test suite"; \
fi
@if [ "$(PROMETHEUS_INSTALL_SKIP)" != "true" ]; then \
echo "Installing Prometheus (if needed)..."; \
fi
go test ./test/e2e/ -v -ginkgo.v
.PHONY: lint

View File

@ -94,7 +94,7 @@ var _ = BeforeSuite(func() {
if !skipIstioctlInstall {
By("checking if istioctl is installed already")
isIstioctlAlreadyInstalled = utils.IsIstioInstalled()
isIstioctlAlreadyInstalled = utils.IsIstioctlInstalled()
if !isIstioctlAlreadyInstalled {
_, _ = fmt.Fprintf(GinkgoWriter, "Installing istioctl...\n")
Expect(utils.InstallIstioctl()).To(Succeed(), "Failed to install istioctl")

View File

@ -308,9 +308,74 @@ func InstallIstioMinimalWithIngress(namespace string) error {
return cmd.Run()
}
// TODO:
// InstallIstio installs Istio with default configuration.
func InstallIstio() error {
// First ensure istioctl is available
if !IsIstioctlInstalled() {
fmt.Println("istioctl not found, installing istioctl...")
if err := InstallIstioctl(); err != nil {
return fmt.Errorf("failed to install istioctl: %w", err)
}
// Verify installation
if !IsIstioctlInstalled() {
return fmt.Errorf("istioctl installation failed - binary not available after installation")
}
}
// Check if Istio is already installed
if IsIstioInstalled() {
fmt.Println("Istio is already installed")
return nil
}
// Install Istio with default configuration
fmt.Println("Installing Istio...")
cmd := exec.Command("istioctl", "install",
"--set", "values.defaultRevision=default",
"-y")
if _, err := Run(cmd); err != nil {
return fmt.Errorf("failed to install Istio: %w", err)
}
fmt.Println("Istio installation completed")
return nil
}
// IsIstioctlInstalled checks if istioctl binary is available and working
func IsIstioctlInstalled() bool {
// Check if istioctl binary exists in PATH
if _, err := exec.LookPath("istioctl"); err != nil {
return false
}
// Verify istioctl can run and show version
cmd := exec.Command("istioctl", "version", "--short", "--remote=false")
_, err := Run(cmd)
return err == nil
}
// IsIstioInstalled checks if Istio is installed in the cluster
func IsIstioInstalled() bool {
cmd := exec.Command("istioctl", "version")
// Check if istioctl binary is available first
if !IsIstioctlInstalled() {
return false
}
// Check if istio-system namespace exists
cmd := exec.Command("kubectl", "get", "namespace", "istio-system")
if _, err := Run(cmd); err != nil {
return false
}
// Check if istiod deployment exists and is available
cmd = exec.Command("kubectl", "get", "deployment", "istiod", "-n", "istio-system")
if _, err := Run(cmd); err != nil {
return false
}
// Verify istioctl can communicate with the cluster
cmd = exec.Command("istioctl", "version", "--short")
_, err := Run(cmd)
return err == nil
}
@ -318,10 +383,14 @@ func IsIstioInstalled() bool {
// WaitIstioAvailable waits for Istio to be available and running.
// Returns nil if Istio is ready, or an error if not ready within timeout.
func WaitIstioAvailable() error {
// First check if istio-system namespace exists
// First check if istio-system namespace exists, if not install Istio
cmd := exec.Command("kubectl", "get", "namespace", "istio-system")
if _, err := Run(cmd); err != nil {
return fmt.Errorf("istio-system namespace not found: %w", err)
// Namespace doesn't exist, install Istio
fmt.Println("istio-system namespace not found, installing Istio...")
if err := InstallIstio(); err != nil {
return fmt.Errorf("failed to install Istio: %w", err)
}
}
// Wait for Istio control plane (istiod) pods to be ready
@ -580,51 +649,44 @@ func WaitCertManagerRunning() error {
"--all-namespaces",
"--timeout", "2m",
)
_, err = Run(cmd)
return err
if _, err := Run(cmd); err != nil {
return fmt.Errorf("cert-manager endpoints not ready: %w", err)
}
// First check if cert-manager namespace exists, if not install cert-manager
// cmd := exec.Command("kubectl", "get", "namespace", "cert-manager")
// if _, err := Run(cmd); err != nil {
// // Namespace doesn't exist, install cert-manager
// fmt.Println("cert-manager namespace not found, installing cert-manager...")
// if err := InstallCertManager(); err != nil {
// return fmt.Errorf("failed to install cert-manager: %w", err)
// }
// }
cmd = exec.Command("kubectl", "get", "namespace", "cert-manager")
if _, err := Run(cmd); err != nil {
// Namespace doesn't exist, install cert-manager
fmt.Println("cert-manager namespace not found, installing cert-manager...")
if err := InstallCertManager(); err != nil {
return fmt.Errorf("failed to install cert-manager: %w", err)
}
}
// // Wait for the cert-manager namespace to be ready
// cmd = exec.Command("kubectl", "wait", "--for=condition=Ready", "namespace/cert-manager", "--timeout=300s")
// if _, err := Run(cmd); err != nil {
// return fmt.Errorf("cert-manager namespace not ready: %w", err)
// }
// Wait for each CertManager deployment individually by name (most reliable)
deployments := []string{"cert-manager", "cert-manager-cainjector", "cert-manager-webhook"}
// // Wait for each CertManager deployment individually by name (most reliable)
// deployments := []string{"cert-manager", "cert-manager-cainjector", "cert-manager-webhook"}
for _, deployment := range deployments {
cmd := exec.Command("kubectl", "wait", "deployment", deployment,
"-n", "cert-manager",
"--for", "condition=Available",
"--timeout", "300s")
// for _, deployment := range deployments {
// cmd := exec.Command("kubectl", "wait", "deployment", deployment,
// "-n", "cert-manager",
// "--for", "condition=Available",
// "--timeout", "300s")
if _, err := Run(cmd); err != nil {
return fmt.Errorf("deployment %s not ready: %w", deployment, err)
}
}
// if _, err := Run(cmd); err != nil {
// return fmt.Errorf("deployment %s not ready: %w", deployment, err)
// }
// }
// Wait for the cert-manager webhook to be ready (critical for functionality)
cmd = exec.Command("kubectl", "wait", "pods",
"-n", "cert-manager",
"-l", "app=webhook",
"--for", "condition=Ready",
"--timeout", "300s")
// // Wait for the cert-manager webhook to be ready (critical for functionality)
// cmd = exec.Command("kubectl", "wait", "pods",
// "-n", "cert-manager",
// "-l", "app=webhook",
// "--for", "condition=Ready",
// "--timeout", "300s")
// if _, err := Run(cmd); err != nil {
// return fmt.Errorf("cert-manager webhook pods not ready: %w", err)
// }
// return nil
if _, err := Run(cmd); err != nil {
return fmt.Errorf("cert-manager webhook pods not ready: %w", err)
}
return err
}
// IsCertManagerCRDsInstalled checks if any Cert Manager CRDs are installed