Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve probe parsing #3250

Merged
merged 20 commits into from
Sep 30, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add parser for liveness and readiness probes
jaronoff97 committed Aug 30, 2024
commit c96376dbbe8460b1f3d0b2c26e9387aa1e3994c7
42 changes: 40 additions & 2 deletions apis/v1beta1/config.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ import (

"github.com/open-telemetry/opentelemetry-operator/internal/components"
"github.com/open-telemetry/opentelemetry-operator/internal/components/exporters"
"github.com/open-telemetry/opentelemetry-operator/internal/components/extensions"
"github.com/open-telemetry/opentelemetry-operator/internal/components/processors"
"github.com/open-telemetry/opentelemetry-operator/internal/components/receivers"
)
@@ -41,10 +42,11 @@ const (
KindReceiver ComponentKind = iota
KindExporter
KindProcessor
KindExtension
)

func (c ComponentKind) String() string {
return [...]string{"receiver", "exporter", "processor"}[c]
return [...]string{"receiver", "exporter", "processor", "extension"}[c]
}

// AnyConfig represent parts of the config.
@@ -108,6 +110,7 @@ func (c *Config) GetEnabledComponents() map[ComponentKind]map[string]interface{}
KindReceiver: {},
KindProcessor: {},
KindExporter: {},
KindExtension: {},
}
for _, pipeline := range c.Service.Pipelines {
if pipeline == nil {
@@ -123,6 +126,9 @@ func (c *Config) GetEnabledComponents() map[ComponentKind]map[string]interface{}
toReturn[KindProcessor][componentId] = struct{}{}
}
}
for _, componentId := range c.Service.Extensions {
toReturn[KindExtension][componentId] = struct{}{}
}
return toReturn
}

@@ -227,6 +233,38 @@ func (c *Config) GetAllRbacRules(logger logr.Logger) ([]rbacv1.PolicyRule, error
return c.getRbacRulesForComponentKinds(logger, KindReceiver, KindExporter, KindProcessor)
}

// GetLivenessProbe gets the first enabled liveness probe. There should only ever be one extension enabled
// that provides the hinting for the liveness probe.
func (c *Config) GetLivenessProbe(logger logr.Logger) (*corev1.Probe, error) {
enabledComponents := c.GetEnabledComponents()
for componentName := range enabledComponents[KindExtension] {
// TODO: Clean up the naming here and make it simpler to use a retriever.
parser := extensions.ParserFor(componentName)
if probe, err := parser.GetLivenessProbe(logger, c.Extensions.Object[componentName]); err != nil {
return nil, err
} else if probe != nil {
return probe, nil
}
}
return nil, nil
}

// GetReadinessProbe gets the first enabled readiness probe. There should only ever be one extension enabled
// that provides the hinting for the readiness probe.
func (c *Config) GetReadinessProbe(logger logr.Logger) (*corev1.Probe, error) {
enabledComponents := c.GetEnabledComponents()
for componentName := range enabledComponents[KindExtension] {
// TODO: Clean up the naming here and make it simpler to use a retriever.
parser := extensions.ParserFor(componentName)
if probe, err := parser.GetReadinessProbe(logger, c.Extensions.Object[componentName]); err != nil {
return nil, err
} else if probe != nil {
return probe, nil
}
}
return nil, nil
}

