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

Support monolithic deployment mode #722

Merged
Merged
Changes from 22 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
edb2a72
Support monolithic deployment mode
andreasgerstmayr Dec 15, 2023
51a2b26
Add changelog
andreasgerstmayr Dec 21, 2023
41dbed1
update mutate_test.go
andreasgerstmayr Dec 21, 2023
8aaa8b5
add webhook tests
andreasgerstmayr Dec 21, 2023
442004c
add generated files
andreasgerstmayr Dec 21, 2023
7d3ce55
support pruning unmanaged objects
andreasgerstmayr Dec 21, 2023
84cba0c
use common reconcile/prune function
andreasgerstmayr Dec 22, 2023
cd797bc
fix linter
andreasgerstmayr Dec 22, 2023
355a79e
add sts tests
andreasgerstmayr Jan 8, 2024
82fef56
add service tests
andreasgerstmayr Jan 8, 2024
0f490dd
add configmap tests
andreasgerstmayr Jan 9, 2024
c84f6bd
use a single service, because the monolithic deployment will use a si…
andreasgerstmayr Jan 10, 2024
bd54f6b
drop component from labels
andreasgerstmayr Jan 10, 2024
8c66093
fix configmap
andreasgerstmayr Jan 10, 2024
5874547
TestBuildAll()
andreasgerstmayr Jan 10, 2024
3b86d3a
add e2e test
andreasgerstmayr Jan 10, 2024
3faae98
drop defaulter webhook for TempoMonolithic
andreasgerstmayr Jan 11, 2024
a027746
delete operator namespace and webhooks in make run
andreasgerstmayr Jan 11, 2024
7af52c4
Merge remote-tracking branch 'upstream/main' into tempo-monolithic-de…
andreasgerstmayr Jan 11, 2024
19d6e07
change the way to include .env file
andreasgerstmayr Jan 11, 2024
f29369f
rebuild bundle, fix linter
andreasgerstmayr Jan 11, 2024
f0c9ffc
fix typo in jaeger-grpc port name
andreasgerstmayr Jan 11, 2024
c0343f1
add warning when overriding tempo config
andreasgerstmayr Jan 15, 2024
0c9b6e6
specify default value of storage.traces.backend
andreasgerstmayr Jan 16, 2024
fd37ff8
update storage docs
andreasgerstmayr Jan 17, 2024
9acad7b
Merge remote-tracking branch 'upstream/main' into tempo-monolithic-de…
andreasgerstmayr Jan 17, 2024
754486e
drop .env file
andreasgerstmayr Jan 17, 2024
3f57be4
reconcile: retry on conflict
andreasgerstmayr Jan 18, 2024
852d0e2
Merge remote-tracking branch 'upstream/main' into tempo-monolithic-de…
andreasgerstmayr Jan 18, 2024
19ca826
update changelog, set size defaults, add api docs
andreasgerstmayr Jan 18, 2024
cd64880
update changelog
andreasgerstmayr Jan 18, 2024
a9e41e9
fix test
andreasgerstmayr Jan 18, 2024
6657c89
add controller test
andreasgerstmayr Jan 18, 2024
9a95fce
enable OTLP/HTTP by default
andreasgerstmayr Jan 24, 2024
1cf6976
drop TLS struct (will reuse TLS struct from TempoStack in follow-up PR)
andreasgerstmayr Jan 25, 2024
16b7030
add comment to default function
andreasgerstmayr Jan 25, 2024
822c016
show diff using cmp.Diff() in logs when immutable field is changed
andreasgerstmayr Jan 26, 2024
bf76bef
re-use ExtraConfig from TempoStack
andreasgerstmayr Jan 26, 2024
4c6715a
Merge remote-tracking branch 'upstream/main' into tempo-monolithic-de…
andreasgerstmayr Jan 26, 2024
c5eba0d
add comment on exported function
andreasgerstmayr Jan 26, 2024
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
16 changes: 16 additions & 0 deletions .chloggen/monolithic_mode.yaml
Original file line number Diff line number Diff line change
@@ -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. operator, github action)
component: operator

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Support monolithic deployment mode

