From e399e610ea4c14b5ade1093699ee43d1ef41e4aa Mon Sep 17 00:00:00 2001 From: Bruno Teixeira Date: Tue, 9 Apr 2024 15:59:56 +0100 Subject: [PATCH] feat/add support for hostPort in container (#2763) Signed-off-by: Bruno Teixeira --- .chloggen/2763 - add hostPort support.yaml | 16 ++ apis/v1alpha1/collector_webhook_test.go | 76 ++++++---- apis/v1alpha1/convert.go | 45 +++++- apis/v1alpha1/convert_test.go | 7 +- apis/v1alpha1/opentelemetrycollector_types.go | 12 +- apis/v1alpha1/zz_generated.deepcopy.go | 18 ++- apis/v1beta1/common.go | 14 +- apis/v1beta1/zz_generated.deepcopy.go | 18 ++- ...ntelemetry.io_opentelemetrycollectors.yaml | 8 +- ...ntelemetry.io_opentelemetrycollectors.yaml | 8 +- controllers/reconcile_test.go | 18 ++- controllers/suite_test.go | 76 +++++----- docs/api.md | 11 +- .../collector/adapters/config_to_ports.go | 14 +- .../adapters/config_to_ports_test.go | 7 +- internal/manifests/collector/container.go | 1 + .../manifests/collector/container_test.go | 138 +++++++++++------- internal/manifests/collector/ingress.go | 10 +- internal/manifests/collector/service.go | 13 +- internal/manifests/collector/service_test.go | 94 ++++++------ internal/manifests/collector/suite_test.go | 40 +++-- pkg/sidecar/pod_test.go | 10 +- tests/e2e/smoke-ports/00-assert.yaml | 37 +++++ tests/e2e/smoke-ports/00-install.yaml | 27 ++++ tests/e2e/smoke-ports/chainsaw-test.yaml | 14 ++ 25 files changed, 521 insertions(+), 211 deletions(-) create mode 100644 .chloggen/2763 - add hostPort support.yaml create mode 100644 tests/e2e/smoke-ports/00-assert.yaml create mode 100644 tests/e2e/smoke-ports/00-install.yaml create mode 100755 tests/e2e/smoke-ports/chainsaw-test.yaml diff --git a/.chloggen/2763 - add hostPort support.yaml b/.chloggen/2763 - add hostPort support.yaml new file mode 100644 index 0000000000..81295c2280 --- /dev/null +++ b/.chloggen/2763 - add hostPort support.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add support for adding/extending otc-collector container ports." + +# One or more tracking issues related to the change +issues: [2763] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: \ No newline at end of file diff --git a/apis/v1alpha1/collector_webhook_test.go b/apis/v1alpha1/collector_webhook_test.go index d54e9577c4..794c4cba65 100644 --- a/apis/v1alpha1/collector_webhook_test.go +++ b/apis/v1alpha1/collector_webhook_test.go @@ -475,15 +475,19 @@ func TestOTELColValidatingWebhook(t *testing.T) { thrift_http: endpoint: 0.0.0.0:15268 `, - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - Name: "port1", - Port: 5555, + ServicePort: v1.ServicePort{ + Name: "port1", + Port: 5555, + }, }, { - Name: "port2", - Port: 5554, - Protocol: v1.ProtocolUDP, + ServicePort: v1.ServicePort{ + Name: "port2", + Port: 5554, + Protocol: v1.ProtocolUDP, + }, }, }, Autoscaler: &AutoscalerSpec{ @@ -533,15 +537,19 @@ func TestOTELColValidatingWebhook(t *testing.T) { thrift_http: endpoint: 0.0.0.0:15268 `, - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - Name: "port1", - Port: 5555, + ServicePort: v1.ServicePort{ + Name: "port1", + Port: 5555, + }, }, { - Name: "port2", - Port: 5554, - Protocol: v1.ProtocolUDP, + ServicePort: v1.ServicePort{ + Name: "port2", + Port: 5554, + Protocol: v1.ProtocolUDP, + }, }, }, Autoscaler: &AutoscalerSpec{ @@ -601,15 +609,19 @@ func TestOTELColValidatingWebhook(t *testing.T) { thrift_http: endpoint: 0.0.0.0:15268 `, - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - Name: "port1", - Port: 5555, + ServicePort: v1.ServicePort{ + Name: "port1", + Port: 5555, + }, }, { - Name: "port2", - Port: 5554, - Protocol: v1.ProtocolUDP, + ServicePort: v1.ServicePort{ + Name: "port2", + Port: 5554, + Protocol: v1.ProtocolUDP, + }, }, }, Autoscaler: &AutoscalerSpec{ @@ -687,12 +699,14 @@ func TestOTELColValidatingWebhook(t *testing.T) { name: "invalid port name", otelcol: OpenTelemetryCollector{ Spec: OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - // this port name contains a non alphanumeric character, which is invalid. - Name: "-testšŸ¦„port", - Port: 12345, - Protocol: v1.ProtocolTCP, + ServicePort: v1.ServicePort{ + // this port name contains a non alphanumeric character, which is invalid. + Name: "-testšŸ¦„port", + Port: 12345, + Protocol: v1.ProtocolTCP, + }, }, }, }, @@ -703,10 +717,12 @@ func TestOTELColValidatingWebhook(t *testing.T) { name: "invalid port name, too long", otelcol: OpenTelemetryCollector{ Spec: OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - Name: "aaaabbbbccccdddd", // len: 16, too long - Port: 5555, + ServicePort: v1.ServicePort{ + Name: "aaaabbbbccccdddd", // len: 16, too long + Port: 5555, + }, }, }, }, @@ -717,10 +733,12 @@ func TestOTELColValidatingWebhook(t *testing.T) { name: "invalid port num", otelcol: OpenTelemetryCollector{ Spec: OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{ + Ports: []PortsSpec{ { - Name: "aaaabbbbccccddd", // len: 15 - // no port set means it's 0, which is invalid + ServicePort: v1.ServicePort{ + Name: "aaaabbbbccccddd", // len: 15 + // no port set means it's 0, which is invalid + }, }, }, }, diff --git a/apis/v1alpha1/convert.go b/apis/v1alpha1/convert.go index a831659666..fb047082c6 100644 --- a/apis/v1alpha1/convert.go +++ b/apis/v1alpha1/convert.go @@ -20,6 +20,7 @@ import ( "gopkg.in/yaml.v3" appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" @@ -96,7 +97,7 @@ func tov1beta1(in OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error Image: copy.Spec.Image, ImagePullPolicy: copy.Spec.ImagePullPolicy, VolumeMounts: copy.Spec.VolumeMounts, - Ports: copy.Spec.Ports, + Ports: tov1beta1Ports(copy.Spec.Ports), Env: copy.Spec.Env, EnvFrom: copy.Spec.EnvFrom, VolumeClaimTemplates: copy.Spec.VolumeClaimTemplates, @@ -144,6 +145,26 @@ func tov1beta1(in OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error }, nil } +func tov1beta1Ports(in []PortsSpec) []v1beta1.PortsSpec { + var ports []v1beta1.PortsSpec + + for _, p := range in { + ports = append(ports, v1beta1.PortsSpec{ + ServicePort: v1.ServicePort{ + Name: p.Name, + Protocol: p.Protocol, + AppProtocol: p.AppProtocol, + Port: p.Port, + TargetPort: p.TargetPort, + NodePort: p.NodePort, + }, + HostPort: p.HostPort, + }) + } + + return ports +} + func tov1beta1TA(in OpenTelemetryTargetAllocator) v1beta1.TargetAllocatorEmbedded { return v1beta1.TargetAllocatorEmbedded{ Replicas: in.Replicas, @@ -249,6 +270,26 @@ func tov1beta1ConfigMaps(in []ConfigMapsSpec) []v1beta1.ConfigMapsSpec { return mapsSpecs } +func tov1alpha1Ports(in []v1beta1.PortsSpec) []PortsSpec { + var ports []PortsSpec + + for _, p := range in { + ports = append(ports, PortsSpec{ + ServicePort: v1.ServicePort{ + Name: p.Name, + Protocol: p.Protocol, + AppProtocol: p.AppProtocol, + Port: p.Port, + TargetPort: p.TargetPort, + NodePort: p.NodePort, + }, + HostPort: p.HostPort, + }) + } + + return ports +} + func tov1alpha1(in v1beta1.OpenTelemetryCollector) (*OpenTelemetryCollector, error) { copy := in.DeepCopy() configYaml, err := copy.Spec.Config.Yaml() @@ -287,7 +328,7 @@ func tov1alpha1(in v1beta1.OpenTelemetryCollector) (*OpenTelemetryCollector, err ImagePullPolicy: copy.Spec.ImagePullPolicy, Config: configYaml, VolumeMounts: copy.Spec.VolumeMounts, - Ports: copy.Spec.Ports, + Ports: tov1alpha1Ports(copy.Spec.Ports), Env: copy.Spec.Env, EnvFrom: copy.Spec.EnvFrom, VolumeClaimTemplates: copy.Spec.VolumeClaimTemplates, diff --git a/apis/v1alpha1/convert_test.go b/apis/v1alpha1/convert_test.go index 61a3df1aad..2b2e032532 100644 --- a/apis/v1alpha1/convert_test.go +++ b/apis/v1alpha1/convert_test.go @@ -177,11 +177,12 @@ func Test_tov1beta1AndBack(t *testing.T) { Name: "aaa", }, }, - Ports: []v1.ServicePort{ - { + Ports: []PortsSpec{{ + ServicePort: v1.ServicePort{ Name: "otlp", }, - }, + HostPort: 0, + }}, Env: []v1.EnvVar{ { Name: "foo", diff --git a/apis/v1alpha1/opentelemetrycollector_types.go b/apis/v1alpha1/opentelemetrycollector_types.go index 998f49ae84..eb95265139 100644 --- a/apis/v1alpha1/opentelemetrycollector_types.go +++ b/apis/v1alpha1/opentelemetrycollector_types.go @@ -186,7 +186,7 @@ type OpenTelemetryCollectorSpec struct { // used to open additional ports that can't be inferred by the operator, like for custom receivers. // +optional // +listType=atomic - Ports []v1.ServicePort `json:"ports,omitempty"` + Ports []PortsSpec `json:"ports,omitempty"` // ENV vars to set on the OpenTelemetry Collector's Pods. These can then in certain cases be // consumed in the config file for the Collector. // +optional @@ -291,6 +291,16 @@ type OpenTelemetryCollectorSpec struct { DeploymentUpdateStrategy appsv1.DeploymentStrategy `json:"deploymentUpdateStrategy,omitempty"` } +// PortsSpec defines the OpenTelemetryCollector's container/service ports additional specifications. +type PortsSpec struct { + // Allows defining which port to bind to the host in the Container. + // +optional + HostPort int32 `json:"hostPort,omitempty"` + + // Maintain previous fields in new struct + v1.ServicePort `json:",inline"` +} + // OpenTelemetryTargetAllocator defines the configurations for the Prometheus target allocator. type OpenTelemetryTargetAllocator struct { // Replicas is the number of pod instances for the underlying TargetAllocator. This should only be set to a value diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index 8db7c841b4..92911cd336 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -830,7 +830,7 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp } if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]v1.ServicePort, len(*in)) + *out = make([]PortsSpec, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1083,6 +1083,22 @@ func (in *PodDisruptionBudgetSpec) DeepCopy() *PodDisruptionBudgetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PortsSpec) DeepCopyInto(out *PortsSpec) { + *out = *in + in.ServicePort.DeepCopyInto(&out.ServicePort) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortsSpec. +func (in *PortsSpec) DeepCopy() *PortsSpec { + if in == nil { + return nil + } + out := new(PortsSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Probe) DeepCopyInto(out *Probe) { *out = *in diff --git a/apis/v1beta1/common.go b/apis/v1beta1/common.go index 2c7531b92d..d4c421553d 100644 --- a/apis/v1beta1/common.go +++ b/apis/v1beta1/common.go @@ -84,6 +84,16 @@ type PodDisruptionBudgetSpec struct { MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` } +// PortsSpec defines the OpenTelemetryCollector's container/service ports additional specifications. +type PortsSpec struct { + // Allows defining which port to bind to the host in the Container. + // +optional + HostPort int32 `json:"hostPort,omitempty"` + + // Maintain previous fields in new struct + v1.ServicePort `json:",inline"` +} + type OpenTelemetryCommonFields struct { // ManagementState defines if the CR should be managed by the operator or not. // Default is managed. @@ -151,12 +161,12 @@ type OpenTelemetryCommonFields struct { // +optional // +listType=atomic VolumeMounts []v1.VolumeMount `json:"volumeMounts,omitempty"` - // Ports allows a set of ports to be exposed by the underlying v1.Service. By default, the operator + // Ports allows a set of ports to be exposed by the underlying v1.Service & v1.ContainerPort. By default, the operator // will attempt to infer the required ports by parsing the .Spec.Config property but this property can be // used to open additional ports that can't be inferred by the operator, like for custom receivers. // +optional // +listType=atomic - Ports []v1.ServicePort `json:"ports,omitempty"` + Ports []PortsSpec `json:"ports,omitempty"` // Environment variables to set on the generated pods. // +optional Env []v1.EnvVar `json:"env,omitempty"` diff --git a/apis/v1beta1/zz_generated.deepcopy.go b/apis/v1beta1/zz_generated.deepcopy.go index 5d62bd470b..e109e8ff7a 100644 --- a/apis/v1beta1/zz_generated.deepcopy.go +++ b/apis/v1beta1/zz_generated.deepcopy.go @@ -386,7 +386,7 @@ func (in *OpenTelemetryCommonFields) DeepCopyInto(out *OpenTelemetryCommonFields } if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]v1.ServicePort, len(*in)) + *out = make([]PortsSpec, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -499,6 +499,22 @@ func (in *PodDisruptionBudgetSpec) DeepCopy() *PodDisruptionBudgetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PortsSpec) DeepCopyInto(out *PortsSpec) { + *out = *in + in.ServicePort.DeepCopyInto(&out.ServicePort) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortsSpec. +func (in *PortsSpec) DeepCopy() *PortsSpec { + if in == nil { + return nil + } + out := new(PortsSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Probe) DeepCopyInto(out *Probe) { *out = *in diff --git a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml index 2883192bf6..aff078058c 100644 --- a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml +++ b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml @@ -4184,7 +4184,8 @@ spec: Ports allows a set of ports to be exposed by the underlying v1.Service. By default, the operator will attempt to infer the required ports by parsing the .Spec. items: - description: ServicePort contains information on service's port. + description: PortsSpec defines the OpenTelemetryCollector's container/service + ports additional specifications. properties: appProtocol: description: |- @@ -4192,6 +4193,11 @@ spec: This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. type: string + hostPort: + description: Allows defining which port to bind to the host + in the Container. + format: int32 + type: integer name: description: |- The name of this port within the service. This must be a DNS_LABEL. diff --git a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml index 9924a8c948..03f8d10ddc 100644 --- a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml +++ b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml @@ -4181,7 +4181,8 @@ spec: Ports allows a set of ports to be exposed by the underlying v1.Service. By default, the operator will attempt to infer the required ports by parsing the .Spec. items: - description: ServicePort contains information on service's port. + description: PortsSpec defines the OpenTelemetryCollector's container/service + ports additional specifications. properties: appProtocol: description: |- @@ -4189,6 +4190,11 @@ spec: This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. type: string + hostPort: + description: Allows defining which port to bind to the host + in the Container. + format: int32 + type: integer name: description: |- The name of this port within the service. This must be a DNS_LABEL. diff --git a/controllers/reconcile_test.go b/controllers/reconcile_test.go index 939df90140..18d6e48abc 100644 --- a/controllers/reconcile_test.go +++ b/controllers/reconcile_test.go @@ -60,11 +60,13 @@ const ( ) var ( - extraPorts = v1.ServicePort{ - Name: "port-web", - Protocol: "TCP", - Port: 8080, - TargetPort: intstr.FromInt32(8080), + extraPorts = v1alpha1.PortsSpec{ + ServicePort: v1.ServicePort{ + Name: "port-web", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt32(8080), + }, } ) @@ -180,7 +182,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.Service(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - assert.Contains(t, actual.Spec.Ports, extraPorts) + assert.Contains(t, actual.Spec.Ports, extraPorts.ServicePort) }, }, wantErr: assert.NoError, @@ -631,7 +633,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { annotationName: annotationVal, } deploymentExtraPorts := opampBridgeParams() - deploymentExtraPorts.OpAMPBridge.Spec.Ports = append(deploymentExtraPorts.OpAMPBridge.Spec.Ports, extraPorts) + deploymentExtraPorts.OpAMPBridge.Spec.Ports = append(deploymentExtraPorts.OpAMPBridge.Spec.Ports, extraPorts.ServicePort) type args struct { params manifests.Params @@ -697,7 +699,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.OpAMPBridgeService(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - assert.Contains(t, actual.Spec.Ports, extraPorts) + assert.Contains(t, actual.Spec.Ports, extraPorts.ServicePort) }, }, wantErr: assert.NoError, diff --git a/controllers/suite_test.go b/controllers/suite_test.go index e66ceb1df5..f36f47d262 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -245,15 +245,16 @@ func testCollectorWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) v1alph }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, + Ports: []v1alpha1.PortsSpec{{ + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}}, Replicas: &replicas, Config: string(configYAML), Mode: mode, @@ -294,15 +295,16 @@ func testCollectorWithConfigFile(taContainerImage string, file string) (v1alpha1 }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ Mode: v1alpha1.ModeStatefulSet, - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, + Ports: []v1alpha1.PortsSpec{{ + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}}, TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ Enabled: true, Image: taContainerImage, @@ -331,15 +333,16 @@ func testCollectorWithHPA(minReps, maxReps int32) v1alpha1.OpenTelemetryCollecto UID: instanceUID, }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, + Ports: []v1alpha1.PortsSpec{{ + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}}, Config: string(configYAML), Autoscaler: &v1alpha1.AutoscalerSpec{ MinReplicas: &minReps, @@ -390,15 +393,16 @@ func testCollectorWithPDB(minAvailable, maxUnavailable int32) v1alpha1.OpenTelem UID: instanceUID, }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, + Ports: []v1alpha1.PortsSpec{{ + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}}, Config: string(configYAML), PodDisruptionBudget: pdb, }, diff --git a/docs/api.md b/docs/api.md index 73f12f5f0a..9e27fb50a1 100644 --- a/docs/api.md +++ b/docs/api.md @@ -19473,7 +19473,7 @@ May also be set in PodSecurityContext.
-ServicePort contains information on service's port. +PortsSpec defines the OpenTelemetryCollector's container/service ports additional specifications. @@ -19502,6 +19502,15 @@ This is used as a hint for implementations to offer richer behavior for protocol This field follows standard Kubernetes label syntax.
+ + + + + diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index 5f2a88be9c..3a0bc5a6fd 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -25,6 +25,7 @@ import ( "github.com/mitchellh/mapstructure" corev1 "k8s.io/api/core/v1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser" exporterParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/exporter" receiverParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver" @@ -43,7 +44,7 @@ func (c ComponentType) String() string { } // ConfigToComponentPorts converts the incoming configuration object into a set of service ports required by the exporters. -func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { +func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config map[interface{}]interface{}) ([]v1beta1.PortsSpec, error) { // now, we gather which ports we might need to open // for that, we get all the exporters and check their `endpoint` properties, // extracting the port from it. The port name has to be a "DNS_LABEL", so, we try to make it follow the pattern: @@ -119,10 +120,17 @@ func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config map[ return ports[i].Name < ports[j].Name }) - return ports, nil + patchedPorts := []v1beta1.PortsSpec{} + for _, p := range ports { + patchedPorts = append(patchedPorts, v1beta1.PortsSpec{ + ServicePort: p, + }) + } + + return patchedPorts, nil } -func ConfigToPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { +func ConfigToPorts(logger logr.Logger, config map[interface{}]interface{}) ([]v1beta1.PortsSpec, error) { ports, err := ConfigToComponentPorts(logger, ComponentTypeReceiver, config) if err != nil { logger.Error(err, "there was a problem while getting the ports from the receivers") diff --git a/internal/manifests/collector/adapters/config_to_ports_test.go b/internal/manifests/collector/adapters/config_to_ports_test.go index 7c872606f6..d76091379c 100644 --- a/internal/manifests/collector/adapters/config_to_ports_test.go +++ b/internal/manifests/collector/adapters/config_to_ports_test.go @@ -95,6 +95,11 @@ func TestExtractPortsFromConfig(t *testing.T) { targetPort4317 := intstr.IntOrString{Type: 0, IntVal: 4317, StrVal: ""} targetPort4318 := intstr.IntOrString{Type: 0, IntVal: 4318, StrVal: ""} + svcPorts := []corev1.ServicePort{} + for _, p := range ports { + svcPorts = append(svcPorts, p.ServicePort) + } + expectedPorts := []corev1.ServicePort{ {Name: "examplereceiver", Port: 12345}, {Name: "port-12346", Port: 12346}, @@ -107,7 +112,7 @@ func TestExtractPortsFromConfig(t *testing.T) { {Name: "otlp-http", AppProtocol: &httpAppProtocol, Port: 4318, TargetPort: targetPort4318}, {Name: "zipkin", AppProtocol: &httpAppProtocol, Protocol: "TCP", Port: 9411}, } - assert.ElementsMatch(t, expectedPorts, ports) + assert.ElementsMatch(t, expectedPorts, svcPorts) } func TestNoPortsParsed(t *testing.T) { diff --git a/internal/manifests/collector/container.go b/internal/manifests/collector/container.go index fdfc004db8..1ffd81cbe0 100644 --- a/internal/manifests/collector/container.go +++ b/internal/manifests/collector/container.go @@ -59,6 +59,7 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme Name: p.Name, ContainerPort: p.Port, Protocol: p.Protocol, + HostPort: p.HostPort, } } diff --git a/internal/manifests/collector/container_test.go b/internal/manifests/collector/container_test.go index 5dfe16be69..e2cd24639d 100644 --- a/internal/manifests/collector/container_test.go +++ b/internal/manifests/collector/container_test.go @@ -55,11 +55,13 @@ func TestContainerNewDefault(t *testing.T) { otelcol := v1beta1.OpenTelemetryCollector{ Spec: v1beta1.OpenTelemetryCollectorSpec{ OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{ - Ports: []corev1.ServicePort{ + Ports: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, }, }, @@ -109,17 +111,19 @@ service: tests := []struct { description string specConfig string - specPorts []corev1.ServicePort + specPorts []v1beta1.PortsSpec expectedPorts []corev1.ContainerPort }{ { description: "couldn't build ports from spec config", specConfig: "", - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, }, expectedPorts: []corev1.ContainerPort{metricContainerPort}, @@ -138,15 +142,19 @@ service: }, { description: "ports in spec ContainerPorts", - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, { - Name: "testport1", - Port: 12345, + ServicePort: corev1.ServicePort{ + Name: "testport1", + Port: 12345, + }, }, }, expectedPorts: []corev1.ContainerPort{ @@ -160,15 +168,19 @@ service: { description: "ports in spec Config and ContainerPorts", specConfig: goodConfig, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "testport1", - Port: 12345, + ServicePort: corev1.ServicePort{ + Name: "testport1", + Port: 12345, + }, }, { - Name: "testport2", - Port: 54321, - Protocol: corev1.ProtocolUDP, + ServicePort: corev1.ServicePort{ + Name: "testport2", + Port: 54321, + Protocol: corev1.ProtocolUDP, + }, }, }, expectedPorts: []corev1.ContainerPort{ @@ -191,14 +203,18 @@ service: { description: "duplicate port name", specConfig: goodConfig, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "testport1", - Port: 12345, + ServicePort: corev1.ServicePort{ + Name: "testport1", + Port: 12345, + }, }, { - Name: "testport1", - Port: 11111, + ServicePort: corev1.ServicePort{ + Name: "testport1", + Port: 11111, + }, }, }, expectedPorts: []corev1.ContainerPort{ @@ -225,15 +241,19 @@ service: receivers: [otlp] exporters: [prometheus, debug] `, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, { - Name: "prometheus", - Port: 9090, + ServicePort: corev1.ServicePort{ + Name: "prometheus", + Port: 9090, + }, }, }, expectedPorts: []corev1.ContainerPort{ @@ -261,19 +281,25 @@ service: metrics: exporters: [prometheus/prod, prometheus/dev, debug] `, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, { - Name: "prometheus-dev", - Port: 9091, + ServicePort: corev1.ServicePort{ + Name: "prometheus-dev", + Port: 9091, + }, }, { - Name: "prometheus-prod", - Port: 9090, + ServicePort: corev1.ServicePort{ + Name: "prometheus-prod", + Port: 9090, + }, }, }, expectedPorts: []corev1.ContainerPort{ @@ -293,11 +319,13 @@ service: specConfig: `exporters: prometheusremotewrite/prometheus: endpoint: http://prometheus-server.monitoring/api/v1/write`, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, }, expectedPorts: []corev1.ContainerPort{metricContainerPort}, @@ -317,19 +345,25 @@ service: pipelines: metrics: exporters: [prometheus/prod, prometheus/dev, prometheusremotewrite/prometheus, debug]`, - specPorts: []corev1.ServicePort{ + specPorts: []v1beta1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, { - Name: "prometheus-dev", - Port: 9091, + ServicePort: corev1.ServicePort{ + Name: "prometheus-dev", + Port: 9091, + }, }, { - Name: "prometheus-prod", - Port: 9090, + ServicePort: corev1.ServicePort{ + Name: "prometheus-prod", + Port: 9090, + }, }, }, expectedPorts: []corev1.ContainerPort{ diff --git a/internal/manifests/collector/ingress.go b/internal/manifests/collector/ingress.go index 18c6d0cb6c..f8a7530d3d 100644 --- a/internal/manifests/collector/ingress.go +++ b/internal/manifests/collector/ingress.go @@ -161,7 +161,7 @@ func servicePortsFromCfg(logger logr.Logger, otelcol v1beta1.OpenTelemetryCollec // in the first case, we remove the port we inferred from the list // in the second case, we rename our inferred port to something like "port-%d" portNumbers, portNames := extractPortNumbersAndNames(otelcol.Spec.Ports) - var resultingInferredPorts []corev1.ServicePort + var resultingInferredPorts []v1beta1.PortsSpec for _, inferred := range ports { if filtered := filterPort(logger, inferred, portNumbers, portNames); filtered != nil { resultingInferredPorts = append(resultingInferredPorts, *filtered) @@ -169,5 +169,11 @@ func servicePortsFromCfg(logger logr.Logger, otelcol v1beta1.OpenTelemetryCollec } ports = append(otelcol.Spec.Ports, resultingInferredPorts...) } - return ports, err + + svcPorts := []corev1.ServicePort{} + for _, p := range ports { + svcPorts = append(svcPorts, p.ServicePort) + } + + return svcPorts, err } diff --git a/internal/manifests/collector/service.go b/internal/manifests/collector/service.go index 333b3e5254..7b834bc751 100644 --- a/internal/manifests/collector/service.go +++ b/internal/manifests/collector/service.go @@ -136,7 +136,7 @@ func Service(params manifests.Params) (*corev1.Service, error) { // in the first case, we remove the port we inferred from the list // in the second case, we rename our inferred port to something like "port-%d" portNumbers, portNames := extractPortNumbersAndNames(params.OtelCol.Spec.Ports) - var resultingInferredPorts []corev1.ServicePort + var resultingInferredPorts []v1beta1.PortsSpec for _, inferred := range ports { if filtered := filterPort(params.Log, inferred, portNumbers, portNames); filtered != nil { resultingInferredPorts = append(resultingInferredPorts, *filtered) @@ -158,6 +158,11 @@ func Service(params manifests.Params) (*corev1.Service, error) { trafficPolicy = corev1.ServiceInternalTrafficPolicyLocal } + svcPorts := []corev1.ServicePort{} + for _, p := range ports { + svcPorts = append(svcPorts, p.ServicePort) + } + return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: naming.Service(params.OtelCol.Name), @@ -169,7 +174,7 @@ func Service(params manifests.Params) (*corev1.Service, error) { InternalTrafficPolicy: &trafficPolicy, Selector: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), ClusterIP: "", - Ports: ports, + Ports: svcPorts, }, }, nil } @@ -191,7 +196,7 @@ func newPortNumberKey(port int32, protocol corev1.Protocol) PortNumberKey { return PortNumberKey{Port: port, Protocol: protocol} } -func filterPort(logger logr.Logger, candidate corev1.ServicePort, portNumbers map[PortNumberKey]bool, portNames map[string]bool) *corev1.ServicePort { +func filterPort(logger logr.Logger, candidate v1beta1.PortsSpec, portNumbers map[PortNumberKey]bool, portNames map[string]bool) *v1beta1.PortsSpec { if portNumbers[newPortNumberKey(candidate.Port, candidate.Protocol)] { return nil } @@ -217,7 +222,7 @@ func filterPort(logger logr.Logger, candidate corev1.ServicePort, portNumbers ma return &candidate } -func extractPortNumbersAndNames(ports []corev1.ServicePort) (map[PortNumberKey]bool, map[string]bool) { +func extractPortNumbersAndNames(ports []v1beta1.PortsSpec) (map[PortNumberKey]bool, map[string]bool) { numbers := map[PortNumberKey]bool{} names := map[string]bool{} diff --git a/internal/manifests/collector/service_test.go b/internal/manifests/collector/service_test.go index 0498a071a8..441fb31493 100644 --- a/internal/manifests/collector/service_test.go +++ b/internal/manifests/collector/service_test.go @@ -30,11 +30,11 @@ import ( func TestExtractPortNumbersAndNames(t *testing.T) { t.Run("should return extracted port names and numbers", func(t *testing.T) { - ports := []v1.ServicePort{ - {Name: "web", Port: 8080}, - {Name: "tcp", Port: 9200}, - {Name: "web-explicit", Port: 80, Protocol: v1.ProtocolTCP}, - {Name: "syslog-udp", Port: 514, Protocol: v1.ProtocolUDP}, + ports := []v1beta1.PortsSpec{ + {ServicePort: v1.ServicePort{Name: "web", Port: 8080}}, + {ServicePort: v1.ServicePort{Name: "tcp", Port: 9200}}, + {ServicePort: v1.ServicePort{Name: "web-explicit", Port: 80, Protocol: v1.ProtocolTCP}}, + {ServicePort: v1.ServicePort{Name: "syslog-udp", Port: 514, Protocol: v1.ProtocolUDP}}, } expectedPortNames := map[string]bool{"web": true, "tcp": true, "web-explicit": true, "syslog-udp": true} expectedPortNumbers := map[PortNumberKey]bool{ @@ -55,14 +55,14 @@ func TestFilterPort(t *testing.T) { tests := []struct { name string - candidate v1.ServicePort + candidate v1beta1.PortsSpec portNumbers map[PortNumberKey]bool portNames map[string]bool - expected v1.ServicePort + expected v1beta1.PortsSpec }{ { name: "should filter out duplicate port", - candidate: v1.ServicePort{Name: "web", Port: 8080}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, @@ -70,7 +70,7 @@ func TestFilterPort(t *testing.T) { { name: "should filter out duplicate port, protocol specified (TCP)", - candidate: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, @@ -78,7 +78,7 @@ func TestFilterPort(t *testing.T) { { name: "should filter out duplicate port, protocol specified (UDP)", - candidate: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKey(8080, v1.ProtocolUDP): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, @@ -86,52 +86,52 @@ func TestFilterPort(t *testing.T) { { name: "should not filter unique port", - candidate: v1.ServicePort{Name: "web", Port: 8090}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8090}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, - expected: v1.ServicePort{Name: "web", Port: 8090}, + expected: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8090}}, }, { name: "should not filter same port with different protocols", - candidate: v1.ServicePort{Name: "web", Port: 8080}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKey(8080, v1.ProtocolUDP): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, - expected: v1.ServicePort{Name: "web", Port: 8080}, + expected: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080}}, }, { name: "should not filter same port with different protocols, candidate has specified port (TCP vs UDP)", - candidate: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKey(8080, v1.ProtocolUDP): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, - expected: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}, + expected: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolTCP}}, }, { name: "should not filter same port with different protocols, candidate has specified port (UDP vs TCP)", - candidate: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"test": true, "metrics": true}, - expected: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}, + expected: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8080, Protocol: v1.ProtocolUDP}}, }, { name: "should change the duplicate portName", - candidate: v1.ServicePort{Name: "web", Port: 8090}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8090}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"web": true, "metrics": true}, - expected: v1.ServicePort{Name: "port-8090", Port: 8090}, + expected: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "port-8090", Port: 8090}}, }, { name: "should return nil if fallback name clashes with existing portName", - candidate: v1.ServicePort{Name: "web", Port: 8090}, + candidate: v1beta1.PortsSpec{ServicePort: v1.ServicePort{Name: "web", Port: 8090}}, portNumbers: map[PortNumberKey]bool{ newPortNumberKeyByPort(8080): true, newPortNumberKeyByPort(9200): true}, portNames: map[string]bool{"web": true, "port-8090": true}, @@ -140,7 +140,7 @@ func TestFilterPort(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { actual := filterPort(logger, test.candidate, test.portNumbers, test.portNames) - if test.expected != (v1.ServicePort{}) { + if test.expected != (v1beta1.PortsSpec{}) { assert.Equal(t, test.expected, *actual) return } @@ -168,12 +168,13 @@ func TestDesiredService(t *testing.T) { t.Run("should return service with port mentioned in OtelCol.Spec.Ports and inferred ports", func(t *testing.T) { grpc := "grpc" - jaegerPorts := v1.ServicePort{ - Name: "jaeger-grpc", - Protocol: "TCP", - Port: 14250, - AppProtocol: &grpc, - } + jaegerPorts := v1beta1.PortsSpec{ + ServicePort: v1.ServicePort{ + Name: "jaeger-grpc", + Protocol: "TCP", + Port: 14250, + AppProtocol: &grpc, + }} params := deploymentParams() ports := append(params.OtelCol.Spec.Ports, jaegerPorts) expected := service("test-collector", ports) @@ -186,12 +187,13 @@ func TestDesiredService(t *testing.T) { t.Run("on OpenShift gRPC appProtocol should be h2c", func(t *testing.T) { h2c := "h2c" - jaegerPort := v1.ServicePort{ - Name: "jaeger-grpc", - Protocol: "TCP", - Port: 14250, - AppProtocol: &h2c, - } + jaegerPort := v1beta1.PortsSpec{ + ServicePort: v1.ServicePort{ + Name: "jaeger-grpc", + Protocol: "TCP", + Port: 14250, + AppProtocol: &h2c, + }} params := deploymentParams() @@ -208,12 +210,13 @@ func TestDesiredService(t *testing.T) { t.Run("should return service with local internal traffic policy", func(t *testing.T) { grpc := "grpc" - jaegerPorts := v1.ServicePort{ - Name: "jaeger-grpc", - Protocol: "TCP", - Port: 14250, - AppProtocol: &grpc, - } + jaegerPorts := v1beta1.PortsSpec{ + ServicePort: v1.ServicePort{ + Name: "jaeger-grpc", + Protocol: "TCP", + Port: 14250, + AppProtocol: &grpc, + }} p := paramsWithMode(v1beta1.ModeDaemonSet) ports := append(p.OtelCol.Spec.Ports, jaegerPorts) expected := serviceWithInternalTrafficPolicy("test-collector", ports, v1.ServiceInternalTrafficPolicyLocal) @@ -277,14 +280,19 @@ func TestMonitoringService(t *testing.T) { }) } -func service(name string, ports []v1.ServicePort) v1.Service { +func service(name string, ports []v1beta1.PortsSpec) v1.Service { return serviceWithInternalTrafficPolicy(name, ports, v1.ServiceInternalTrafficPolicyCluster) } -func serviceWithInternalTrafficPolicy(name string, ports []v1.ServicePort, internalTrafficPolicy v1.ServiceInternalTrafficPolicyType) v1.Service { +func serviceWithInternalTrafficPolicy(name string, ports []v1beta1.PortsSpec, internalTrafficPolicy v1.ServiceInternalTrafficPolicyType) v1.Service { params := deploymentParams() labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) + svcPorts := []v1.ServicePort{} + for _, p := range ports { + svcPorts = append(svcPorts, p.ServicePort) + } + return v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -296,7 +304,7 @@ func serviceWithInternalTrafficPolicy(name string, ports []v1.ServicePort, inter InternalTrafficPolicy: &internalTrafficPolicy, Selector: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), ClusterIP: "", - Ports: ports, + Ports: svcPorts, }, } } diff --git a/internal/manifests/collector/suite_test.go b/internal/manifests/collector/suite_test.go index e16b5699e3..1f2654ba60 100644 --- a/internal/manifests/collector/suite_test.go +++ b/internal/manifests/collector/suite_test.go @@ -78,15 +78,19 @@ func paramsWithMode(mode v1beta1.Mode) manifests.Params { OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{ Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Ports: []v1beta1.PortsSpec{ + { + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }, }, - NodePort: 0, - }}, + }, Replicas: &replicas, }, Config: cfg, @@ -139,15 +143,19 @@ func newParams(taContainerImage string, file string, options ...config.Option) ( }, Spec: v1beta1.OpenTelemetryCollectorSpec{ OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{ - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Ports: []v1beta1.PortsSpec{ + { + ServicePort: v1.ServicePort{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }, }, - NodePort: 0, - }}, + }, Replicas: &replicas, }, diff --git a/pkg/sidecar/pod_test.go b/pkg/sidecar/pod_test.go index a15548c62d..61209ece5c 100644 --- a/pkg/sidecar/pod_test.go +++ b/pkg/sidecar/pod_test.go @@ -54,11 +54,13 @@ func TestAddSidecarWhenNoSidecarExists(t *testing.T) { Namespace: "some-app", }, Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ports: []corev1.ServicePort{ + Ports: []v1alpha1.PortsSpec{ { - Name: "metrics", - Port: 8888, - Protocol: corev1.ProtocolTCP, + ServicePort: corev1.ServicePort{ + Name: "metrics", + Port: 8888, + Protocol: corev1.ProtocolTCP, + }, }, }, InitContainers: []corev1.Container{ diff --git a/tests/e2e/smoke-ports/00-assert.yaml b/tests/e2e/smoke-ports/00-assert.yaml new file mode 100644 index 0000000000..792c481802 --- /dev/null +++ b/tests/e2e/smoke-ports/00-assert.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: smoke-ports-collector +spec: + template: + spec: + containers: + - name: otc-container + ports: + - containerPort: 14250 + name: jaeger-grpc + protocol: TCP + - containerPort: 8888 + name: metrics + protocol: TCP + - containerPort: 4317 + name: otlp-grpc + protocol: TCP + hostPort: 4317 +--- +apiVersion: v1 +kind: Service +metadata: + name: smoke-ports-collector +spec: + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + targetPort: 4317 + - appProtocol: grpc + name: jaeger-grpc + port: 14250 + protocol: TCP + targetPort: 14250 diff --git a/tests/e2e/smoke-ports/00-install.yaml b/tests/e2e/smoke-ports/00-install.yaml new file mode 100644 index 0000000000..1326c61f40 --- /dev/null +++ b/tests/e2e/smoke-ports/00-install.yaml @@ -0,0 +1,27 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: smoke-ports +spec: + mode: daemonset + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + targetPort: 4317 + hostPort: 4317 + config: | + receivers: + jaeger: + protocols: + grpc: {} + processors: + exporters: + debug: {} + service: + pipelines: + traces: + receivers: [jaeger] + processors: [] + exporters: [debug] diff --git a/tests/e2e/smoke-ports/chainsaw-test.yaml b/tests/e2e/smoke-ports/chainsaw-test.yaml new file mode 100755 index 0000000000..3d9816ddf9 --- /dev/null +++ b/tests/e2e/smoke-ports/chainsaw-test.yaml @@ -0,0 +1,14 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: smoke-ports +spec: + steps: + - name: step-00 + try: + - apply: + file: 00-install.yaml + - assert: + file: 00-assert.yaml
false
hostPortinteger + Allows defining which port to bind to the host in the Container.
+
+ Format: int32
+
false
name string