Skip to content

Commit 261aea6

Browse files
atoulmegithub-actions[bot]frzifus
authored
[webhook] do not crash if collector CRD is not present in the cluster (#3955)
* [webhook] do not crash if collector CRD is not present in the cluster * code review * do not change the default behavior * Update main.go Co-authored-by: Ben B. <bongartz@klimlive.de> * Update main.go --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Ben B. <bongartz@klimlive.de>
1 parent 6df9301 commit 261aea6

File tree

9 files changed

+182
-34
lines changed

9 files changed

+182
-34
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
5+
component: webhook
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Allow to run the operator without the OpenTelemetry CRDs present
9+
10+
# One or more tracking issues related to the change
11+
issues: [3568]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext: |
17+
Skip registering the webhook and keep the operator working in case the OpenTelemetryCollector CRDs are not deployed.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package collector
5+
6+
// Availability represents that the OpenTelemetryCollector CR is available in the cluster.
7+
type Availability int
8+
9+
const (
10+
// NotAvailable OpenTelemetryCollector CR is not available in the cluster.
11+
NotAvailable Availability = iota
12+
13+
// Available OpenTelemetryCollector CR is available in the cluster.
14+
Available
15+
)
16+
17+
func (p Availability) String() string {
18+
return [...]string{"NotAvailable", "Available"}[p]
19+
}

internal/autodetect/main.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"k8s.io/client-go/rest"
1515

1616
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/certmanager"
17+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
1718
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/fips"
1819
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
1920
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
@@ -31,6 +32,7 @@ type AutoDetect interface {
3132
RBACPermissions(ctx context.Context) (autoRBAC.Availability, error)
3233
CertManagerAvailability(ctx context.Context) (certmanager.Availability, error)
3334
TargetAllocatorAvailability() (targetallocator.Availability, error)
35+
CollectorAvailability() (collector.Availability, error)
3436
FIPSEnabled(ctx context.Context) bool
3537
}
3638

@@ -182,6 +184,38 @@ func (a *autoDetect) TargetAllocatorAvailability() (targetallocator.Availability
182184
return targetallocator.NotAvailable, nil
183185
}
184186

187+
// CollectorAvailability checks if OpenTelemetryCollector CR are available.
188+
func (a *autoDetect) CollectorAvailability() (collector.Availability, error) {
189+
apiList, err := a.dcl.ServerGroups()
190+
if err != nil {
191+
return collector.NotAvailable, err
192+
}
193+
194+
apiGroups := apiList.Groups
195+
otelGroupIndex := slices.IndexFunc(apiGroups, func(group metav1.APIGroup) bool {
196+
return group.Name == "opentelemetry.io"
197+
})
198+
if otelGroupIndex == -1 {
199+
return collector.NotAvailable, nil
200+
}
201+
202+
otelGroup := apiGroups[otelGroupIndex]
203+
for _, groupVersion := range otelGroup.Versions {
204+
resourceList, err := a.dcl.ServerResourcesForGroupVersion(groupVersion.GroupVersion)
205+
if err != nil {
206+
return collector.NotAvailable, err
207+
}
208+
collectorIndex := slices.IndexFunc(resourceList.APIResources, func(group metav1.APIResource) bool {
209+
return group.Kind == "OpenTelemetryCollector"
210+
})
211+
if collectorIndex >= 0 {
212+
return collector.Available, nil
213+
}
214+
}
215+
216+
return collector.NotAvailable, nil
217+
}
218+
185219
func (a *autoDetect) FIPSEnabled(_ context.Context) bool {
186220
return fips.IsFipsEnabled()
187221
}

internal/config/config.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect"
1414
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/certmanager"
15+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
1516
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
1617
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
1718
autoRBAC "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac"
@@ -56,6 +57,8 @@ type Config struct {
5657
prometheusCRAvailability prometheus.Availability
5758
certManagerAvailability certmanager.Availability
5859
targetAllocatorAvailability targetallocator.Availability
60+
collectorAvailability collector.Availability
61+
ignoreMissingCollectorCRDs bool
5962
labelsFilter []string
6063
annotationsFilter []string
6164
}
@@ -69,6 +72,7 @@ func New(opts ...Option) Config {
6972
createRBACPermissions: autoRBAC.NotAvailable,
7073
certManagerAvailability: certmanager.NotAvailable,
7174
targetAllocatorAvailability: targetallocator.NotAvailable,
75+
collectorAvailability: collector.NotAvailable,
7276
collectorConfigMapEntry: defaultCollectorConfigMapEntry,
7377
targetAllocatorConfigMapEntry: defaultTargetAllocatorConfigMapEntry,
7478
operatorOpAMPBridgeConfigMapEntry: defaultOperatorOpAMPBridgeConfigMapEntry,
@@ -103,6 +107,8 @@ func New(opts ...Option) Config {
103107
prometheusCRAvailability: o.prometheusCRAvailability,
104108
certManagerAvailability: o.certManagerAvailability,
105109
targetAllocatorAvailability: o.targetAllocatorAvailability,
110+
collectorAvailability: o.collectorAvailability,
111+
ignoreMissingCollectorCRDs: o.ignoreMissingCollectorCRDs,
106112
autoInstrumentationJavaImage: o.autoInstrumentationJavaImage,
107113
autoInstrumentationNodeJSImage: o.autoInstrumentationNodeJSImage,
108114
autoInstrumentationPythonImage: o.autoInstrumentationPythonImage,
@@ -155,6 +161,13 @@ func (c *Config) AutoDetect() error {
155161
c.targetAllocatorAvailability = taAvl
156162
c.logger.V(2).Info("determined TargetAllocator CRD availability", "availability", cmAvl)
157163

164+
coAvl, err := c.autoDetect.CollectorAvailability()
165+
if err != nil {
166+
return err
167+
}
168+
c.collectorAvailability = coAvl
169+
c.logger.V(2).Info("determined Collector CRD availability", "availability", coAvl)
170+
158171
return nil
159172
}
160173

@@ -253,6 +266,16 @@ func (c *Config) TargetAllocatorAvailability() targetallocator.Availability {
253266
return c.targetAllocatorAvailability
254267
}
255268

269+
// CollectorAvailability represents the availability of the OpenTelemetryCollector CRD.
270+
func (c *Config) CollectorAvailability() collector.Availability {
271+
return c.collectorAvailability
272+
}
273+
274+
// IgnoreMissingCollectorCRDs is true if the operator can ignore missing OpenTelemetryCollector CRDs.
275+
func (c *Config) IgnoreMissingCollectorCRDs() bool {
276+
return c.ignoreMissingCollectorCRDs
277+
}
278+
256279
// AutoInstrumentationJavaImage returns OpenTelemetry Java auto-instrumentation container image.
257280
func (c *Config) AutoInstrumentationJavaImage() string {
258281
return c.autoInstrumentationJavaImage

internal/config/config_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect"
1414
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/certmanager"
15+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
1516
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
1617
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
1718
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac"
@@ -53,6 +54,9 @@ func TestConfigChangesOnAutoDetect(t *testing.T) {
5354
TargetAllocatorAvailabilityFunc: func() (targetallocator.Availability, error) {
5455
return targetallocator.Available, nil
5556
},
57+
CollectorAvailabilityFunc: func() (collector.Availability, error) {
58+
return collector.Available, nil
59+
},
5660
}
5761
cfg := config.New(
5862
config.WithAutoDetect(mock),
@@ -64,6 +68,7 @@ func TestConfigChangesOnAutoDetect(t *testing.T) {
6468
require.Equal(t, rbac.NotAvailable, cfg.CreateRBACPermissions())
6569
require.Equal(t, certmanager.NotAvailable, cfg.CertManagerAvailability())
6670
require.Equal(t, targetallocator.NotAvailable, cfg.TargetAllocatorAvailability())
71+
require.Equal(t, collector.NotAvailable, cfg.CollectorAvailability())
6772

6873
// test
6974
err := cfg.AutoDetect()
@@ -85,6 +90,7 @@ type mockAutoDetect struct {
8590
RBACPermissionsFunc func(ctx context.Context) (rbac.Availability, error)
8691
CertManagerAvailabilityFunc func(ctx context.Context) (certmanager.Availability, error)
8792
TargetAllocatorAvailabilityFunc func() (targetallocator.Availability, error)
93+
CollectorAvailabilityFunc func() (collector.Availability, error)
8894
}
8995

9096
func (m *mockAutoDetect) FIPSEnabled(_ context.Context) bool {
@@ -125,3 +131,10 @@ func (m *mockAutoDetect) TargetAllocatorAvailability() (targetallocator.Availabi
125131
}
126132
return targetallocator.NotAvailable, nil
127133
}
134+
135+
func (m *mockAutoDetect) CollectorAvailability() (collector.Availability, error) {
136+
if m.CollectorAvailabilityFunc != nil {
137+
return m.CollectorAvailabilityFunc()
138+
}
139+
return collector.NotAvailable, nil
140+
}

internal/config/options.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect"
1111
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/certmanager"
12+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
1213
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
1314
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
1415
autoRBAC "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac"
@@ -49,6 +50,8 @@ type options struct {
4950
prometheusCRAvailability prometheus.Availability
5051
certManagerAvailability certmanager.Availability
5152
targetAllocatorAvailability targetallocator.Availability
53+
collectorAvailability collector.Availability
54+
ignoreMissingCollectorCRDs bool
5255
labelsFilter []string
5356
annotationsFilter []string
5457
}
@@ -227,3 +230,9 @@ func WithEncodeLevelFormat(s string) zapcore.LevelEncoder {
227230
return zapcore.CapitalLevelEncoder
228231
}
229232
}
233+
234+
func WithIgnoreMissingCollectorCRDs(b bool) Option {
235+
return func(o *options) {
236+
o.ignoreMissingCollectorCRDs = b
237+
}
238+
}

internal/controllers/reconcile_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838

3939
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
4040
"github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
41+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
4142
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
4243
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
4344
autoRBAC "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac"
@@ -794,6 +795,9 @@ func TestOpenTelemetryCollectorReconciler_RemoveDisabled(t *testing.T) {
794795
testCtx, cancel := context.WithCancel(context.Background())
795796
t.Cleanup(cancel)
796797
reconciler := createTestReconciler(t, testCtx, config.New(
798+
config.WithAutoDetect(&mockAutoDetect{CollectorCRDAvailabilityFunc: func() (collector.Availability, error) {
799+
return collector.Available, nil
800+
}}),
797801
config.WithCollectorImage("default-collector"),
798802
config.WithTargetAllocatorImage("default-ta-allocator"),
799803
config.WithOpenShiftRoutesAvailability(openshift.RoutesAvailable),

internal/controllers/suite_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
"github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
4747
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect"
4848
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/certmanager"
49+
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/collector"
4950
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
5051
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/prometheus"
5152
autoRBAC "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/rbac"
@@ -92,6 +93,7 @@ type mockAutoDetect struct {
9293
RBACPermissionsFunc func(ctx context.Context) (autoRBAC.Availability, error)
9394
CertManagerAvailabilityFunc func(ctx context.Context) (certmanager.Availability, error)
9495
TargetAllocatorAvailabilityFunc func() (targetallocator.Availability, error)
96+
CollectorCRDAvailabilityFunc func() (collector.Availability, error)
9597
}
9698

9799
func (m *mockAutoDetect) FIPSEnabled(_ context.Context) bool {
@@ -133,6 +135,13 @@ func (m *mockAutoDetect) TargetAllocatorAvailability() (targetallocator.Availabi
133135
return targetallocator.NotAvailable, nil
134136
}
135137

138+
func (m *mockAutoDetect) CollectorAvailability() (collector.Availability, error) {
139+
if m.CollectorCRDAvailabilityFunc != nil {
140+
return m.CollectorCRDAvailabilityFunc()
141+
}
142+
return collector.Available, nil
143+
}
144+
136145
func TestMain(m *testing.M) {
137146
var err error
138147
ctx, cancel = context.WithCancel(context.TODO())

0 commit comments

Comments
 (0)