# One or more tracking issues related to the change
issues: [710]

# (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:
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions .env
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RELATED_IMAGE_TEMPO=docker.io/grafana/tempo:2.3.0
RELATED_IMAGE_TEMPO_QUERY=docker.io/grafana/tempo-query:2.3.0
RELATED_IMAGE_TEMPO_GATEWAY=quay.io/observatorium/api:main-2023-11-20-81f8fdf
RELATED_IMAGE_TEMPO_GATEWAY_OPA=quay.io/observatorium/opa-openshift:main-2023-10-13-13d8960
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -129,7 +129,10 @@ build: generate fmt ## Build manager binary.
run: manifests generate fmt ## Run a controller from your host.
# Disabled webhooks only affects local runs, not the build or in-cluster deployments.
@echo -e "\033[33mWebhooks are disabled! Use the normal deployment method to enable full operator functionality.\033[0m"
ENABLE_WEBHOOKS=false go run ./main.go start
-kubectl delete ns $(OPERATOR_NAMESPACE)
-kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io tempo-operator-mutating-webhook-configuration
-kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io tempo-operator-validating-webhook-configuration
set -a && . .env && ENABLE_WEBHOOKS=false go run ./main.go start

.PHONY: docker-build
docker-build: ## Build docker image with the manager.
13 changes: 13 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -21,4 +21,17 @@ resources:
defaulting: true
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: grafana.com
group: tempo
kind: TempoMonolithic
path: github.com/grafana/tempo-operator/api/v1alpha1
version: v1alpha1
webhooks:
defaulting: true
validation: true
webhookVersion: v1
version: "3"
265 changes: 265 additions & 0 deletions apis/tempo/v1alpha1/tempomonolithic_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
package v1alpha1

import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// TempoMonolithicSpec defines the desired state of TempoMonolithic.
type TempoMonolithicSpec struct {
// Storage defines the backend storage configuration
//
// +kubebuilder:validation:Optional
Storage *MonolithicStorageSpec `json:"storage,omitempty"`

// Ingestion defines the trace ingestion configuration
//
// +kubebuilder:validation:Optional
Ingestion *MonolithicIngestionSpec `json:"ingestion,omitempty"`

// JaegerUI defines the Jaeger UI configuration
//
// +kubebuilder:validation:Optional
JaegerUI *MonolithicJaegerUISpec `json:"jaegerui,omitempty"`

// ManagementState defines whether this instance is managed by the operator or self-managed
//
// +kubebuilder:validation:Optional
Management ManagementStateType `json:"management,omitempty"`

// Observability defines observability configuration for the Tempo deployment
//
// +kubebuilder:validation:Optional
Observability *MonolithicObservabilitySpec `json:"observability,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking again, can we reuse some of the structs from the microservies type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, question is do we value consistency inside the same CR or consistency between the two CRs more?

spec:
  observability:                         # Observability defines observability configuration for the Tempo deployment
    metrics:                             # Metrics defines the metrics configuration of the Tempo deployment
      prometheusRules:                   # ServiceMonitors defines the PrometheusRule configuration
        enabled: false                   # Enabled defines if the operator should create PrometheusRules for this Tempo deployment
      serviceMonitors:                   # ServiceMonitors defines the ServiceMonitor configuration
        enabled: false

vs

spec:
  observability:                         # ObservabilitySpec defines how telemetry data gets handled.
    grafana:                             # Grafana defines the Grafana configuration for operands.
      createDatasource: false            # CreateDatasource specifies if a Grafana Datasource should be created for Tempo.
      instanceSelector:                  # InstanceSelector specifies the Grafana instance where the datasource should be created.
    metrics:                             # Metrics defines the metrics configuration for operands.
      createPrometheusRules: false       # CreatePrometheusRules specifies if Prometheus rules for alerts should be created for Tempo components.
      createServiceMonitors: false       # CreateServiceMonitors specifies if ServiceMonitors should be created for Tempo components.
    tracing:                             # Tracing defines a config for operands.
      jaeger_agent_endpoint: "localhost:6831" # JaegerAgentEndpoint defines the jaeger endpoint data gets send to.
      sampling_fraction: ""

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first example is consistent with the rest of the Monolithic CR, and allows additional settings for prometheusRules or serviceMonitors in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer consistency on the same CRD, just one question, in the future is possible to have some sort of consolidation in order to get both? That will imply a breaking change though

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was thinking of maybe doing this change in v1alpha2 of TempoStack if we have a consensus.


// ExtraConfig defines any extra (overlay) configuration for components
//
// +kubebuilder:validation:Optional
ExtraConfig *MonolithicExtraConfigSpec `json:"extraConfig,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for not reusing the same as microservices? The only reason I think is because the microservices could include other configs in the future. If that is the reason I'm ok

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we worked on the same feature at the same time. I'll check if I can reuse the struct and logic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the PR and reused the struct and logic from the TempoStack now.

}

