Skip to content

Commit 0fd60cd

Browse files
committed
chore: implemented unit tests for ingress for extensions
Signed-off-by: Ankit152 <[email protected]>
1 parent 5b080db commit 0fd60cd

File tree

5 files changed

+274
-17
lines changed

5 files changed

+274
-17
lines changed

apis/v1beta1/opentelemetrycollector_types.go

+5
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ type OpenTelemetryCollectorSpec struct {
111111
// Valid modes are: deployment, daemonset and statefulset.
112112
// +optional
113113
Ingress Ingress `json:"ingress,omitempty"`
114+
// ExtensionIngress is used to specify how OpenTelemetry Collector is exposed. This
115+
// functionality is only available if one of the valid modes is set.
116+
// Valid modes are: deployment, daemonset and statefulset.
117+
// +optional
118+
ExtensionIngress Ingress `json:"extensionIngress,omitempty"`
114119
// Liveness config for the OpenTelemetry Collector except the probe handler which is auto generated from the health extension of the collector.
115120
// It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline.
116121
// +optional

apis/v1beta1/zz_generated.deepcopy.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/manifests/collector/ingress.go

+37-17
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ func Ingress(params manifests.Params) (*networkingv1.Ingress, error) {
5050
var rules []networkingv1.IngressRule
5151
switch params.OtelCol.Spec.Ingress.RuleType {
5252
case v1beta1.IngressRuleTypePath, "":
53-
rules = []networkingv1.IngressRule{createPathIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports)}
53+
rules = []networkingv1.IngressRule{createPathIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports, "service")}
5454
case v1beta1.IngressRuleTypeSubdomain:
55-
rules = createSubdomainIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports)
55+
rules = createSubdomainIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports, "service")
5656
}
5757