// Yaml encodes the current object and returns it as a string.
func (c *Config) Yaml() (string, error) {
var buf bytes.Buffer
@@ -268,7 +306,7 @@ func (c *Config) nullObjects() []string {
}

type Service struct {
Extensions *[]string `json:"extensions,omitempty" yaml:"extensions,omitempty"`
Extensions []string `json:"extensions,omitempty" yaml:"extensions,omitempty"`
// +kubebuilder:pruning:PreserveUnknownFields
Telemetry *AnyConfig `json:"telemetry,omitempty" yaml:"telemetry,omitempty"`
// +kubebuilder:pruning:PreserveUnknownFields
2 changes: 1 addition & 1 deletion apis/v1beta1/config_test.go
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ func TestConfigYaml(t *testing.T) {
},
},
Service: Service{
Extensions: &[]string{"addon"},
Extensions: []string{"addon"},
Telemetry: &AnyConfig{
Object: map[string]interface{}{
"insights": "yeah!",
8 changes: 2 additions & 6 deletions apis/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 0 additions & 158 deletions internal/manifests/collector/adapters/config_to_probe.go

This file was deleted.

187 changes: 0 additions & 187 deletions internal/manifests/collector/adapters/config_to_probe_test.go

This file was deleted.

63 changes: 7 additions & 56 deletions internal/manifests/collector/container.go
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
package collector

import (
"errors"
"fmt"
"path"
"sort"
@@ -27,7 +26,6 @@ import (

"github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters"
"github.com/open-telemetry/opentelemetry-operator/internal/naming"
"github.com/open-telemetry/opentelemetry-operator/pkg/featuregate"
)
@@ -43,12 +41,6 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme
image = cfg.CollectorImage()
}

configYaml, err := otelcol.Spec.Config.Yaml()
if err != nil {
logger.Error(err, "could not convert json to yaml")
return corev1.Container{}
}

// build container ports from service ports
ports, err := getConfigContainerPorts(logger, otelcol.Spec.Config)
if err != nil {
@@ -140,28 +132,13 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTeleme
})
}

var livenessProbe *corev1.Probe
var readinessProbe *corev1.Probe
if configFromString, err := adapters.ConfigFromString(configYaml); err == nil {
if probe, err := getProbe(configFromString, otelcol.Spec.LivenessProbe); err == nil {
livenessProbe = probe
} else if errors.Is(err, adapters.ErrNoServiceExtensions) {
logger.V(4).Info("extensions not configured, skipping liveness probe creation")
} else if errors.Is(err, adapters.ErrNoServiceExtensionHealthCheck) {
logger.V(4).Info("healthcheck extension not configured, skipping liveness probe creation")
} else {
logger.Error(err, "cannot create liveness probe.")
}

if probe, err := getProbe(configFromString, otelcol.Spec.ReadinessProbe); err == nil {
readinessProbe = probe
} else if errors.Is(err, adapters.ErrNoServiceExtensions) {
logger.V(4).Info("extensions not configured, skipping readiness probe creation")
} else if errors.Is(err, adapters.ErrNoServiceExtensionHealthCheck) {
logger.V(4).Info("healthcheck extension not configured, skipping readiness probe creation")
} else {
logger.Error(err, "cannot create readiness probe.")
}
livenessProbe, livenessProbeErr := otelcol.Spec.Config.GetLivenessProbe(logger)
if livenessProbeErr != nil {
logger.Error(livenessProbeErr, "cannot create liveness probe.")
}
readinessProbe, readinessProbeErr := otelcol.Spec.Config.GetReadinessProbe(logger)
if readinessProbeErr != nil {
logger.Error(readinessProbeErr, "cannot create readiness probe.")
}

if featuregate.SetGolangFlags.IsEnabled() {
@@ -256,29 +233,3 @@ func portMapToList(portMap map[string]corev1.ContainerPort) []corev1.ContainerPo
})
return ports
}

func getProbe(config map[interface{}]interface{}, probeConfig *v1beta1.Probe) (*corev1.Probe, error) {
probe, err := adapters.ConfigToContainerProbe(config)
if err != nil {
return nil, err
}
if probeConfig != nil {
if probeConfig.InitialDelaySeconds != nil {
probe.InitialDelaySeconds = *probeConfig.InitialDelaySeconds
}
if probeConfig.PeriodSeconds != nil {
probe.PeriodSeconds = *probeConfig.PeriodSeconds
}
if probeConfig.FailureThreshold != nil {
probe.FailureThreshold = *probeConfig.FailureThreshold
}
if probeConfig.SuccessThreshold != nil {
probe.SuccessThreshold = *probeConfig.SuccessThreshold
}
if probeConfig.TimeoutSeconds != nil {
probe.TimeoutSeconds = *probeConfig.TimeoutSeconds
}
probe.TerminationGracePeriodSeconds = probeConfig.TerminationGracePeriodSeconds
}
return probe, nil
}
10 changes: 2 additions & 8 deletions internal/manifests/manifestutils/annotations_test.go
Original file line number Diff line number Diff line change
@@ -34,10 +34,7 @@ func TestDefaultAnnotations(t *testing.T) {
Spec: v1beta1.OpenTelemetryCollectorSpec{
Config: v1beta1.Config{
Service: v1beta1.Service{
Extensions: func() *[]string {
res := []string{"test"}
return &res
}(),
Extensions: []string{"test"},
},
},
},
@@ -101,10 +98,7 @@ func TestUserAnnotations(t *testing.T) {
Spec: v1beta1.OpenTelemetryCollectorSpec{
Config: v1beta1.Config{
Service: v1beta1.Service{
Extensions: func() *[]string {
res := []string{"test2"}
return &res
}(),
Extensions: []string{"test2"},
},
},
},