Skip to content

Commit

Permalink
remove deprecated config component
Browse files Browse the repository at this point in the history
Signed-off-by: Ruben Vargas <[email protected]>
  • Loading branch information
rubenvp8510 committed Nov 18, 2024
1 parent 0a595ac commit af27b51
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 20 deletions.
66 changes: 64 additions & 2 deletions api/config/v1alpha1/projectconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"os"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
cfg "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
configv1alpha1 "k8s.io/component-base/config/v1alpha1"
)

const (
Expand Down Expand Up @@ -223,14 +223,76 @@ type FeatureGates struct {
GrafanaOperator bool `json:"grafanaOperator,omitempty"`
}

// ControllerManagerConfigurationSpec defines the desired state of GenericControllerManagerConfiguration.
type ControllerManagerConfigurationSpec struct {
// LeaderElection is the LeaderElection config to be used when configuring
// the manager.Manager leader election
// +optional
LeaderElection *configv1alpha1.LeaderElectionConfiguration `json:"leaderElection,omitempty"`

// Metrics contains the controller metrics configuration
// +optional
Metrics ControllerMetrics `json:"metrics,omitempty"`

// Health contains the controller health configuration
// +optional
Health ControllerHealth `json:"health,omitempty"`

// Webhook contains the controllers webhook configuration
// +optional
Webhook ControllerWebhook `json:"webhook,omitempty"`
}

// ControllerMetrics defines the metrics configs.
type ControllerMetrics struct {
// BindAddress is the TCP address that the controller should bind to
// for serving prometheus metrics.
// It can be set to "0" to disable the metrics serving.
// +optional
BindAddress string `json:"bindAddress,omitempty"`
}

// ControllerHealth defines the health configs.
type ControllerHealth struct {
// HealthProbeBindAddress is the TCP address that the controller should bind to
// for serving health probes
// It can be set to "0" or "" to disable serving the health probe.
// +optional
HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"`
}

// ControllerWebhook defines the webhook server for the controller.
type ControllerWebhook struct {
// Port is the port that the webhook server serves at.
// It is used to set webhook.Server.Port.
// +optional
Port *int `json:"port,omitempty"`
}

//+kubebuilder:object:root=true

// ControllerManagerConfiguration is the Schema for the GenericControllerManagerConfigurations API.
type ControllerManagerConfiguration struct {
metav1.TypeMeta `json:",inline"`

// ControllerManagerConfiguration returns the configurations for controllers
ControllerManagerConfigurationSpec `json:",inline"`
}

// Complete returns the configuration for controller-runtime.
func (c *ControllerManagerConfigurationSpec) Complete() (ControllerManagerConfigurationSpec, error) {
return *c, nil
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// ProjectConfig is the Schema for the projectconfigs API.
type ProjectConfig struct {
metav1.TypeMeta `json:",inline"`

// ControllerManagerConfigurationSpec returns the configurations for controllers
cfg.ControllerManagerConfigurationSpec `json:",inline"`
ControllerManagerConfigurationSpec `json:",inline"`

// The images are read from environment variables and not from the configuration file
DefaultImages ImagesSpec
Expand Down
99 changes: 99 additions & 0 deletions api/config/v1alpha1/zz_generated.deepcopy.go

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

30 changes: 30 additions & 0 deletions cmd/root/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package root

import (
"errors"
"fmt"
"os"
"path/filepath"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"

configv1alpha1 "github.com/grafana/tempo-operator/api/config/v1alpha1"
)

var errConfigFileLoading = errors.New("could not read file at path")

func loadConfigFile(scheme *runtime.Scheme, outConfig *configv1alpha1.ProjectConfig, configFile string) error {
content, err := os.ReadFile(filepath.Clean(configFile))
if err != nil {
return fmt.Errorf("%w %s", errConfigFileLoading, configFile)
}

codecs := serializer.NewCodecFactory(scheme)

if err = runtime.DecodeInto(codecs.UniversalDecoder(), content, outConfig); err != nil {
return fmt.Errorf("could not decode file into runtime.Object: %w", err)
}

return nil
}
108 changes: 108 additions & 0 deletions cmd/root/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package root

import (
"fmt"
"net/http"
"net/http/pprof"
"reflect"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/webhook"

configv1alpha1 "github.com/grafana/tempo-operator/api/config/v1alpha1"
)

// LoadConfig initializes the controller configuration, optionally overriding the defaults
// from a provided configuration file.
func LoadConfig(scheme *runtime.Scheme, configFile string) (*configv1alpha1.ProjectConfig, ctrl.Options, error) {
options := ctrl.Options{Scheme: scheme}
ctrlConfig := configv1alpha1.DefaultProjectConfig()

if configFile == "" {
return &ctrlConfig, options, nil
}

err := loadConfigFile(scheme, &ctrlConfig, configFile)
if err != nil {
return nil, options, fmt.Errorf("failed to parse controller manager config file: %w", err)
}

options = mergeOptionsFromFile(options, &ctrlConfig)
return &ctrlConfig, options, nil
}

func mergeOptionsFromFile(o manager.Options, cfg *configv1alpha1.ProjectConfig) manager.Options {
o = setLeaderElectionConfig(o, cfg.ControllerManagerConfigurationSpec)

if o.Metrics.BindAddress == "" && cfg.Metrics.BindAddress != "" {
o.Metrics.BindAddress = cfg.Metrics.BindAddress

endpoints := map[string]http.HandlerFunc{
"/debug/pprof/": pprof.Index,
"/debug/pprof/cmdline": pprof.Cmdline,
"/debug/pprof/profile": pprof.Profile,
"/debug/pprof/symbol": pprof.Symbol,
"/debug/pprof/trace": pprof.Trace,
}

if o.Metrics.ExtraHandlers == nil {
o.Metrics.ExtraHandlers = map[string]http.Handler{}
}

for path, handler := range endpoints {
o.Metrics.ExtraHandlers[path] = handler
}
}

if o.HealthProbeBindAddress == "" && cfg.Health.HealthProbeBindAddress != "" {
o.HealthProbeBindAddress = cfg.Health.HealthProbeBindAddress
}

if cfg.Webhook.Port != nil {
o.WebhookServer = webhook.NewServer(webhook.Options{
Port: *cfg.Webhook.Port,
})
}

return o
}

func setLeaderElectionConfig(o manager.Options, obj configv1alpha1.ControllerManagerConfigurationSpec) manager.Options {
if obj.LeaderElection == nil {
// The source does not have any configuration; noop
return o
}

if !o.LeaderElection && obj.LeaderElection.LeaderElect != nil {
o.LeaderElection = *obj.LeaderElection.LeaderElect
}

if o.LeaderElectionResourceLock == "" && obj.LeaderElection.ResourceLock != "" {
o.LeaderElectionResourceLock = obj.LeaderElection.ResourceLock
}

if o.LeaderElectionNamespace == "" && obj.LeaderElection.ResourceNamespace != "" {
o.LeaderElectionNamespace = obj.LeaderElection.ResourceNamespace
}

if o.LeaderElectionID == "" && obj.LeaderElection.ResourceName != "" {
o.LeaderElectionID = obj.LeaderElection.ResourceName
}

if o.LeaseDuration == nil && !reflect.DeepEqual(obj.LeaderElection.LeaseDuration, metav1.Duration{}) {
o.LeaseDuration = &obj.LeaderElection.LeaseDuration.Duration
}

if o.RenewDeadline == nil && !reflect.DeepEqual(obj.LeaderElection.RenewDeadline, metav1.Duration{}) {
o.RenewDeadline = &obj.LeaderElection.RenewDeadline.Duration
}

if o.RetryPeriod == nil && !reflect.DeepEqual(obj.LeaderElection.RetryPeriod, metav1.Duration{}) {
o.RetryPeriod = &obj.LeaderElection.RetryPeriod.Duration
}

return o
}
20 changes: 5 additions & 15 deletions cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package root

import (
"context"
"fmt"

grafanav1 "github.com/grafana/grafana-operator/v5/api/v1beta1"
configv1 "github.com/openshift/api/config/v1"
Expand Down Expand Up @@ -45,25 +44,16 @@ func init() {
//+kubebuilder:scaffold:scheme
}

//var errConfigFileLoading = errors.New("could not read file at path")

func readConfig(cmd *cobra.Command, configFile string) error {
// default controller configuration
ctrlConfig := configv1alpha1.DefaultProjectConfig()

var err error
options := ctrl.Options{Scheme: scheme}
if configFile != "" {
options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile).OfKind(&ctrlConfig))
if err != nil {
return fmt.Errorf("unable to load the config file: %w", err)
}
}

err = ctrlConfig.Validate()
ctrlCfg, options, err := LoadConfig(scheme, configFile)
if err != nil {
return fmt.Errorf("controller config validation failed: %w", err)
return err
}

cmd.SetContext(context.WithValue(cmd.Context(), RootConfigKey{}, RootConfig{options, ctrlConfig}))
cmd.SetContext(context.WithValue(cmd.Context(), RootConfigKey{}, RootConfig{options, *ctrlCfg}))
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
k8s.io/apimachinery v0.29.4
k8s.io/apiserver v0.29.4
k8s.io/client-go v0.29.4
k8s.io/component-base v0.29.4
k8s.io/klog/v2 v2.120.1
sigs.k8s.io/controller-runtime v0.17.3
sigs.k8s.io/yaml v1.4.0
Expand Down Expand Up @@ -104,7 +105,6 @@ require (
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/component-base v0.29.4 // indirect
k8s.io/kube-openapi v0.0.0-20240221221325-2ac9dc51f3f1 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
Expand Down
Loading

0 comments on commit af27b51

Please sign in to comment.