// MonolithicStorageSpec defines the storage for the Tempo deployment.
type MonolithicStorageSpec struct {
Copy link
Collaborator

@rubenvp8510 rubenvp8510 Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question, Why this have it's own spec and inside only have one structure? or why to not use MonolithicTracesStorageSpec directly. Is this for mimic the tempo configuration?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's to mimic the tempo configuration. I thought maybe tempo has plans to store other things in the future, so I'll keep the same here also.

But I don't have very strong opinions on this, I could remove that extra layer if you like.

// Traces defines the backend storage configuration for traces
//
// +kubebuilder:validation:Required
Traces MonolithicTracesStorageSpec `json:"traces"`
}

// MonolithicTracesStorageSpec defines the traces storage for the Tempo deployment.
type MonolithicTracesStorageSpec struct {
// Backend defines the backend for storing traces
//
// +kubebuilder:validation:Required
Backend MonolithicTracesStorageBackend `json:"backend"`
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved

// WAL defines the write-ahead logging (WAL) configuration
//
// +kubebuilder:validation:Optional
WAL *MonolithicTracesStorageWALSpec `json:"wal,omitempty"`

// PV defines the Persistent Volume configuration
//
// +kubebuilder:validation:Optional
PV *MonolithicTracesStoragePVSpec `json:"pv,omitempty"`
}

// MonolithicTracesStorageBackend defines the backend storage for traces.
//
// +kubebuilder:validation:Enum=memory;pv
type MonolithicTracesStorageBackend string

const (
// MonolithicTracesStorageBackendMemory specifies a in-memory storage backend.
MonolithicTracesStorageBackendMemory MonolithicTracesStorageBackend = "memory"
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved
// MonolithicTracesStorageBackendPersistentVolume specifies a Persistent Volume storage backend.
MonolithicTracesStorageBackendPersistentVolume MonolithicTracesStorageBackend = "pv"
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved
)

// MonolithicTracesStorageWALSpec defines the write-ahead logging (WAL) configuration.
type MonolithicTracesStorageWALSpec struct {
// Size defines the size of the Persistent Volume for storing the WAL. Defaults to 10Gi.
//
// +kubebuilder:validation:Required
Size resource.Quantity `json:"size"`
}

// MonolithicTracesStoragePVSpec defines the Persistent Volume configuration.
type MonolithicTracesStoragePVSpec struct {
// Size defines the size of the Persistent Volume for storing the traces. Defaults to 10Gi.
//
// +kubebuilder:validation:Required
Size resource.Quantity `json:"size"`
}

