diff --git a/.github/workflows/test_and_build_image.yaml b/.github/workflows/test_and_build_image.yaml index ff9998faa..1c7a3d185 100644 --- a/.github/workflows/test_and_build_image.yaml +++ b/.github/workflows/test_and_build_image.yaml @@ -37,6 +37,12 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- + - name: Install yq + run: | + sudo rm /bin/yq + wget https://github.com/mikefarah/yq/releases/download/v4.28.1/yq_linux_amd64.tar.gz + tar -xzf yq_linux_amd64.tar.gz + sudo mv ./yq_linux_amd64 /usr/bin/yq - name: Run unit and integration tests run: | export PATH=$GOROOT/bin:$GOPATH/bin:$PATH diff --git a/CHANGELOG/CHANGELOG-1.5.md b/CHANGELOG/CHANGELOG-1.5.md index 1c3062abf..69a0d4a18 100644 --- a/CHANGELOG/CHANGELOG-1.5.md +++ b/CHANGELOG/CHANGELOG-1.5.md @@ -15,15 +15,18 @@ When cutting a new release, update the `unreleased` heading to the tag being gen ## unreleased * [FEATURE] [#739815](https://github.com/k8ssandra/k8ssandra-operator/issues/815) Add configuration block to CRDs for new Cassandra metrics agent. +* [FEATURE] [#783](https://github.com/k8ssandra/k8ssandra-operator/issues/783) Allow disabling MCAC * [FEATURE] [#739](https://github.com/k8ssandra/k8ssandra-operator/issues/739) Add API for cluster-level tasks * [FEATURE] [#775](https://github.com/k8ssandra/k8ssandra-operator/issues/775) Add the ability to inject and configure a Vector agent sidecar in the Cassandra pods * [FEATURE] [#600](https://github.com/k8ssandra/k8ssandra-operator/issues/600) Disable secrets management and replication with the external secrets provider +* [ENHANCEMENT] [#817](https://github.com/k8ssandra/k8ssandra-operator/issues/817) Allow configuring the Vector agent sidecar in the CRD * [ENHANCEMENT] [#796](https://github.com/k8ssandra/k8ssandra-operator/issues/796) Enable smart token allocation by default for DSE * [ENHANCEMENT] [#765](https://github.com/k8ssandra/k8ssandra-operator/issues/765) Add GitHub workflow to test various k8s versions * [ENHANCEMENT] [#323](https://github.com/k8ssandra/k8ssandra/issues/323) Use Cassandra internals for JMX authentication * [ENHANCEMENT] [#770](https://github.com/k8ssandra/k8ssandra-operator/issues/770) Update to Go 1.19 and Operator SDK 1.25.2 * [ENHANCEMENT] [#525](https://github.com/k8ssandra/k8ssandra-operator/issues/525) Deep-merge cluster- and dc-level templates * [ENHANCEMENT] [#781](https://github.com/k8ssandra/k8ssandra-operator/issues/781) Expose perNodeConfigInitContainer.Image through CRD +* [ENHANCEMENT] [#783](https://github.com/k8ssandra/k8ssandra-operator/issues/783) Make ServiceAccount of Cassandra pods configurable * [BUGFIX] [#726](https://github.com/k8ssandra/k8ssandra-operator/issues/726) Don't propagate Cassandra tolerations to the Stargate deployment * [BUGFIX] [#778](https://github.com/k8ssandra/k8ssandra-operator/issues/778) Fix Stargate deployments on k8s clusters using a custom domain name * [TESTING] [#761](https://github.com/k8ssandra/k8ssandra-operator/issues/761) Stabilize integration and e2e tests diff --git a/apis/k8ssandra/v1alpha1/k8ssandracluster_types.go b/apis/k8ssandra/v1alpha1/k8ssandracluster_types.go index 2eaf9ff3e..3552585d4 100644 --- a/apis/k8ssandra/v1alpha1/k8ssandracluster_types.go +++ b/apis/k8ssandra/v1alpha1/k8ssandracluster_types.go @@ -419,6 +419,9 @@ type DatacenterOptions struct { // +optional // +kubebuilder:default="mikefarah/yq:4" PerNodeConfigInitContainerImage string `json:"perNodeConfigInitContainerImage,omitempty"` + + // The k8s service account to use for the Cassandra pods + ServiceAccount string `json:"serviceAccount,omitempty"` } // NetworkingConfig is a copy of cass-operator's NetworkingConfig struct. It is copied here to diff --git a/apis/telemetry/v1alpha1/telemetry_methods.go b/apis/telemetry/v1alpha1/telemetry_methods.go index 37c855521..e11202a4f 100644 --- a/apis/telemetry/v1alpha1/telemetry_methods.go +++ b/apis/telemetry/v1alpha1/telemetry_methods.go @@ -11,6 +11,10 @@ func (in *TelemetrySpec) IsPrometheusEnabled() bool { return in != nil && in.Prometheus != nil && in.Prometheus.Enabled != nil && *in.Prometheus.Enabled } +func (in *TelemetrySpec) IsMcacEnabled() bool { + return in == nil || in.Mcac == nil || in.Mcac.Enabled == nil || *in.Mcac.Enabled +} + func (in *TelemetrySpec) IsVectorEnabled() bool { return in != nil && in.Vector != nil && in.Vector.Enabled != nil && *in.Vector.Enabled } diff --git a/apis/telemetry/v1alpha1/telemetry_types.go b/apis/telemetry/v1alpha1/telemetry_types.go index e459ae1d9..a935ec012 100644 --- a/apis/telemetry/v1alpha1/telemetry_types.go +++ b/apis/telemetry/v1alpha1/telemetry_types.go @@ -28,13 +28,6 @@ type VectorSpec struct { // Enabling the vector agent will inject a sidecar container into the pod. Enabled *bool `json:"enabled,omitempty"` - // Config is the name of the configmap containing custom sinks and transformers for the Vector agent. - // The configmap must be in the same namespace as the CassandraDatacenter and contain a vector.toml entry - // with the Vector configuration in toml format. - // The agent is already configured with a "cassandra_metrics" source that needs to be used as input for the sinks. - // If not set, the default console sink will be used. - Config *corev1.LocalObjectReference `json:"config,omitempty"` - // Resources is the resource requirements for the Vector agent. Resources *corev1.ResourceRequirements `json:"resources,omitempty"` @@ -48,6 +41,66 @@ type VectorSpec struct { // +optional // kube:default=30s ScrapeInterval *metav1.Duration `json:"scrapeInterval,omitempty"` + + Components *VectorComponentsSpec `json:"components,omitempty"` +} + +type VectorComponentsSpec struct { + // Sources is the list of sources to use for the Vector agent. + // +optional + Sources []VectorSourceSpec `json:"sources,omitempty"` + + // Sinks is the list of sinks to use for the Vector agent. + // +optional + Sinks []VectorSinkSpec `json:"sinks,omitempty"` + + // Transforms is the list of transforms to use for the Vector agent. + // +optional + Transforms []VectorTransformSpec `json:"transforms,omitempty"` +} + +type VectorSourceSpec struct { + // Name is the name of the source. + Name string `json:"name"` + + // Type is the type of the source. + Type string `json:"type"` + + // Config is the configuration for the source. + // +optional + Config string `json:"config,omitempty"` +} + +type VectorSinkSpec struct { + // Name is the name of the sink. + Name string `json:"name"` + + // Type is the type of the sink. + Type string `json:"type"` + + // Inputs is the list of inputs for the transform. + // +optional + Inputs []string `json:"inputs,omitempty"` + + // Config is the configuration for the sink. + // +optional + Config string `json:"config,omitempty"` +} + +type VectorTransformSpec struct { + // Name is the name of the transform. + Name string `json:"name"` + + // Type is the type of the transform. + Type string `json:"type"` + + // Inputs is the list of inputs for the transform. + // +optional + Inputs []string `json:"inputs,omitempty"` + + // Config is the configuration for the transform. + // +optional + Config string `json:"config,omitempty"` } type McacTelemetrySpec struct { @@ -70,6 +123,10 @@ type McacTelemetrySpec struct { // Setting it to an empty list will result in all metrics being extracted. // +optional MetricFilters *[]string `json:"metricFilters,omitempty"` + + // enabled sets whether MCAC (legacy metrics endpoint) is enabled. + // This is considered true by default. + Enabled *bool `json:"enabled,omitempty"` } type CassandraAgentSpec struct { diff --git a/apis/telemetry/v1alpha1/zz_generated.deepcopy.go b/apis/telemetry/v1alpha1/zz_generated.deepcopy.go index bf3145cd9..54da6841b 100644 --- a/apis/telemetry/v1alpha1/zz_generated.deepcopy.go +++ b/apis/telemetry/v1alpha1/zz_generated.deepcopy.go @@ -77,6 +77,11 @@ func (in *McacTelemetrySpec) DeepCopyInto(out *McacTelemetrySpec) { copy(*out, *in) } } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new McacTelemetrySpec. @@ -151,6 +156,75 @@ func (in *TelemetrySpec) DeepCopy() *TelemetrySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VectorComponentsSpec) DeepCopyInto(out *VectorComponentsSpec) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]VectorSourceSpec, len(*in)) + copy(*out, *in) + } + if in.Sinks != nil { + in, out := &in.Sinks, &out.Sinks + *out = make([]VectorSinkSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Transforms != nil { + in, out := &in.Transforms, &out.Transforms + *out = make([]VectorTransformSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorComponentsSpec. +func (in *VectorComponentsSpec) DeepCopy() *VectorComponentsSpec { + if in == nil { + return nil + } + out := new(VectorComponentsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VectorSinkSpec) DeepCopyInto(out *VectorSinkSpec) { + *out = *in + if in.Inputs != nil { + in, out := &in.Inputs, &out.Inputs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorSinkSpec. +func (in *VectorSinkSpec) DeepCopy() *VectorSinkSpec { + if in == nil { + return nil + } + out := new(VectorSinkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VectorSourceSpec) DeepCopyInto(out *VectorSourceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorSourceSpec. +func (in *VectorSourceSpec) DeepCopy() *VectorSourceSpec { + if in == nil { + return nil + } + out := new(VectorSourceSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VectorSpec) DeepCopyInto(out *VectorSpec) { *out = *in @@ -159,11 +233,6 @@ func (in *VectorSpec) DeepCopyInto(out *VectorSpec) { *out = new(bool) **out = **in } - if in.Config != nil { - in, out := &in.Config, &out.Config - *out = new(v1.LocalObjectReference) - **out = **in - } if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = new(v1.ResourceRequirements) @@ -174,6 +243,11 @@ func (in *VectorSpec) DeepCopyInto(out *VectorSpec) { *out = new(metav1.Duration) **out = **in } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = new(VectorComponentsSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorSpec. @@ -185,3 +259,23 @@ func (in *VectorSpec) DeepCopy() *VectorSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VectorTransformSpec) DeepCopyInto(out *VectorTransformSpec) { + *out = *in + if in.Inputs != nil { + in, out := &in.Inputs, &out.Inputs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorTransformSpec. +func (in *VectorTransformSpec) DeepCopy() *VectorTransformSpec { + if in == nil { + return nil + } + out := new(VectorTransformSpec) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml b/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml index 184827e75..d0845b2ee 100644 --- a/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml +++ b/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml @@ -7748,6 +7748,10 @@ spec: and 4.0.X - DSE: 6.8.X' pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+) type: string + serviceAccount: + description: The k8s service account to use for the Cassandra + pods + type: string size: description: Size is the number Cassandra pods to deploy in this datacenter. This number does not include Stargate @@ -10865,6 +10869,11 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC + (legacy metrics endpoint) is enabled. + This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the @@ -10906,27 +10915,88 @@ spec: type: object vector: properties: - config: - description: Config is the name of the - configmap containing custom sinks and - transformers for the Vector agent. The - configmap must be in the same namespace - as the CassandraDatacenter and contain - a vector.toml entry with the Vector - configuration in toml format. The agent - is already configured with a "cassandra_metrics" - source that needs to be used as input - for the sinks. If not set, the default - console sink will be used. + components: properties: - name: - description: 'Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string + sinks: + description: Sinks is the list of + sinks to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the sink. + type: string + inputs: + description: Inputs is the list + of inputs for the transform. + items: + type: string + type: array + name: + description: Name is the name + of the sink. + type: string + type: + description: Type is the type + of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of + sources to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the source. + type: string + name: + description: Name is the name + of the source. + type: string + type: + description: Type is the type + of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list + of transforms to use for the Vector + agent. + items: + properties: + config: + description: Config is the configuration + for the transform. + type: string + inputs: + description: Inputs is the list + of inputs for the transform. + items: + type: string + type: array + name: + description: Name is the name + of the transform. + type: string + type: + description: Type is the type + of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, @@ -11314,6 +11384,11 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy + metrics endpoint) is enabled. This is considered + true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted @@ -11354,26 +11429,87 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap - containing custom sinks and transformers for - the Vector agent. The configmap must be in - the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector - configuration in toml format. The agent is - already configured with a "cassandra_metrics" - source that needs to be used as input for - the sinks. If not set, the default console - sink will be used. + components: properties: - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string + sinks: + description: Sinks is the list of sinks + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the sink. + type: string + inputs: + description: Inputs is the list of + inputs for the transform. + items: + type: string + type: array + name: + description: Name is the name of the + sink. + type: string + type: + description: Type is the type of the + sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the source. + type: string + name: + description: Name is the name of the + source. + type: string + type: + description: Type is the type of the + source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the transform. + type: string + inputs: + description: Inputs is the list of + inputs for the transform. + items: + type: string + type: array + name: + description: Name is the name of the + transform. + type: string + type: + description: Type is the type of the + transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). @@ -11960,6 +12096,11 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics + endpoint) is enabled. This is considered true + by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted @@ -11999,25 +12140,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap - containing custom sinks and transformers for the - Vector agent. The configmap must be in the same - namespace as the CassandraDatacenter and contain - a vector.toml entry with the Vector configuration - in toml format. The agent is already configured - with a "cassandra_metrics" source that needs to - be used as input for the sinks. If not set, the - default console sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string + sinks: + description: Sinks is the list of sinks to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the sink. + type: string + inputs: + description: Inputs is the list of inputs + for the transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration + for the transform. + type: string + inputs: + description: Inputs is the list of inputs + for the transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). @@ -15746,6 +15943,10 @@ spec: - DSE: 6.8.X' pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.\d+\.\d+) type: string + serviceAccount: + description: The k8s service account to use for the Cassandra + pods + type: string softPodAntiAffinity: description: SoftPodAntiAffinity sets whether multiple Cassandra instances can be scheduled on the same node. This should normally @@ -16211,6 +16412,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics + endpoint) is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. @@ -16248,23 +16453,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. - The configmap must be in the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector configuration - in toml format. The agent is already configured with - a "cassandra_metrics" source that needs to be used as - input for the sinks. If not set, the default console - sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the sink. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the transform. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling the @@ -18826,6 +19089,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics + endpoint) is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. @@ -18863,23 +19130,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. - The configmap must be in the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector configuration - in toml format. The agent is already configured with - a "cassandra_metrics" source that needs to be used as - input for the sinks. If not set, the default console - sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the sink. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the transform. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling the @@ -20433,6 +20758,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics + endpoint) is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. @@ -20470,23 +20799,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. - The configmap must be in the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector configuration - in toml format. The agent is already configured with - a "cassandra_metrics" source that needs to be used as - input for the sinks. If not set, the default console - sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the sink. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the transform. + type: string + inputs: + description: Inputs is the list of inputs for + the transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling the diff --git a/config/crd/bases/reaper.k8ssandra.io_reapers.yaml b/config/crd/bases/reaper.k8ssandra.io_reapers.yaml index de84ed593..ffb8c9e5b 100644 --- a/config/crd/bases/reaper.k8ssandra.io_reapers.yaml +++ b/config/crd/bases/reaper.k8ssandra.io_reapers.yaml @@ -2134,6 +2134,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics endpoint) + is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. Not @@ -2169,21 +2173,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. The - configmap must be in the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector configuration - in toml format. The agent is already configured with a "cassandra_metrics" - source that needs to be used as input for the sinks. If - not set, the default console sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for the + Vector agent. + items: + properties: + config: + description: Config is the configuration for the + sink. + type: string + inputs: + description: Inputs is the list of inputs for the + transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for the + source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for the + transform. + type: string + inputs: + description: Inputs is the list of inputs for the + transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling the vector agent diff --git a/config/crd/bases/stargate.k8ssandra.io_stargates.yaml b/config/crd/bases/stargate.k8ssandra.io_stargates.yaml index 082ad70ca..e630a422e 100644 --- a/config/crd/bases/stargate.k8ssandra.io_stargates.yaml +++ b/config/crd/bases/stargate.k8ssandra.io_stargates.yaml @@ -2825,6 +2825,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics + endpoint) is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. @@ -2863,23 +2867,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. - The configmap must be in the same namespace as the - CassandraDatacenter and contain a vector.toml entry - with the Vector configuration in toml format. The - agent is already configured with a "cassandra_metrics" - source that needs to be used as input for the sinks. - If not set, the default console sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the sink. + type: string + inputs: + description: Inputs is the list of inputs + for the transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms + to use for the Vector agent. + items: + properties: + config: + description: Config is the configuration for + the transform. + type: string + inputs: + description: Inputs is the list of inputs + for the transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling @@ -3227,6 +3289,10 @@ spec: type: object mcac: properties: + enabled: + description: enabled sets whether MCAC (legacy metrics endpoint) + is enabled. This is considered true by default. + type: boolean metricFilters: description: 'MetricFilters allows passing filters to MCAC in order to reduce the amount of extracted metrics. Not @@ -3262,21 +3328,81 @@ spec: type: object vector: properties: - config: - description: Config is the name of the configmap containing - custom sinks and transformers for the Vector agent. The - configmap must be in the same namespace as the CassandraDatacenter - and contain a vector.toml entry with the Vector configuration - in toml format. The agent is already configured with a "cassandra_metrics" - source that needs to be used as input for the sinks. If - not set, the default console sink will be used. + components: properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string + sinks: + description: Sinks is the list of sinks to use for the + Vector agent. + items: + properties: + config: + description: Config is the configuration for the + sink. + type: string + inputs: + description: Inputs is the list of inputs for the + transform. + items: + type: string + type: array + name: + description: Name is the name of the sink. + type: string + type: + description: Type is the type of the sink. + type: string + required: + - name + - type + type: object + type: array + sources: + description: Sources is the list of sources to use for + the Vector agent. + items: + properties: + config: + description: Config is the configuration for the + source. + type: string + name: + description: Name is the name of the source. + type: string + type: + description: Type is the type of the source. + type: string + required: + - name + - type + type: object + type: array + transforms: + description: Transforms is the list of transforms to use + for the Vector agent. + items: + properties: + config: + description: Config is the configuration for the + transform. + type: string + inputs: + description: Inputs is the list of inputs for the + transform. + items: + type: string + type: array + name: + description: Name is the name of the transform. + type: string + type: + description: Type is the type of the transform. + type: string + required: + - name + - type + type: object + type: array type: object - x-kubernetes-map-type: atomic enabled: description: Enabled enables the Vector agent for this resource (Cassandra, Reaper or Stargate). Enabling the vector agent diff --git a/pkg/cassandra/datacenter.go b/pkg/cassandra/datacenter.go index 4f0e4deaf..f877d7261 100644 --- a/pkg/cassandra/datacenter.go +++ b/pkg/cassandra/datacenter.go @@ -114,7 +114,9 @@ type DatacenterConfig struct { ManagementApiAuth *cassdcapi.ManagementApiAuthConfig PerNodeConfigMapRef corev1.LocalObjectReference PerNodeInitContainerImage string + ServiceAccount string ExternalSecrets bool + McacEnabled bool // InitialTokensByPodName is a list of initial tokens for the RF first pods in the cluster. It // is only populated when num_tokens < 16 in the whole cluster. Used for generating default @@ -125,6 +127,7 @@ type DatacenterConfig struct { const ( mgmtApiHeapSizeEnvVar = "MANAGEMENT_API_HEAP_SIZE" + mcacDisabledEnvVar = "MGMT_API_DISABLE_MCAC" ) func NewDatacenter(klusterKey types.NamespacedName, template *DatacenterConfig) (*cassdcapi.CassandraDatacenter, error) { @@ -171,6 +174,7 @@ func NewDatacenter(klusterKey types.NamespacedName, template *DatacenterConfig) PodTemplateSpec: &template.PodTemplateSpec, CDC: template.CDC, DseWorkloads: template.DseWorkloads, + ServiceAccount: template.ServiceAccount, }, } @@ -209,21 +213,34 @@ func NewDatacenter(klusterKey types.NamespacedName, template *DatacenterConfig) dc.Spec.Tolerations = template.Tolerations + if !template.McacEnabled { + // MCAC needs to be disabled + setMcacDisabled(dc, template) + } + return dc, nil } // setMgmtAPIHeap sets the management API heap size on a CassandraDatacenter func setMgmtAPIHeap(dc *cassdcapi.CassandraDatacenter, heapSize *resource.Quantity) { - if dc.Spec.PodTemplateSpec == nil { - dc.Spec.PodTemplateSpec = &corev1.PodTemplateSpec{} - } - UpdateCassandraContainer(dc.Spec.PodTemplateSpec, func(c *corev1.Container) { heapSizeInBytes := heapSize.Value() c.Env = append(c.Env, corev1.EnvVar{Name: mgmtApiHeapSizeEnvVar, Value: fmt.Sprintf("%v", heapSizeInBytes)}) }) } +func setMcacDisabled(dc *cassdcapi.CassandraDatacenter, template *DatacenterConfig) { + UpdateCassandraContainer(dc.Spec.PodTemplateSpec, func(c *corev1.Container) { + c.Env = append( + c.Env, + corev1.EnvVar{ + Name: mcacDisabledEnvVar, + Value: "true", + }, + ) + }) +} + // UpdateCassandraContainer finds the cassandra container, passes it to f, and then adds it // back to the PodTemplateSpec. The Container object is created if necessary before calling // f. Only the Name field is initialized. @@ -243,7 +260,7 @@ func UpdateVectorContainer(p *corev1.PodTemplateSpec, f func(c *corev1.Container // f. Only the Name field is initialized. func UpdateContainer(p *corev1.PodTemplateSpec, name string, f func(c *corev1.Container)) { idx, found := FindContainer(p, name) - container := &corev1.Container{} + var container *corev1.Container if !found { idx = len(p.Spec.Containers) @@ -324,6 +341,7 @@ func Coalesce(clusterName string, clusterTemplate *api.CassandraClusterTemplate, dcConfig.ManagementApiAuth = mergedOptions.ManagementApiAuth dcConfig.PodTemplateSpec.Spec.SecurityContext = mergedOptions.PodSecurityContext dcConfig.PerNodeInitContainerImage = mergedOptions.PerNodeConfigInitContainerImage + dcConfig.ServiceAccount = mergedOptions.ServiceAccount dcConfig.Meta.Metadata = goalesceutils.MergeCRs(clusterTemplate.Meta, dcTemplate.Meta.Metadata) @@ -344,6 +362,8 @@ func Coalesce(clusterName string, clusterTemplate *api.CassandraClusterTemplate, // we need to declare at least one container, otherwise the PodTemplateSpec struct will be invalid UpdateCassandraContainer(&dcConfig.PodTemplateSpec, func(c *corev1.Container) {}) + dcConfig.McacEnabled = mergedOptions.Telemetry.IsMcacEnabled() + return dcConfig } diff --git a/pkg/cassandra/datacenter_test.go b/pkg/cassandra/datacenter_test.go index 117892c3a..dd7bf1d5c 100644 --- a/pkg/cassandra/datacenter_test.go +++ b/pkg/cassandra/datacenter_test.go @@ -1,9 +1,10 @@ package cassandra import ( - "github.com/k8ssandra/cass-operator/pkg/reconciliation" "testing" + "github.com/k8ssandra/cass-operator/pkg/reconciliation" + "github.com/k8ssandra/k8ssandra-operator/pkg/images" "github.com/k8ssandra/k8ssandra-operator/pkg/meta" "github.com/k8ssandra/k8ssandra-operator/pkg/unstructured" @@ -15,6 +16,7 @@ import ( "github.com/Masterminds/semver/v3" cassdcapi "github.com/k8ssandra/cass-operator/apis/cassandra/v1beta1" api "github.com/k8ssandra/k8ssandra-operator/apis/k8ssandra/v1alpha1" + "github.com/k8ssandra/k8ssandra-operator/apis/telemetry/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -76,6 +78,7 @@ func TestCoalesce(t *testing.T) { Size: 3, AdditionalSeeds: []string{"172.18.0.8", "172.18.0.14"}, ServerType: "dse", + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -97,6 +100,7 @@ func TestCoalesce(t *testing.T) { }, want: &DatacenterConfig{ ServerVersion: semver.MustParse("4.0.1"), + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -118,6 +122,7 @@ func TestCoalesce(t *testing.T) { }, want: &DatacenterConfig{ ServerImage: "k8ssandra/cass-operator:dev", + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -154,6 +159,7 @@ func TestCoalesce(t *testing.T) { corev1.ResourceMemory: resource.MustParse("2048Mi"), }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -202,6 +208,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -229,6 +236,7 @@ func TestCoalesce(t *testing.T) { Networking: &cassdcapi.NetworkingConfig{ HostNetwork: true, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -272,6 +280,7 @@ func TestCoalesce(t *testing.T) { MaxHeapSize: parseQuantity("1024Mi"), }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -317,6 +326,7 @@ func TestCoalesce(t *testing.T) { Name: "rack3", }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -325,7 +335,7 @@ func TestCoalesce(t *testing.T) { }, }, { - name: "set management api heap size from DatacenterTemplate", + name: "set management api heap size and MCAC disabled from DatacenterTemplate", clusterName: "k8ssandra", clusterTemplate: &api.CassandraClusterTemplate{ SuperuserSecretRef: corev1.LocalObjectReference{Name: "test-superuser"}, @@ -345,6 +355,11 @@ func TestCoalesce(t *testing.T) { Size: 3, DatacenterOptions: api.DatacenterOptions{ MgmtAPIHeap: &mgmtAPIHeap, + Telemetry: &v1alpha1.TelemetrySpec{ + Mcac: &v1alpha1.McacTelemetrySpec{ + Enabled: pointer.Bool(false), + }, + }, }, }, want: &DatacenterConfig{ @@ -363,6 +378,7 @@ func TestCoalesce(t *testing.T) { SuperuserSecretRef: corev1.LocalObjectReference{Name: "test-superuser"}, Size: 3, MgmtAPIHeap: &mgmtAPIHeap, + McacEnabled: false, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -409,6 +425,7 @@ func TestCoalesce(t *testing.T) { SuperuserSecretRef: corev1.LocalObjectReference{Name: "test-superuser"}, Size: 3, MgmtAPIHeap: &mgmtAPIHeap, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -430,6 +447,7 @@ func TestCoalesce(t *testing.T) { }, want: &DatacenterConfig{ JmxInitContainerImage: &images.Image{Name: "dc-image"}, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -444,7 +462,8 @@ func TestCoalesce(t *testing.T) { Stopped: true, }, want: &DatacenterConfig{ - Stopped: true, + Stopped: true, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -466,6 +485,7 @@ func TestCoalesce(t *testing.T) { }, dcTemplate: &api.CassandraDatacenterTemplate{}, want: &DatacenterConfig{ + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ @@ -507,6 +527,7 @@ func TestCoalesce(t *testing.T) { }, dcTemplate: &api.CassandraDatacenterTemplate{}, want: &DatacenterConfig{ + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ @@ -558,6 +579,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -642,6 +664,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ @@ -681,6 +704,7 @@ func TestCoalesce(t *testing.T) { }, want: &DatacenterConfig{ DseWorkloads: &cassdcapi.DseWorkloads{AnalyticsEnabled: true, GraphEnabled: true}, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -764,6 +788,7 @@ func TestCoalesce(t *testing.T) { }, }, want: &DatacenterConfig{ + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ @@ -855,6 +880,7 @@ func TestCoalesce(t *testing.T) { }, }, want: &DatacenterConfig{ + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -897,6 +923,7 @@ func TestCoalesce(t *testing.T) { }, want: &DatacenterConfig{ PerNodeInitContainerImage: "dc-level:latest", + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -934,6 +961,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"label": "lvalue"}, @@ -978,6 +1006,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"label": "lvalue"}, @@ -1022,6 +1051,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"label": "dcvalue", "cluster": "cluster", "dc": "dc"}, @@ -1098,6 +1128,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -1172,6 +1203,7 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -1264,6 +1296,29 @@ func TestCoalesce(t *testing.T) { }, }, }, + McacEnabled: true, + PodTemplateSpec: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{Name: "cassandra"}}, + }, + }, + }, + }, + { + name: "Override service account", + clusterTemplate: &api.CassandraClusterTemplate{ + DatacenterOptions: api.DatacenterOptions{ + ServiceAccount: "cluster_account", + }, + }, + dcTemplate: &api.CassandraDatacenterTemplate{ + DatacenterOptions: api.DatacenterOptions{ + ServiceAccount: "dc_account", + }, + }, + want: &DatacenterConfig{ + ServiceAccount: "dc_account", + McacEnabled: true, PodTemplateSpec: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{{Name: "cassandra"}}, @@ -1295,6 +1350,28 @@ func TestNewDatacenter_MgmtAPIHeapSize_Set(t *testing.T) { assert.Equal(t, dc.Spec.PodTemplateSpec.Spec.Containers[0].Env[0].Value, "999000000") } +func TestNewDatacenter_McacDisabled_Set(t *testing.T) { + template := GetDatacenterConfig() + template.McacEnabled = false + dc, err := NewDatacenter( + types.NamespacedName{Name: "testdc", Namespace: "test-namespace"}, + &template, + ) + assert.Equal(t, err, nil) + cassContainerIdx, found := FindContainer(dc.Spec.PodTemplateSpec, "cassandra") + if !found { + assert.Fail(t, "could not find cassandra container") + } + + found = false + for _, envVar := range dc.Spec.PodTemplateSpec.Spec.Containers[cassContainerIdx].Env { + if envVar.Name == mcacDisabledEnvVar { + found = true + } + } + assert.True(t, found, "could not find expected MCAC disabled environment variable") +} + // TestNewDatacenter_MgmtAPIHeapSize_Unset tests that the podTemplateSpec remains empty when no management API heap size is set. func TestNewDatacenter_MgmtAPIHeapSize_Unset(t *testing.T) { template := GetDatacenterConfig() @@ -1333,6 +1410,17 @@ func TestNewDatacenter_Tolerations(t *testing.T) { assert.Equal(t, template.Tolerations, dc.Spec.Tolerations) } +func TestNewDatacenter_ServiceAccount(t *testing.T) { + template := GetDatacenterConfig() + template.ServiceAccount = "svc" + dc, err := NewDatacenter( + types.NamespacedName{Name: "testdc", Namespace: "test-namespace"}, + &template, + ) + assert.NoError(t, err) + assert.Equal(t, template.ServiceAccount, dc.Spec.ServiceAccount) +} + // TestValidateCoalesced_Fail_NoStorageConfig tests that NewDatacenter fails when no storage config is provided. func TestValidateDatacenterConfig_Fail_NoStorageConfig(t *testing.T) { template := GetDatacenterConfig() @@ -1448,5 +1536,6 @@ func GetDatacenterConfig() DatacenterConfig { }, }, }, + McacEnabled: true, } } diff --git a/pkg/telemetry/vector.go b/pkg/telemetry/vector.go index a006188d0..c742ad9a1 100644 --- a/pkg/telemetry/vector.go +++ b/pkg/telemetry/vector.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "strings" "text/template" "github.com/go-logr/logr" @@ -13,7 +14,6 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -97,7 +97,7 @@ type VectorConfig struct { } func CreateCassandraVectorToml(ctx context.Context, telemetrySpec *telemetry.TelemetrySpec, remoteClient client.Client, namespace string) (string, error) { - sinks := ` + vectorConfigToml := ` [sinks.console] type = "console" inputs = [ "cassandra_metrics" ] @@ -106,19 +106,9 @@ target = "stdout" [sinks.console.encoding] codec = "json"` - if telemetrySpec.Vector.Config != nil { - // Read the Vector provided config map content and use it as the Vector sink config - vectorConfigMap := &corev1.ConfigMap{} - err := remoteClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: telemetrySpec.Vector.Config.Name}, vectorConfigMap) - if err != nil { - return "", err - } else { - if toml, found := vectorConfigMap.Data["vector.toml"]; found { - sinks = toml - } else { - return "", fmt.Errorf("vector.toml not found in config map %s", telemetrySpec.Vector.Config.Name) - } - } + if telemetrySpec.Vector.Components != nil { + // Vector components are provided in the Telemetry spec, build the Vector sink config from them + vectorConfigToml = BuildCustomVectorToml(telemetrySpec) } var scrapeInterval int32 = DefaultScrapeInterval @@ -127,7 +117,7 @@ target = "stdout" } config := VectorConfig{ - Sinks: sinks, + Sinks: vectorConfigToml, ScrapePort: CassandraMetricsPort, ScrapeInterval: scrapeInterval, } @@ -158,6 +148,37 @@ scrape_interval_secs = {{ .ScrapeInterval }} return vectorToml.String(), nil } +func BuildCustomVectorToml(telemetrySpec *telemetry.TelemetrySpec) string { + vectorConfigToml := "" + for _, source := range telemetrySpec.Vector.Components.Sources { + vectorConfigToml += fmt.Sprintf("\n[sources.%s]\n", source.Name) + vectorConfigToml += fmt.Sprintf("type = \"%s\"\n", source.Type) + if source.Config != "" { + vectorConfigToml += source.Config + "\n" + } + } + + for _, transform := range telemetrySpec.Vector.Components.Transforms { + vectorConfigToml += fmt.Sprintf("\n[transforms.%s]\n", transform.Name) + vectorConfigToml += fmt.Sprintf("type = \"%s\"\n", transform.Type) + vectorConfigToml += fmt.Sprintf("inputs = [\"%s\"]\n", strings.Join(transform.Inputs, "\", \"")) + if transform.Config != "" { + vectorConfigToml += transform.Config + "\n" + } + } + + for _, sink := range telemetrySpec.Vector.Components.Sinks { + vectorConfigToml += fmt.Sprintf("\n[sinks.%s]\n", sink.Name) + vectorConfigToml += fmt.Sprintf("type = \"%s\"\n", sink.Type) + vectorConfigToml += fmt.Sprintf("inputs = [\"%s\"]\n", strings.Join(sink.Inputs, "\", \"")) + if sink.Config != "" { + vectorConfigToml += sink.Config + "\n" + } + } + + return vectorConfigToml +} + func BuildVectorAgentConfigMap(namespace, k8cName, dcName, k8cNamespace, vectorToml string) *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/telemetry/vector_test.go b/pkg/telemetry/vector_test.go index f0064b0b6..b1717a3f1 100644 --- a/pkg/telemetry/vector_test.go +++ b/pkg/telemetry/vector_test.go @@ -55,3 +55,110 @@ func TestBuildVectorAgentConfigMap(t *testing.T) { assert.Equal(t, "k8ssandra-dc1-cass-vector", vectorConfigMap.Name) assert.Equal(t, "k8ssandra-operator", vectorConfigMap.Namespace) } + +func TestBuildVectorToml(t *testing.T) { + tests := []struct { + name string + tspec *telemetry.TelemetrySpec + want string + }{ + { + "Single sink", + &telemetry.TelemetrySpec{ + Vector: &telemetry.VectorSpec{ + Enabled: pointer.Bool(true), + Components: &telemetry.VectorComponentsSpec{ + Sinks: []telemetry.VectorSinkSpec{ + { + Name: "console_sink", + Type: "console", + Inputs: []string{ + "test", + "test2", + }, + }, + }, + }, + }, + }, + ` +[sinks.console_sink] +type = "console" +inputs = ["test", "test2"] +`, + }, + { + "Source, sink and transform", + &telemetry.TelemetrySpec{ + Vector: &telemetry.VectorSpec{ + Enabled: pointer.Bool(true), + Components: &telemetry.VectorComponentsSpec{ + Sources: []telemetry.VectorSourceSpec{ + { + Name: "custom_source", + Type: "whatever", + Config: `foo = "bar" +baz = 1`, + }, + }, + Transforms: []telemetry.VectorTransformSpec{ + { + Name: "custom_transform1", + Type: "remap", + Inputs: []string{"custom_source"}, + Config: `foo = "bar" +baz = 2`, + }, + { + Name: "custom_transform2", + Type: "remap", + Inputs: []string{"custom_transform1"}, + Config: `foo = "bar" +baz = 3 +bulk.index = "vector-%Y-%m-%d"`, + }, + }, + Sinks: []telemetry.VectorSinkSpec{ + { + Name: "console_sink", + Type: "console", + Inputs: []string{ + "test", + "test2", + }, + }, + }, + }, + }, + }, ` +[sources.custom_source] +type = "whatever" +foo = "bar" +baz = 1 + +[transforms.custom_transform1] +type = "remap" +inputs = ["custom_source"] +foo = "bar" +baz = 2 + +[transforms.custom_transform2] +type = "remap" +inputs = ["custom_transform1"] +foo = "bar" +baz = 3 +bulk.index = "vector-%Y-%m-%d" + +[sinks.console_sink] +type = "console" +inputs = ["test", "test2"] +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := BuildCustomVectorToml(tt.tspec) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/test/e2e/suite_test.go b/test/e2e/suite_test.go index d04482c98..9bb8dce18 100644 --- a/test/e2e/suite_test.go +++ b/test/e2e/suite_test.go @@ -975,8 +975,6 @@ func createStargateAndDatacenter(t *testing.T, ctx context.Context, namespace st func createMultiDatacenterCluster(t *testing.T, ctx context.Context, namespace string, f *framework.E2eFramework) { require := require.New(t) - f.DeployVectorConfigMap(namespace) - t.Log("check that the K8ssandraCluster was created") k8ssandra := &api.K8ssandraCluster{} kcKey := client.ObjectKey{Namespace: namespace, Name: "test"} diff --git a/test/kuttl/test-servicemonitors/03-assert.yaml b/test/kuttl/test-servicemonitors/03-assert.yaml index 7751e2434..af0fae55d 100644 --- a/test/kuttl/test-servicemonitors/03-assert.yaml +++ b/test/kuttl/test-servicemonitors/03-assert.yaml @@ -3,6 +3,36 @@ kind: StatefulSet metadata: name: test-dc1-default-sts namespace: k8ssandra-operator +spec: + template: + spec: + containers: + - name: cassandra + env: + - name: LOCAL_JMX + value: "no" + - name: METRIC_FILTERS + value: >- + deny:org.apache.cassandra.metrics.Table deny:org.apache.cassandra.metrics.table + allow:org.apache.cassandra.metrics.table.live_ss_table_count allow:org.apache.cassandra.metrics.Table.LiveSSTableCount + allow:org.apache.cassandra.metrics.table.live_disk_space_used allow:org.apache.cassandra.metrics.table.LiveDiskSpaceUsed + allow:org.apache.cassandra.metrics.Table.Pending allow:org.apache.cassandra.metrics.Table.Memtable + allow:org.apache.cassandra.metrics.Table.Compaction allow:org.apache.cassandra.metrics.table.read + allow:org.apache.cassandra.metrics.table.write allow:org.apache.cassandra.metrics.table.range + allow:org.apache.cassandra.metrics.table.coordinator allow:org.apache.cassandra.metrics.table.dropped_mutations + - name: MGMT_API_DISABLE_MCAC + value: "true" + - name: DS_LICENSE + value: accept + - name: DSE_AUTO_CONF_OFF + value: all + - name: USE_MGMT_API + value: "true" + - name: MGMT_API_EXPLICIT_START + value: "true" + - name: DSE_MGMT_EXPLICIT_START + value: "true" + - name: server-system-logger status: readyReplicas: 1 --- diff --git a/test/kuttl/test-servicemonitors/config/single-node-k8ssandra/kustomization.yaml b/test/kuttl/test-servicemonitors/config/single-node-k8ssandra/kustomization.yaml index 61a5421cc..a4baa7836 100644 --- a/test/kuttl/test-servicemonitors/config/single-node-k8ssandra/kustomization.yaml +++ b/test/kuttl/test-servicemonitors/config/single-node-k8ssandra/kustomization.yaml @@ -23,6 +23,8 @@ patches: enabled: true commonLabels: test-label: gobbledegook + mcac: + enabled: false - op: add path: /spec/reaper value: diff --git a/test/testdata/fixtures/multi-dc/k8ssandra.yaml b/test/testdata/fixtures/multi-dc/k8ssandra.yaml index 727cbfa5f..9095eb206 100644 --- a/test/testdata/fixtures/multi-dc/k8ssandra.yaml +++ b/test/testdata/fixtures/multi-dc/k8ssandra.yaml @@ -16,8 +16,22 @@ spec: telemetry: vector: enabled: true - config: - name: vector-custom-conf + components: + transforms: + - name: my-transform + type: remap + inputs: + - cassandra_metrics + config: |- + source = ".tags.host = get_hostname!()" + sinks: + - name: console + inputs: + - my-transform + type: console + config: |- + [sinks.console.encoding] + codec = "json" resources: requests: cpu: 100m diff --git a/test/testdata/fixtures/single-dc/k8ssandra.yaml b/test/testdata/fixtures/single-dc/k8ssandra.yaml index fc2b24322..99ca158ff 100644 --- a/test/testdata/fixtures/single-dc/k8ssandra.yaml +++ b/test/testdata/fixtures/single-dc/k8ssandra.yaml @@ -9,8 +9,12 @@ spec: telemetry: vector: enabled: true - config: - name: vector-custom-conf + components: + sinks: + - name: void + type: blackhole + inputs: + - cassandra_metrics scrapeInterval: 30s resources: requests: diff --git a/test/testdata/fixtures/vector-custom-config.yaml b/test/testdata/fixtures/vector-custom-config.yaml deleted file mode 100644 index 62991d938..000000000 --- a/test/testdata/fixtures/vector-custom-config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: vector-custom-conf -data: - vector.toml: | - [sinks.void] - type = "blackhole" - inputs = [ "cassandra_metrics" ] \ No newline at end of file