diff --git a/api/v1beta1/additional.go b/api/v1beta1/additional.go index 181f5912..fbd1859f 100644 --- a/api/v1beta1/additional.go +++ b/api/v1beta1/additional.go @@ -579,14 +579,39 @@ func (l *License) IsProvided() bool { return l.Key != nil || l.KeyRef != nil } -// RequiresVolumeMounts returns true if license requires volume mounts. -// Volume mount is required to pass license key content from secret to container. -func (l *License) RequiresVolumeMounts() bool { - if !l.IsProvided() { - return false +// MaybeAddToArgs conditionally adds license commandline args into given args +func (l *License) MaybeAddToArgs(args []string, secretMountDir string) []string { + if l == nil || !l.IsProvided() { + return args + } + if l.Key != nil { + args = append(args, fmt.Sprintf("-license=%s", *l.Key)) + } + if l.KeyRef != nil { + args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(secretMountDir, l.KeyRef.Name, l.KeyRef.Key))) } + return args +} - return l.KeyRef != nil +// MaybeAddToVolumes conditionally mounts secret with license key into given volumes and mounts +func (l *License) MaybeAddToVolumes(volumes []v1.Volume, mounts []v1.VolumeMount, secretMountDir string) ([]v1.Volume, []v1.VolumeMount) { + if l == nil || l.KeyRef == nil { + return volumes, mounts + } + volumes = append(volumes, v1.Volume{ + Name: "license", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: l.KeyRef.Name, + }, + }, + }) + mounts = append(mounts, v1.VolumeMount{ + Name: "license", + ReadOnly: true, + MountPath: path.Join(secretMountDir, l.KeyRef.Name), + }) + return volumes, mounts } func (l *License) sanityCheck() error { diff --git a/api/v1beta1/vmauth_types.go b/api/v1beta1/vmauth_types.go index 38774104..3a6caeca 100644 --- a/api/v1beta1/vmauth_types.go +++ b/api/v1beta1/vmauth_types.go @@ -187,6 +187,11 @@ type VMAuthSpec struct { // drops not needed security permissions // +optional UseStrictSecurity *bool `json:"useStrictSecurity,omitempty"` + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` } // VMAuthUnauthorizedPath defines url_map for unauthorized access diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 29679906..f7904379 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -3571,6 +3571,11 @@ func (in *VMAuthSpec) DeepCopyInto(out *VMAuthSpec) { *out = new(bool) **out = **in } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAuthSpec. diff --git a/api/victoriametrics/v1beta1/additional.go b/api/victoriametrics/v1beta1/additional.go index 2718b580..4304302f 100644 --- a/api/victoriametrics/v1beta1/additional.go +++ b/api/victoriametrics/v1beta1/additional.go @@ -556,3 +556,72 @@ func (m *StringOrArray) UnmarshalJSON(data []byte) error { return &json.UnmarshalTypeError{Value: string(data), Type: rawType} } } + +// License holds license key for enterprise features. +// Using license key is supported starting from VictoriaMetrics v1.94.0 +// See: https://docs.victoriametrics.com/enterprise.html +type License struct { + // Enterprise license key. This flag is available only in VictoriaMetrics enterprise. + // Documentation - https://docs.victoriametrics.com/enterprise.html + // for more information, visit https://victoriametrics.com/products/enterprise/ . + // To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ + Key *string `json:"key,omitempty"` + // KeyRef is reference to secret with license key for enterprise features. + KeyRef *v1.SecretKeySelector `json:"keyRef,omitempty"` +} + +// IsProvided returns true if license is provided. +func (l *License) IsProvided() bool { + if l == nil { + return false + } + + return l.Key != nil || l.KeyRef != nil +} + +// MaybeAddToArgs conditionally adds license commandline args into given args +func (l *License) MaybeAddToArgs(args []string, secretMountDir string) []string { + if !l.IsProvided() { + return args + } + if l.Key != nil { + args = append(args, fmt.Sprintf("-license=%s", *l.Key)) + } + if l.KeyRef != nil { + args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(secretMountDir, l.KeyRef.Name, l.KeyRef.Key))) + } + return args +} + +// MaybeAddToVolumes conditionally mounts secret with license key into given volumes and mounts +func (l *License) MaybeAddToVolumes(volumes []v1.Volume, mounts []v1.VolumeMount, secretMountDir string) ([]v1.Volume, []v1.VolumeMount) { + if l.KeyRef == nil { + return volumes, mounts + } + volumes = append(volumes, v1.Volume{ + Name: "license", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: l.KeyRef.Name, + }, + }, + }) + mounts = append(mounts, v1.VolumeMount{ + Name: "license", + ReadOnly: true, + MountPath: path.Join(secretMountDir, l.KeyRef.Name), + }) + return volumes, mounts +} + +func (l *License) sanityCheck() error { + if !l.IsProvided() { + return nil + } + + if l.Key != nil && l.KeyRef != nil { + return fmt.Errorf("only one of key or keyRef can be specified") + } + + return nil +} diff --git a/api/victoriametrics/v1beta1/vmagent_types.go b/api/victoriametrics/v1beta1/vmagent_types.go index 993a88ba..b3fea62d 100644 --- a/api/victoriametrics/v1beta1/vmagent_types.go +++ b/api/victoriametrics/v1beta1/vmagent_types.go @@ -388,6 +388,12 @@ type VMAgentSpec struct { // drops not needed security permissions // +optional UseStrictSecurity *bool `json:"useStrictSecurity,omitempty"` + + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` } // UnmarshalJSON implements json.Unmarshaler interface diff --git a/api/victoriametrics/v1beta1/vmalert_types.go b/api/victoriametrics/v1beta1/vmalert_types.go index 8ff13412..70391c68 100644 --- a/api/victoriametrics/v1beta1/vmalert_types.go +++ b/api/victoriametrics/v1beta1/vmalert_types.go @@ -260,6 +260,12 @@ type VMAlertSpec struct { // drops not needed security permissions // +optional UseStrictSecurity *bool `json:"useStrictSecurity,omitempty"` + + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` } // UnmarshalJSON implements json.Unmarshaler interface diff --git a/api/victoriametrics/v1beta1/vmauth_types.go b/api/victoriametrics/v1beta1/vmauth_types.go index 38774104..3a6caeca 100644 --- a/api/victoriametrics/v1beta1/vmauth_types.go +++ b/api/victoriametrics/v1beta1/vmauth_types.go @@ -187,6 +187,11 @@ type VMAuthSpec struct { // drops not needed security permissions // +optional UseStrictSecurity *bool `json:"useStrictSecurity,omitempty"` + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` } // VMAuthUnauthorizedPath defines url_map for unauthorized access diff --git a/api/victoriametrics/v1beta1/vmcluster_types.go b/api/victoriametrics/v1beta1/vmcluster_types.go index 2b37e9df..cd084260 100644 --- a/api/victoriametrics/v1beta1/vmcluster_types.go +++ b/api/victoriametrics/v1beta1/vmcluster_types.go @@ -57,6 +57,13 @@ type VMClusterSpec struct { // see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod // +optional ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` + // +optional VMSelect *VMSelect `json:"vmselect,omitempty"` // +optional @@ -686,6 +693,7 @@ type VMBackup struct { // AcceptEULA accepts enterprise feature usage, must be set to true. // otherwise backupmanager cannot be added to single/cluster version. // https://victoriametrics.com/legal/esa/ + // +optional AcceptEULA bool `json:"acceptEULA"` // SnapshotCreateURL overwrites url for snapshot create // +optional @@ -759,6 +767,18 @@ type VMBackup struct { Restore *VMRestore `json:"restore,omitempty"` } +func (cr *VMBackup) sanityCheck(l *License) error { + if !l.IsProvided() && !cr.AcceptEULA { + return fmt.Errorf("it is required to provide license key. See: https://docs.victoriametrics.com/enterprise.html") + } + + if l.IsProvided() { + return l.sanityCheck() + } + + return nil +} + type VMRestore struct { // OnStart defines configuration for restore on pod start // +optional diff --git a/api/victoriametrics/v1beta1/vmcluster_webhook.go b/api/victoriametrics/v1beta1/vmcluster_webhook.go index 0bf740ce..00b727f4 100644 --- a/api/victoriametrics/v1beta1/vmcluster_webhook.go +++ b/api/victoriametrics/v1beta1/vmcluster_webhook.go @@ -41,6 +41,12 @@ func (r *VMCluster) sanityCheck() error { } } } + if r.Spec.VMStorage != nil && r.Spec.VMStorage.VMBackup != nil { + if err := r.Spec.VMStorage.VMBackup.sanityCheck(r.Spec.License); err != nil { + return err + } + } + return nil } diff --git a/api/victoriametrics/v1beta1/vmsingle_types.go b/api/victoriametrics/v1beta1/vmsingle_types.go index 7f35a8ed..2033d546 100644 --- a/api/victoriametrics/v1beta1/vmsingle_types.go +++ b/api/victoriametrics/v1beta1/vmsingle_types.go @@ -176,6 +176,11 @@ type VMSingleSpec struct { // VMBackup configuration for backup // +optional VMBackup *VMBackup `json:"vmBackup,omitempty"` + // License allows to configure license key to be used for enterprise features. + // Using license key is supported starting from VictoriaMetrics v1.94.0. + // See: https://docs.victoriametrics.com/enterprise.html + // +optional + License *License `json:"license,omitempty"` // ExtraArgs that will be passed to VMSingle pod // for example remoteWrite.tmpDataPath: /tmp // +optional diff --git a/api/victoriametrics/v1beta1/vmsingle_webhook.go b/api/victoriametrics/v1beta1/vmsingle_webhook.go index 867804a3..bd6ac841 100644 --- a/api/victoriametrics/v1beta1/vmsingle_webhook.go +++ b/api/victoriametrics/v1beta1/vmsingle_webhook.go @@ -22,7 +22,12 @@ func (r *VMSingle) SetupWebhookWithManager(mgr ctrl.Manager) error { var _ webhook.Validator = &VMSingle{} func (r *VMSingle) sanityCheck() error { - // todo add some checks. + if r.Spec.VMBackup != nil { + if err := r.Spec.VMBackup.sanityCheck(r.Spec.License); err != nil { + return err + } + } + return nil } diff --git a/api/victoriametrics/v1beta1/zz_generated.deepcopy.go b/api/victoriametrics/v1beta1/zz_generated.deepcopy.go index 63fb4157..f7904379 100644 --- a/api/victoriametrics/v1beta1/zz_generated.deepcopy.go +++ b/api/victoriametrics/v1beta1/zz_generated.deepcopy.go @@ -709,6 +709,31 @@ func (in *InsertPorts) DeepCopy() *InsertPorts { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *License) DeepCopyInto(out *License) { + *out = *in + if in.Key != nil { + in, out := &in.Key, &out.Key + *out = new(string) + **out = **in + } + if in.KeyRef != nil { + in, out := &in.KeyRef, &out.KeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new License. +func (in *License) DeepCopy() *License { + if in == nil { + return nil + } + out := new(License) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LinkConfig) DeepCopyInto(out *LinkConfig) { *out = *in @@ -2493,6 +2518,11 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(bool) **out = **in } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAgentSpec. @@ -2881,6 +2911,11 @@ func (in *VMAlertSpec) DeepCopyInto(out *VMAlertSpec) { *out = new(bool) **out = **in } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAlertSpec. @@ -3536,6 +3571,11 @@ func (in *VMAuthSpec) DeepCopyInto(out *VMAuthSpec) { *out = new(bool) **out = **in } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAuthSpec. @@ -3749,6 +3789,11 @@ func (in *VMClusterSpec) DeepCopyInto(out *VMClusterSpec) { *out = make([]v1.LocalObjectReference, len(*in)) copy(*out, *in) } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } if in.VMSelect != nil { in, out := &in.VMSelect, &out.VMSelect *out = new(VMSelect) @@ -5119,6 +5164,11 @@ func (in *VMSingleSpec) DeepCopyInto(out *VMSingleSpec) { *out = new(VMBackup) (*in).DeepCopyInto(*out) } + if in.License != nil { + in, out := &in.License, &out.License + *out = new(License) + (*in).DeepCopyInto(*out) + } if in.ExtraArgs != nil { in, out := &in.ExtraArgs, &out.ExtraArgs *out = make(map[string]string, len(*in)) diff --git a/config/crd/bases/operator.victoriametrics.com_vmagents.yaml b/config/crd/bases/operator.victoriametrics.com_vmagents.yaml index ecb2b738..47eaea60 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmagents.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmagents.yaml @@ -885,7 +885,6 @@ spec: in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html for more information, visit https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ - . type: string keyRef: description: KeyRef is reference to secret with license key for diff --git a/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml b/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml index 7f2c5244..98b7c02d 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml @@ -397,7 +397,6 @@ spec: in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html for more information, visit https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ - . type: string keyRef: description: KeyRef is reference to secret with license key for diff --git a/config/crd/bases/operator.victoriametrics.com_vmauths.yaml b/config/crd/bases/operator.victoriametrics.com_vmauths.yaml index 8556630f..5d9bfe7a 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmauths.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmauths.yaml @@ -428,6 +428,38 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true type: array + license: + description: 'License allows to configure license key to be used for + enterprise features. Using license key is supported starting from + VictoriaMetrics v1.94.0. See: https://docs.victoriametrics.com/enterprise.html' + properties: + key: + description: Enterprise license key. This flag is available only + in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html + for more information, visit https://victoriametrics.com/products/enterprise/ + . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ + type: string + keyRef: + description: KeyRef is reference to secret with license key for + enterprise features. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object livenessProbe: description: LivenessProbe that will be added CRD pod type: object diff --git a/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml b/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml index ee704652..37400348 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml @@ -87,7 +87,6 @@ spec: in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html for more information, visit https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ - . type: string keyRef: description: KeyRef is reference to secret with license key for diff --git a/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml b/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml index e7b1944a..ef8a0b0a 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml @@ -228,7 +228,6 @@ spec: in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html for more information, visit https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/ - . type: string keyRef: description: KeyRef is reference to secret with license key for diff --git a/controllers/factory/vmagent.go b/controllers/factory/vmagent.go index 9e513e6b..96e6d26e 100644 --- a/controllers/factory/vmagent.go +++ b/controllers/factory/vmagent.go @@ -311,17 +311,9 @@ func makeSpecForVMAgent(cr *victoriametricsv1beta1.VMAgent, c *config.BaseOperat if len(cr.Spec.ExtraEnvs) > 0 { args = append(args, "-envflag.enable=true") } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) var envs []corev1.EnvVar - envs = append(envs, cr.Spec.ExtraEnvs...) var ports []corev1.ContainerPort @@ -463,21 +455,8 @@ func makeSpecForVMAgent(cr *victoriametricsv1beta1.VMAgent, c *config.BaseOperat }) } - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("secret-" + cr.Spec.License.KeyRef.Name), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - agentVolumeMounts = append(agentVolumeMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("secret-" + cr.Spec.License.KeyRef.Name), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, agentVolumeMounts = cr.Spec.License.MaybeAddToVolumes(volumes, agentVolumeMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) if cr.Spec.RelabelConfig != nil || len(cr.Spec.InlineRelabelConfig) > 0 { args = append(args, "-remoteWrite.relabelConfig="+path.Join(RelabelingConfigDir, globalRelabelingName)) diff --git a/controllers/factory/vmalert.go b/controllers/factory/vmalert.go index ba038dbb..90be07c3 100644 --- a/controllers/factory/vmalert.go +++ b/controllers/factory/vmalert.go @@ -326,21 +326,8 @@ func vmAlertSpecGen(cr *victoriametricsv1beta1.VMAlert, c *config.BaseOperatorCo }, ) - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("license"), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, volumeMounts = cr.Spec.License.MaybeAddToVolumes(volumes, volumeMounts, SecretsDir) + if cr.Spec.NotifierConfigRef != nil { volumes = append(volumes, corev1.Volume{ Name: "vmalert-notifier-config", @@ -639,15 +626,7 @@ func buildVMAlertArgs(cr *victoriametricsv1beta1.VMAlert, ruleConfigMapNames []s args = append(args, "-envflag.enable=true") } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } - + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.ExtraArgs, "-") sort.Strings(args) diff --git a/controllers/factory/vmauth.go b/controllers/factory/vmauth.go index 5d1abce4..460126ba 100644 --- a/controllers/factory/vmauth.go +++ b/controllers/factory/vmauth.go @@ -230,6 +230,8 @@ func makeSpecForVMAuth(cr *victoriametricsv1beta1.VMAuth, c *config.BaseOperator MountPath: path.Join(ConfigMapsDir, c), }) } + volumes, vmMounts = cr.Spec.License.MaybeAddToVolumes(volumes, vmMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.ExtraArgs, "-") sort.Strings(args) diff --git a/controllers/factory/vmcluster.go b/controllers/factory/vmcluster.go index bc7a928e..67078996 100644 --- a/controllers/factory/vmcluster.go +++ b/controllers/factory/vmcluster.go @@ -438,15 +438,6 @@ func makePodSpecForVMSelect(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) ( args = append(args, "-envflag.enable=true") } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } - var envs []corev1.EnvVar envs = append(envs, cr.Spec.VMSelect.ExtraEnvs...) @@ -505,21 +496,8 @@ func makePodSpecForVMSelect(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) ( }) } - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("license"), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - vmMounts = append(vmMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, vmMounts = cr.Spec.License.MaybeAddToVolumes(volumes, vmMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.VMSelect.ExtraArgs, "-") sort.Strings(args) @@ -786,15 +764,6 @@ func makePodSpecForVMInsert(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) ( args = append(args, "-envflag.enable=true") } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } - var envs []corev1.EnvVar envs = append(envs, cr.Spec.VMInsert.ExtraEnvs...) @@ -858,22 +827,8 @@ func makePodSpecForVMInsert(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) ( MountPath: path.Join(ConfigMapsDir, c), }) } - - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("license"), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - vmMounts = append(vmMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, vmMounts = cr.Spec.License.MaybeAddToVolumes(volumes, vmMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.VMInsert.ExtraArgs, "-") sort.Strings(args) @@ -1104,15 +1059,6 @@ func makePodSpecForVMStorage(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) } } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } - var envs []corev1.EnvVar envs = append(envs, cr.Spec.VMStorage.ExtraEnvs...) @@ -1193,21 +1139,8 @@ func makePodSpecForVMStorage(cr *v1beta1.VMCluster, c *config.BaseOperatorConf) }) } - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("license"), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - vmMounts = append(vmMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, vmMounts = cr.Spec.License.MaybeAddToVolumes(volumes, vmMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.VMStorage.ExtraArgs, "-") sort.Strings(args) diff --git a/controllers/factory/vmsingle.go b/controllers/factory/vmsingle.go index d9df6fa7..b04c1800 100644 --- a/controllers/factory/vmsingle.go +++ b/controllers/factory/vmsingle.go @@ -175,14 +175,6 @@ func makeSpecForVMSingle(cr *victoriametricsv1beta1.VMSingle, c *config.BaseOper if cr.Spec.LogFormat != "" { args = append(args, fmt.Sprintf("-loggerFormat=%s", cr.Spec.LogFormat)) } - if cr.Spec.License.IsProvided() { - if cr.Spec.License.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *cr.Spec.License.Key)) - } - if cr.Spec.License.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, cr.Spec.License.KeyRef.Name, cr.Spec.License.KeyRef.Key))) - } - } args = append(args, fmt.Sprintf("-httpListenAddr=:%s", cr.Spec.Port)) if len(cr.Spec.ExtraEnvs) > 0 { @@ -296,21 +288,8 @@ func makeSpecForVMSingle(cr *victoriametricsv1beta1.VMSingle, c *config.BaseOper args = append(args, fmt.Sprintf("--streamAggr.dedupInterval=%s", cr.Spec.StreamAggrConfig.DedupInterval)) } } - if cr.Spec.License.RequiresVolumeMounts() { - volumes = append(volumes, corev1.Volume{ - Name: k8stools.SanitizeVolumeName("license"), - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: cr.Spec.License.KeyRef.Name, - }, - }, - }) - vmMounts = append(vmMounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - ReadOnly: true, - MountPath: path.Join(SecretsDir, cr.Spec.License.KeyRef.Name), - }) - } + volumes, vmMounts = cr.Spec.License.MaybeAddToVolumes(volumes, vmMounts, SecretsDir) + args = cr.Spec.License.MaybeAddToArgs(args, SecretsDir) args = addExtraArgsOverrideDefaults(args, cr.Spec.ExtraArgs, "-") sort.Strings(args) @@ -442,8 +421,8 @@ func makeSpecForVMBackuper( isCluster bool, license *victoriametricsv1beta1.License, ) (*corev1.Container, error) { - if !cr.AcceptEULA { - log.Info("EULA wasn't accepted, update your backup setting. You must switch to victoriametrics/vmbackupmanager:v1.56.0-enterprise image or higher.") + if !cr.AcceptEULA && !license.IsProvided() { + log.Info("EULA or license wasn't defined, update your backup settings. Follow https://docs.victoriametrics.com/enterprise.html for further instructions.") return nil, nil } if cr.Image.Repository == "" { @@ -482,14 +461,6 @@ func makeSpecForVMBackuper( fmt.Sprintf("-snapshot.deleteURL=%s", snapshotDeleteURL), "-eula", } - if license.IsProvided() { - if license.Key != nil { - args = append(args, fmt.Sprintf("-license=%s", *license.Key)) - } - if license.KeyRef != nil { - args = append(args, fmt.Sprintf("-licenseFile=%s", path.Join(SecretsDir, license.KeyRef.Name, license.KeyRef.Key))) - } - } if cr.LogLevel != nil { args = append(args, fmt.Sprintf("-loggerLevel=%s", *cr.LogLevel)) @@ -539,12 +510,9 @@ func makeSpecForVMBackuper( }) args = append(args, fmt.Sprintf("-credsFilePath=%s/%s", vmBackuperCreds, cr.CredentialsSecret.Key)) } - if license.RequiresVolumeMounts() { - mounts = append(mounts, corev1.VolumeMount{ - Name: k8stools.SanitizeVolumeName("license"), - MountPath: path.Join(SecretsDir, license.KeyRef.Name), - }) - } + + _, mounts = license.MaybeAddToVolumes(nil, mounts, SecretsDir) + args = license.MaybeAddToArgs(args, SecretsDir) extraEnvs := cr.ExtraEnvs if len(cr.ExtraEnvs) > 0 {