Skip to content

Commit 1fa2195

Browse files
committed
fixes tests
1 parent 3319a92 commit 1fa2195

File tree

2 files changed

+320
-3
lines changed

2 files changed

+320
-3
lines changed

pkg/resources/istioingress/meshgateway.go

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,34 @@ func (r *Reconciler) meshgateway(log logr.Logger, externalListenerConfig v1beta1
6363
Spec: corev1.PodSpec{
6464
Containers: []corev1.Container{
6565
{
66-
Name: "istio-proxy",
67-
Image: v1beta1.DefaultIstioProxyImage, // Use a standard Istio proxy image
68-
Env: convertEnvVars(ingressConfig.IstioIngressConfig.Envs),
66+
Name: "istio-proxy",
67+
Image: v1beta1.DefaultIstioProxyImage, // Use a standard Istio proxy image
68+
Command: []string{"/usr/local/bin/pilot-agent"},
69+
Args: []string{
70+
"proxy",
71+
"router",
72+
"--domain", fmt.Sprintf("%s.svc.cluster.local", r.KafkaCluster.Namespace),
73+
"--proxyLogLevel=warning",
74+
"--proxyComponentLogLevel=misc:error",
75+
"--log_output_level=default:info",
76+
},
77+
Env: append(convertEnvVars(ingressConfig.IstioIngressConfig.Envs), getIstioProxyEnvVars(meshgatewayName, r.KafkaCluster.Namespace)...),
6978
Resources: *ingressConfig.IstioIngressConfig.GetResources(),
7079
SecurityContext: &corev1.SecurityContext{
7180
RunAsNonRoot: util.BoolPointer(false),
7281
},
82+
Ports: []corev1.ContainerPort{
83+
{
84+
ContainerPort: 15090,
85+
Protocol: corev1.ProtocolTCP,
86+
Name: "http-envoy-prom",
87+
},
88+
{
89+
ContainerPort: 15021,
90+
Protocol: corev1.ProtocolTCP,
91+
Name: "status-port",
92+
},
93+
},
7394
},
7495
},
7596
NodeSelector: ingressConfig.IstioIngressConfig.NodeSelector,
@@ -190,3 +211,98 @@ func convertTolerations(tolerations []*corev1.Toleration) []corev1.Toleration {
190211
}
191212
return result
192213
}
214+
215+
// getIstioProxyEnvVars returns the required environment variables for Istio proxy
216+
func getIstioProxyEnvVars(gatewayName, namespace string) []corev1.EnvVar {
217+
return []corev1.EnvVar{
218+
{
219+
Name: "PILOT_CERT_PROVIDER",
220+
Value: "istiod",
221+
},
222+
{
223+
Name: "CA_ADDR",
224+
Value: "istiod.istio-system.svc:15012",
225+
},
226+
{
227+
Name: "POD_NAME",
228+
ValueFrom: &corev1.EnvVarSource{
229+
FieldRef: &corev1.ObjectFieldSelector{
230+
APIVersion: "v1",
231+
FieldPath: "metadata.name",
232+
},
233+
},
234+
},
235+
{
236+
Name: "POD_NAMESPACE",
237+
ValueFrom: &corev1.EnvVarSource{
238+
FieldRef: &corev1.ObjectFieldSelector{
239+
APIVersion: "v1",
240+
FieldPath: "metadata.namespace",
241+
},
242+
},
243+
},
244+
{
245+
Name: "INSTANCE_IP",
246+
ValueFrom: &corev1.EnvVarSource{
247+
FieldRef: &corev1.ObjectFieldSelector{
248+
APIVersion: "v1",
249+
FieldPath: "status.podIP",
250+
},
251+
},
252+
},
253+
{
254+
Name: "SERVICE_ACCOUNT",
255+
ValueFrom: &corev1.EnvVarSource{
256+
FieldRef: &corev1.ObjectFieldSelector{
257+
APIVersion: "v1",
258+
FieldPath: "spec.serviceAccountName",
259+
},
260+
},
261+
},
262+
{
263+
Name: "HOST_IP",
264+
ValueFrom: &corev1.EnvVarSource{
265+
FieldRef: &corev1.ObjectFieldSelector{
266+
APIVersion: "v1",
267+
FieldPath: "status.hostIP",
268+
},
269+
},
270+
},
271+
{
272+
Name: "PROXY_CONFIG",
273+
Value: "{}",
274+
},
275+
{
276+
Name: "ISTIO_META_POD_PORTS",
277+
Value: `[{"containerPort":15090,"protocol":"TCP","name":"http-envoy-prom"},{"containerPort":15021,"protocol":"TCP","name":"status-port"}]`,
278+
},
279+
{
280+
Name: "ISTIO_META_APP_CONTAINERS",
281+
Value: "istio-proxy",
282+
},
283+
{
284+
Name: "ISTIO_META_CLUSTER_ID",
285+
Value: "Kubernetes",
286+
},
287+
{
288+
Name: "ISTIO_META_INTERCEPTION_MODE",
289+
Value: "REDIRECT",
290+
},
291+
{
292+
Name: "ISTIO_META_WORKLOAD_NAME",
293+
Value: gatewayName,
294+
},
295+
{
296+
Name: "ISTIO_META_OWNER",
297+
Value: fmt.Sprintf("kubernetes://apis/apps/v1/namespaces/%s/deployments/%s", namespace, gatewayName),
298+
},
299+
{
300+
Name: "ISTIO_META_MESH_ID",
301+
Value: "cluster.local",
302+
},
303+
{
304+
Name: "TRUST_DOMAIN",
305+
Value: "cluster.local",
306+
},
307+
}
308+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// Copyright 2025 Adobe. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package istioingress
16+
17+
import (
18+
"testing"
19+
20+
"github.com/go-logr/logr"
21+
appsv1 "k8s.io/api/apps/v1"
22+
corev1 "k8s.io/api/core/v1"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
25+
"github.com/banzaicloud/koperator/api/v1beta1"
26+
"github.com/banzaicloud/koperator/pkg/resources"
27+
)
28+
29+
func TestMeshgatewayContainerConfiguration(t *testing.T) {
30+
// Create a minimal KafkaCluster for testing
31+
kafkaCluster := &v1beta1.KafkaCluster{
32+
ObjectMeta: metav1.ObjectMeta{
33+
Name: "test-kafka",
34+
Namespace: "test-namespace",
35+
},
36+
Spec: v1beta1.KafkaClusterSpec{
37+
Brokers: []v1beta1.Broker{
38+
{Id: 0},
39+
},
40+
},
41+
}
42+
43+
// Create reconciler
44+
reconciler := &Reconciler{
45+
Reconciler: resources.Reconciler{
46+
KafkaCluster: kafkaCluster,
47+
},
48+
}
49+
50+
// Create test external listener config
51+
externalListenerConfig := v1beta1.ExternalListenerConfig{
52+
CommonListenerSpec: v1beta1.CommonListenerSpec{
53+
Type: "plaintext",
54+
Name: "external",
55+
ContainerPort: 9094,
56+
},
57+
ExternalStartingPort: 19090,
58+
}
59+
60+
// Create test ingress config
61+
ingressConfig := v1beta1.IngressConfig{
62+
IstioIngressConfig: &v1beta1.IstioIngressConfig{},
63+
}
64+
65+
// Call the meshgateway function
66+
result := reconciler.meshgateway(
67+
logr.Discard(),
68+
externalListenerConfig,
69+
ingressConfig,
70+
"test-config",
71+
"default-config",
72+
"",
73+
)
74+
75+
// Cast to Deployment
76+
deployment, ok := result.(*appsv1.Deployment)
77+
if !ok {
78+
t.Fatalf("Expected *appsv1.Deployment, got %T", result)
79+
}
80+
81+
// Verify deployment has one container
82+
if len(deployment.Spec.Template.Spec.Containers) != 1 {
83+
t.Fatalf("Expected 1 container, got %d", len(deployment.Spec.Template.Spec.Containers))
84+
}
85+
86+
container := deployment.Spec.Template.Spec.Containers[0]
87+
88+
// Verify container name
89+
if container.Name != "istio-proxy" {
90+
t.Errorf("Expected container name 'istio-proxy', got '%s'", container.Name)
91+
}
92+
93+
// Verify container image
94+
if container.Image != v1beta1.DefaultIstioProxyImage {
95+
t.Errorf("Expected image '%s', got '%s'", v1beta1.DefaultIstioProxyImage, container.Image)
96+
}
97+
98+
// Verify container has command
99+
if len(container.Command) == 0 {
100+
t.Error("Expected container to have command, but it's empty")
101+
} else if container.Command[0] != "/usr/local/bin/pilot-agent" {
102+
t.Errorf("Expected command '/usr/local/bin/pilot-agent', got '%s'", container.Command[0])
103+
}
104+
105+
// Verify container has args
106+
if len(container.Args) == 0 {
107+
t.Error("Expected container to have args, but it's empty")
108+
} else if container.Args[0] != "proxy" {
109+
t.Errorf("Expected first arg 'proxy', got '%s'", container.Args[0])
110+
}
111+
112+
// Verify container has required environment variables
113+
envVarMap := make(map[string]string)
114+
for _, env := range container.Env {
115+
envVarMap[env.Name] = env.Value
116+
}
117+
118+
requiredEnvVars := []string{
119+
"PILOT_CERT_PROVIDER",
120+
"CA_ADDR",
121+
"PROXY_CONFIG",
122+
"ISTIO_META_CLUSTER_ID",
123+
"ISTIO_META_INTERCEPTION_MODE",
124+
"TRUST_DOMAIN",
125+
}
126+
127+
for _, envVar := range requiredEnvVars {
128+
if _, exists := envVarMap[envVar]; !exists {
129+
t.Errorf("Expected environment variable '%s' to be set", envVar)
130+
}
131+
}
132+
133+
// Verify container has required ports
134+
if len(container.Ports) != 2 {
135+
t.Errorf("Expected 2 container ports, got %d", len(container.Ports))
136+
}
137+
138+
portMap := make(map[string]int32)
139+
for _, port := range container.Ports {
140+
portMap[port.Name] = port.ContainerPort
141+
}
142+
143+
if port, exists := portMap["http-envoy-prom"]; !exists || port != 15090 {
144+
t.Errorf("Expected port 'http-envoy-prom' on 15090, got %d", port)
145+
}
146+
147+
if port, exists := portMap["status-port"]; !exists || port != 15021 {
148+
t.Errorf("Expected port 'status-port' on 15021, got %d", port)
149+
}
150+
}
151+
152+
func TestGetIstioProxyEnvVars(t *testing.T) {
153+
gatewayName := "test-gateway"
154+
namespace := "test-namespace"
155+
156+
envVars := getIstioProxyEnvVars(gatewayName, namespace)
157+
158+
// Verify we have environment variables
159+
if len(envVars) == 0 {
160+
t.Fatal("Expected environment variables, got none")
161+
}
162+
163+
// Create a map for easier testing
164+
envVarMap := make(map[string]corev1.EnvVar)
165+
for _, env := range envVars {
166+
envVarMap[env.Name] = env
167+
}
168+
169+
// Test specific environment variables
170+
testCases := []struct {
171+
name string
172+
expectedValue string
173+
}{
174+
{"PILOT_CERT_PROVIDER", "istiod"},
175+
{"CA_ADDR", "istiod.istio-system.svc:15012"},
176+
{"PROXY_CONFIG", "{}"},
177+
{"ISTIO_META_CLUSTER_ID", "Kubernetes"},
178+
{"ISTIO_META_INTERCEPTION_MODE", "REDIRECT"},
179+
{"ISTIO_META_WORKLOAD_NAME", gatewayName},
180+
{"ISTIO_META_MESH_ID", "cluster.local"},
181+
{"TRUST_DOMAIN", "cluster.local"},
182+
}
183+
184+
for _, tc := range testCases {
185+
if env, exists := envVarMap[tc.name]; !exists {
186+
t.Errorf("Expected environment variable '%s' to exist", tc.name)
187+
} else if env.Value != tc.expectedValue {
188+
t.Errorf("Expected '%s' to have value '%s', got '%s'", tc.name, tc.expectedValue, env.Value)
189+
}
190+
}
191+
192+
// Test environment variables with field references
193+
fieldRefVars := []string{"POD_NAME", "POD_NAMESPACE", "INSTANCE_IP", "SERVICE_ACCOUNT", "HOST_IP"}
194+
for _, varName := range fieldRefVars {
195+
if env, exists := envVarMap[varName]; !exists {
196+
t.Errorf("Expected environment variable '%s' to exist", varName)
197+
} else if env.ValueFrom == nil || env.ValueFrom.FieldRef == nil {
198+
t.Errorf("Expected '%s' to have FieldRef, but it doesn't", varName)
199+
}
200+
}
201+
}

0 commit comments

Comments
 (0)