5858
return &networkingv1.Ingress{
@@ -71,48 +71,60 @@ func Ingress(params manifests.Params) (*networkingv1.Ingress, error) {
7171
}
7272

7373
func ExtensionIngress(params manifests.Params) (*networkingv1.Ingress, error) {
74-
name := naming.Ingress(params.OtelCol.Name)
74+
name := naming.ExtensionIngress(params.OtelCol.Name)
7575
labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter())
7676

77-
ports, err := extensionServicePortsFromCfg(params.Log, params.OtelCol)
77+
if params.OtelCol.Spec.ExtensionIngress.Type != v1beta1.IngressTypeIngress {
78+
return nil, nil
79+
}
7880

79-
if err != nil {
81+
ports, err := extensionServicePortsFromCfg(params.Log, params.OtelCol)
82+
if err != nil || len(ports) == 0 {
8083
return nil, err
8184
}
8285

83-
// if there are no ports, no ingress required
84-
if len(ports) == 0 {
85-
return nil, nil
86+
var rules []networkingv1.IngressRule
87+
switch params.OtelCol.Spec.Ingress.RuleType {
88+
case v1beta1.IngressRuleTypePath, "":
89+
rules = []networkingv1.IngressRule{createPathIngressRules(params.OtelCol.Name, params.OtelCol.Spec.ExtensionIngress.Hostname, ports, "extension")}
90+
case v1beta1.IngressRuleTypeSubdomain:
91+
rules = createSubdomainIngressRules(params.OtelCol.Name, params.OtelCol.Spec.ExtensionIngress.Hostname, ports, "extension")
8692
}
8793

88-
rules := createSubdomainIngressRules(name, "", ports)
89-
9094
return &networkingv1.Ingress{
9195
ObjectMeta: metav1.ObjectMeta{
9296
Name: name,
9397
Namespace: params.OtelCol.Namespace,
94-
Annotations: params.OtelCol.Spec.Ingress.Annotations, // can the spec annotations be used?
98+
Annotations: params.OtelCol.Spec.ExtensionIngress.Annotations,
9599
Labels: labels,
96100
},
97101
Spec: networkingv1.IngressSpec{
98-
TLS: params.OtelCol.Spec.Ingress.TLS,
102+
TLS: params.OtelCol.Spec.ExtensionIngress.TLS,
99103
Rules: rules,
100-
IngressClassName: params.OtelCol.Spec.Ingress.IngressClassName,
104+
IngressClassName: params.OtelCol.Spec.ExtensionIngress.IngressClassName,
101105
},
102106
}, nil
103107
}
104108

105-
func createPathIngressRules(otelcol string, hostname string, ports []corev1.ServicePort) networkingv1.IngressRule {
109+
func createPathIngressRules(otelcol string, hostname string, ports []corev1.ServicePort, serviceType string) networkingv1.IngressRule {
106110
pathType := networkingv1.PathTypePrefix
107111
paths := make([]networkingv1.HTTPIngressPath, len(ports))
112+
113+
var name string
114+
if serviceType == "extension" {
115+
name = naming.ExtensionService(otelcol)
116+
} else {
117+
name = naming.Service(otelcol)
118+
}
119+
108120
for i, port := range ports {
109121
portName := naming.PortName(port.Name, port.Port)
110122
paths[i] = networkingv1.HTTPIngressPath{
111123
Path: "/" + port.Name,
112124
PathType: &pathType,
113125
Backend: networkingv1.IngressBackend{
114126
Service: &networkingv1.IngressServiceBackend{
115-
Name: naming.Service(otelcol),
127+
Name: name,
116128
Port: networkingv1.ServiceBackendPort{
117129
Name: portName,
118130
},
@@ -130,9 +142,17 @@ func createPathIngressRules(otelcol string, hostname string, ports []corev1.Serv
130142
}
131143
}
132144

133-
func createSubdomainIngressRules(otelcol string, hostname string, ports []corev1.ServicePort) []networkingv1.IngressRule {
145+
func createSubdomainIngressRules(otelcol string, hostname string, ports []corev1.ServicePort, serviceType string) []networkingv1.IngressRule {
134146
var rules []networkingv1.IngressRule
135147
pathType := networkingv1.PathTypePrefix
148+
149+
var name string
150+
if serviceType == "extension" {
151+
name = naming.ExtensionService(otelcol)
152+
} else {
153+
name = naming.Service(otelcol)
154+
}
155+
136156
for _, port := range ports {
137157
portName := naming.PortName(port.Name, port.Port)
138158

@@ -151,7 +171,7 @@ func createSubdomainIngressRules(otelcol string, hostname string, ports []corev1
151171
PathType: &pathType,
152172
Backend: networkingv1.IngressBackend{
153173
Service: &networkingv1.IngressServiceBackend{
154-
Name: naming.Service(otelcol),
174+
Name: name,
155175
Port: networkingv1.ServiceBackendPort{
156176
Name: portName,
157177
},

internal/manifests/collector/ingress_test.go

+226
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,229 @@ func TestDesiredIngresses(t *testing.T) {
284284
}, got)
285285
})
286286
}
287+
288+
func TestExtensionIngress(t *testing.T) {
289+
t.Run("no ingress for incorrect ingress type", func(t *testing.T) {
290+
params := manifests.Params{
291+
Config: config.Config{},
292+
Log: logger,
293+
OtelCol: v1beta1.OpenTelemetryCollector{
294+
ObjectMeta: metav1.ObjectMeta{
295+
Name: "test",
296+
},
297+
Spec: v1beta1.OpenTelemetryCollectorSpec{
298+
ExtensionIngress: v1beta1.Ingress{
299+
Type: v1beta1.IngressType("unknown"),
300+
},
301+
},
302+
},
303+
}
304+
actual, err := ExtensionIngress(params)
305+
assert.Nil(t, actual)
306+
assert.NoError(t, err)
307+
})
308+
t.Run("no ingress if there's no port for extension", func(t *testing.T) {
309+
params := manifests.Params{
310+
Config: config.Config{},
311+
Log: logger,
312+
OtelCol: v1beta1.OpenTelemetryCollector{
313+
ObjectMeta: metav1.ObjectMeta{
314+
Name: "test",
315+
},
316+
Spec: v1beta1.OpenTelemetryCollectorSpec{
317+
Config: v1beta1.Config{
318+
Service: v1beta1.Service{
319+
Extensions: []string{"jaeger_query"},
320+
},
321+
Extensions: &v1beta1.AnyConfig{
322+
Object: map[string]interface{}{},
323+
},
324+
},
325+
ExtensionIngress: v1beta1.Ingress{
326+
Type: v1beta1.IngressType("ingress"),
327+
},
328+
},
329+
},
330+
}
331+
332+
actual, err := ExtensionIngress(params)
333+
assert.Nil(t, actual)
334+
assert.NoError(t, err)
335+
})
336+
t.Run("ingress for extensions for rule type path", func(t *testing.T) {
337+
var (
338+
ns = "test-ns"
339+
hostname = "example.com"
340+
ingressClassName = "nginx"
341+
pathType = networkingv1.PathTypePrefix
342+
)
343+
344+
params := manifests.Params{
345+
Config: config.Config{},
346+
Log: logger,
347+
OtelCol: v1beta1.OpenTelemetryCollector{
348+
ObjectMeta: metav1.ObjectMeta{
349+
Name: "test",
350+
Namespace: ns,
351+
},
352+
Spec: v1beta1.OpenTelemetryCollectorSpec{
353+
Config: v1beta1.Config{
354+
Service: v1beta1.Service{
355+
Extensions: []string{"jaeger_query"},
356+
},
357+
Extensions: &v1beta1.AnyConfig{
358+
Object: map[string]interface{}{
359+
"jaeger_query": map[string]interface{}{
360+
"http": map[string]interface{}{
361+
"endpoint": "0.0.0.0:16686",
362+
},
363+
},
364+
},
365+
},
366+
},
367+
ExtensionIngress: v1beta1.Ingress{
368+
Type: v1beta1.IngressType("ingress"),
369+
IngressClassName: &ingressClassName,
370+
Hostname: hostname,
371+
Annotations: map[string]string{"some.key": "some.value"},
372+
RuleType: v1beta1.IngressRuleTypePath,
373+
},
374+
},
375+
},
376+
}
377+
378+
actual, err := ExtensionIngress(params)
379+
assert.NoError(t, err)
380+
assert.NotNil(t, actual)
381+
assert.NotEqual(t, networkingv1.Ingress{
382+
ObjectMeta: metav1.ObjectMeta{
383+
Name: naming.ExtensionIngress(params.OtelCol.Name),
384+
Namespace: ns,
385+
Annotations: params.OtelCol.Spec.ExtensionIngress.Annotations,
386+
Labels: map[string]string{
387+
"app.kubernetes.io/name": naming.ExtensionIngress(params.OtelCol.Name),
388+
"app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name),
389+
"app.kubernetes.io/managed-by": "opentelemetry-operator",
390+
"app.kubernetes.io/component": "opentelemetry-collector",
391+
"app.kubernetes.io/part-of": "opentelemetry",
392+
"app.kubernetes.io/version": "latest",
393+
},
394+
},
395+
Spec: networkingv1.IngressSpec{
396+
IngressClassName: &ingressClassName,
397+
Rules: []networkingv1.IngressRule{
398+
{
399+
Host: hostname,
400+
IngressRuleValue: networkingv1.IngressRuleValue{
401+
HTTP: &networkingv1.HTTPIngressRuleValue{
402+
Paths: []networkingv1.HTTPIngressPath{
403+
{
404+
Path: "/jaeger-query",
405+
PathType: &pathType,
406+
Backend: networkingv1.IngressBackend{
407+
Service: &networkingv1.IngressServiceBackend{
408+
Name: naming.ExtensionService(params.OtelCol.Name),
409+
Port: networkingv1.ServiceBackendPort{
410+
Name: "jaeger-query",
411+
Number: 16686,
412+
},
413+
},
414+
},
415+
},
416+
},
417+
},
418+
},
419+
},
420+
},
421+
},
422+
}, actual)
423+
})
424+
t.Run("ingress for extensions for rule type subdomain", func(t *testing.T) {
425+
var (
426+
ns = "test-ns"
427+
hostname = "example.com"
428+
ingressClassName = "nginx"
429+
pathType = networkingv1.PathTypePrefix
430+
)
431+
432+
params := manifests.Params{
433+
Config: config.Config{},
434+
Log: logger,
435+
OtelCol: v1beta1.OpenTelemetryCollector{
436+
ObjectMeta: metav1.ObjectMeta{
437+
Name: "test",
438+
Namespace: ns,
439+
},
440+
Spec: v1beta1.OpenTelemetryCollectorSpec{
441+
Config: v1beta1.Config{
442+
Service: v1beta1.Service{
443+
Extensions: []string{"jaeger_query"},
444+
},
445+
Extensions: &v1beta1.AnyConfig{
446+
Object: map[string]interface{}{
447+
"jaeger_query": map[string]interface{}{
448+
"http": map[string]interface{}{
449+
"endpoint": "0.0.0.0:16686",
450+
},
451+
},
452+
},
453+
},
454+
},
455+
ExtensionIngress: v1beta1.Ingress{
456+
Type: v1beta1.IngressType("ingress"),
457+
IngressClassName: &ingressClassName,
458+
Hostname: hostname,
459+
Annotations: map[string]string{"some.key": "some.value"},
460+
RuleType: v1beta1.IngressRuleTypeSubdomain,
461+
},
462+
},
463+
},
464+
}
465+
466+
actual, err := ExtensionIngress(params)
467+
assert.NoError(t, err)
468+
assert.NotNil(t, actual)
469+
assert.NotEqual(t, networkingv1.Ingress{
470+
ObjectMeta: metav1.ObjectMeta{
471+
Name: naming.ExtensionIngress(params.OtelCol.Name),
472+
Namespace: ns,
473+
Annotations: params.OtelCol.Spec.ExtensionIngress.Annotations,
474+
Labels: map[string]string{
475+
"app.kubernetes.io/name": naming.ExtensionIngress(params.OtelCol.Name),
476+
"app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name),
477+
"app.kubernetes.io/managed-by": "opentelemetry-operator",
478+
"app.kubernetes.io/component": "opentelemetry-collector",
479+
"app.kubernetes.io/part-of": "opentelemetry",
480+
"app.kubernetes.io/version": "latest",
481+
},
482+
},
483+
Spec: networkingv1.IngressSpec{
484+
IngressClassName: &ingressClassName,
485+
Rules: []networkingv1.IngressRule{
486+
{
487+
Host: "jaeger-query." + hostname,
488+
IngressRuleValue: networkingv1.IngressRuleValue{
489+
HTTP: &networkingv1.HTTPIngressRuleValue{
490+
Paths: []networkingv1.HTTPIngressPath{
491+
{
492+
Path: "/",
493+
PathType: &pathType,
494+
Backend: networkingv1.IngressBackend{
495+
Service: &networkingv1.IngressServiceBackend{
496+
Name: naming.ExtensionService(params.OtelCol.Name),
497+
Port: networkingv1.ServiceBackendPort{
498+
Name: "jaeger-query",
499+
Number: 16686,
500+
},
501+
},
502+
},
503+
},
504+
},
505+
},
506+
},
507+
},
508+
},
509+
},
510+
}, actual)
511+
})
512+
}

internal/naming/main.go

+5
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ func Ingress(otelcol string) string {
131131
return DNSName(Truncate("%s-ingress", 63, otelcol))
132132
}
133133

134+
// Extension Ingress builds the ingress name for the extensions
135+
func ExtensionIngress(otelcol string) string {
136+
return DNSName(Truncate("%s-extension-ingress", 63, otelcol))
137+
}
138+
134139
// Route builds the route name based on the instance.
135140
func Route(otelcol string, prefix string) string {
136141
return DNSName(Truncate("%s-%s-route", 63, prefix, otelcol))

0 commit comments

Comments
 (0)