// MonolithicIngestionSpec defines the ingestion settings.
type MonolithicIngestionSpec struct {
// OTLP defines the ingestion configuration for OTLP
//
// +kubebuilder:validation:Optional
OTLP *MonolithicIngestionOTLPSpec `json:"otlp,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be the only protocol supported?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to make the gateway a drop-in feature, so the service ports should not change if gateway is enabled or not. So I can only support protocols which the gateway also supports.
Afaics the gateway only supports otlp/grpc and otlp/http, right?

With the general move to the OTEL SDK, and using the OTEL collector, I think it's fine to only support OTLP.


// TLS defines the TLS configuration for ingestion
//
// +kubebuilder:validation:Optional
TLS *MonolithicIngestionTLSSpec `json:"tls,omitempty"`
}

// MonolithicIngestionOTLPSpec defines the settings for OTLP ingestion.
type MonolithicIngestionOTLPSpec struct {
// GRPC defines the OTLP/gRPC configuration
//
// +kubebuilder:validation:Optional
GRPC *MonolithicIngestionOTLPProtocolsGRPCSpec `json:"grpc,omitempty"`

// HTTP defines the OTLP/HTTP configuration
//
// +kubebuilder:validation:Optional
HTTP *MonolithicIngestionOTLPProtocolsHTTPSpec `json:"http,omitempty"`
}

// MonolithicIngestionOTLPProtocolsGRPCSpec defines the settings for OTLP ingestion over GRPC.
type MonolithicIngestionOTLPProtocolsGRPCSpec struct {
// Enabled defines if OTLP over gRPC is enabled
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicIngestionOTLPProtocolsHTTPSpec defines the settings for OTLP ingestion over HTTP.
type MonolithicIngestionOTLPProtocolsHTTPSpec struct {
// Enabled defines if OTLP over HTTP is enabled
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicIngestionTLSSpec defines the TLS settings for ingestion.
type MonolithicIngestionTLSSpec struct {
// Enabled defines if TLS is enabled for ingestion
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`

// CA defines the name of a secret containing the CA certificate
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
CA string `json:"ca"`

// Cert defines the name of a secret containing the TLS certificate and private key
andreasgerstmayr marked this conversation as resolved.
Show resolved Hide resolved
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Cert string `json:"cert"`
}

// MonolithicJaegerUISpec defines the settings for the Jaeger UI.
type MonolithicJaegerUISpec struct {
// Enabled defines if the Jaeger UI should be enabled
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`

// Ingress defines the ingress configuration for Jaeger UI
//
// +kubebuilder:validation:Optional
Ingress *MonolithicJaegerUIIngressSpec `json:"ingress,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be the ingress spec reused from the microservices? There are more settings users might want to configure

Copy link
Collaborator Author

@andreasgerstmayr andreasgerstmayr Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already ready in #755:

spec:
  jaegerui:                              # JaegerUI defines the Jaeger UI configuration
    enabled: false                       # Enabled defines if the Jaeger UI should be enabled
    ingress:                             # Ingress defines the ingress configuration for Jaeger UI
      annotations:                       # Annotations defines the annotations of the Ingress object.
        "key": ""
      enabled: false                     # Enabled defines if an Ingress object should be created for Jaeger UI
      host: ""                           # Host defines the hostname of the Ingress object.
      ingressClassName: ""               # IngressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource.
    route:                               # Route defines the route configuration for Jaeger UI
      annotations:                       # Annotations defines the annotations of the Ingress object.
        "key": ""
      enabled: false                     # Enabled defines if a Route object should be created for Jaeger UI
      host: ""                           # Host defines the hostname of the Ingress object.
      ingressClassName: ""               # IngressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource.
      termination: "edge"                # Termination specifies the termination type. Default: edge.

vs spec of TempoStack:

      jaegerQuery:                       # JaegerQuerySpec defines Jaeger Query specific options.
        enabled: false                   # Enabled is used to define if Jaeger Query component should be created.
        ingress:                         # Ingress defines Jaeger Query Ingress options.
          annotations:                   # Annotations defines the annotations of the Ingress object.
            "key": ""
          host: ""                       # Host defines the hostname of the Ingress object.
          ingressClassName: ""           # IngressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource.
          route:                         # Route defines OpenShift Route specific options.
            termination: ""              # Termination specifies the termination type. By default "edge" is used.
          type: ""                       # Type defines the type of Ingress for the Jaeger Query UI. Currently ingress, route and none are supported.

(ingressClassName should have been under ingress, as it doesn't apply to route)

Do we value we value consistency inside the same CR or consistency between the two CRs more?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment, I'd prefer consistency on the same CR


// Route defines the route configuration for Jaeger UI
//
// +kubebuilder:validation:Optional
Route *MonolithicJaegerUIRouteSpec `json:"route,omitempty"`
}

// MonolithicJaegerUIIngressSpec defines the settings for the Jaeger UI ingress.
type MonolithicJaegerUIIngressSpec struct {
// Enabled defines if an Ingress object should be created for Jaeger UI
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicJaegerUIRouteSpec defines the settings for the Jaeger UI route.
type MonolithicJaegerUIRouteSpec struct {
// Enabled defines if a Route object should be created for Jaeger UI
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicObservabilitySpec defines the observability settings of the Tempo deployment.
type MonolithicObservabilitySpec struct {
// Metrics defines the metrics configuration of the Tempo deployment
//
// +kubebuilder:validation:Optional
Metrics *MonolithicObservabilityMetricsSpec `json:"metrics,omitempty"`
}

// MonolithicObservabilityMetricsSpec defines the metrics settings of the Tempo deployment.
type MonolithicObservabilityMetricsSpec struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we reuse smth from the microservice type?

e.g. the whole observability spec

type ObservabilitySpec struct {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be inconsistent with the

<feature>:
  enabled: true

style of the CR. I'd prefer to migrate the TempoStack, maybe in the next CRD version? Shouldn't be too difficult to create a conversion webhook for this.

spec:                                    # TempoMonolithicSpec defines the desired state of TempoMonolithic.
  observability:                         # Observability defines observability configuration for the Tempo deployment
    metrics:                             # Metrics defines the metrics configuration of the Tempo deployment
      prometheusRules:                   # ServiceMonitors defines the PrometheusRule configuration
        enabled: false                   # Enabled defines if the operator should create PrometheusRules for this Tempo deployment
      serviceMonitors:                   # ServiceMonitors defines the ServiceMonitor configuration
        enabled: false                   # Enabled defines if the operator should create ServiceMonitors for this Tempo deployment

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we agreed on using the enabled field which is better supported in tools like kustomize and kubectl edit (the empty structs are removed). Are we going to reuse some parts from the monolithic APIs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can reuse a TLS struct, the multitenancy structs, ManagementStateType, LimitSpec and the storage secret.

// ServiceMonitors defines the ServiceMonitor configuration
//
// +kubebuilder:validation:Optional
ServiceMonitors *MonolithicObservabilityMetricsServiceMonitorsSpec `json:"serviceMonitors,omitempty"`

// ServiceMonitors defines the PrometheusRule configuration
//
// +kubebuilder:validation:Optional
PrometheusRules *MonolithicObservabilityMetricsPrometheusRulesSpec `json:"prometheusRules,omitempty"`
}

// MonolithicObservabilityMetricsServiceMonitorsSpec defines the ServiceMonitor settings.
type MonolithicObservabilityMetricsServiceMonitorsSpec struct {
// Enabled defines if the operator should create ServiceMonitors for this Tempo deployment
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicObservabilityMetricsPrometheusRulesSpec defines the PrometheusRules settings.
type MonolithicObservabilityMetricsPrometheusRulesSpec struct {
// Enabled defines if the operator should create PrometheusRules for this Tempo deployment
//
// +kubebuilder:validation:Required
Enabled bool `json:"enabled"`
}

// MonolithicExtraConfigSpec defines extra configuration for this deployment.
type MonolithicExtraConfigSpec struct {
// Tempo defines any extra Tempo configuration, which will be merged with the operator's generated Tempo configuration
// +kubebuilder:validation:Optional
Tempo apiextensionsv1.JSON `json:"tempo,omitempty"`
}

// TempoMonolithicStatus defines the observed state of TempoMonolithic.
type TempoMonolithicStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}

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

// TempoMonolithic is the Schema for the tempomonolithics API.
type TempoMonolithic struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec TempoMonolithicSpec `json:"spec,omitempty"`
Status TempoMonolithicStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// TempoMonolithicList contains a list of TempoMonolithic.
type TempoMonolithicList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []TempoMonolithic `json:"items"`
}

func init() {
SchemeBuilder.Register(&TempoMonolithic{}, &TempoMonolithicList{})
}
77 changes: 77 additions & 0 deletions apis/tempo/v1alpha1/tempomonolithic_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package v1alpha1

import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

// SetupWebhookWithManager will setup the manager to manage the webhooks.
func (r *TempoMonolithic) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}

// Default implements webhook.Defaulter so a webhook will be registered for the type.
func (r *TempoMonolithic) Default() {
log := ctrl.Log.WithName("tempomonolithic-webhook")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is this rendered in the logs? Isn't it too long?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll print this line:

{"level":"debug","ts":"2024-01-15T19:07:08.746058013+01:00","logger":"tempomonolithic-webhook","msg":"running defaulter webhook","name":"sample"}

if debug logs are enabled (go run ./main.go --zap-log-level=debug start).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But as we'll set the defaults in the reconcile loop now, I'm removing this log statement.

I'll keep it there for the validating webhook, which is still in use.

log.V(1).Info("running defaulter webhook", "name", r.Name)

if r.Spec.Storage == nil {
r.Spec.Storage = &MonolithicStorageSpec{}
}

if r.Spec.Storage.Traces.Backend == "" {
r.Spec.Storage.Traces.Backend = MonolithicTracesStorageBackendMemory
}

if r.Spec.Storage.Traces.Backend != MonolithicTracesStorageBackendMemory && r.Spec.Storage.Traces.WAL == nil {
r.Spec.Storage.Traces.WAL = &MonolithicTracesStorageWALSpec{
Size: tenGBQuantity,
}
}

if r.Spec.Storage.Traces.Backend == MonolithicTracesStorageBackendPersistentVolume && r.Spec.Storage.Traces.PV == nil {
r.Spec.Storage.Traces.PV = &MonolithicTracesStoragePVSpec{
Size: tenGBQuantity,
}
}

if r.Spec.Ingestion == nil {
r.Spec.Ingestion = &MonolithicIngestionSpec{
OTLP: &MonolithicIngestionOTLPSpec{
GRPC: &MonolithicIngestionOTLPProtocolsGRPCSpec{
Enabled: true,
},
},
}
}
}

//+kubebuilder:webhook:path=/validate-tempo-grafana-com-v1alpha1-tempomonolithic,mutating=false,failurePolicy=fail,sideEffects=None,groups=tempo.grafana.com,resources=tempomonolithics,verbs=create;update,versions=v1alpha1,name=vtempomonolithic.kb.io,admissionReviewVersions=v1

var _ webhook.Validator = &TempoMonolithic{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (r *TempoMonolithic) ValidateCreate() (admission.Warnings, error) {
return r.validate()
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (r *TempoMonolithic) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
return r.validate()
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
func (r *TempoMonolithic) ValidateDelete() (admission.Warnings, error) {
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
return r.validate()
}

func (r *TempoMonolithic) validate() (admission.Warnings, error) {
log := ctrl.Log.WithName("tempomonolithic-webhook")
log.V(1).Info("running validating webhook", "name", r.Name)
return nil, nil
}
Loading