From b6c5d2a5bb98c4126c76a79ddb97fbd39c48c99a Mon Sep 17 00:00:00 2001 From: Nicolas Bigler Date: Wed, 26 Nov 2025 13:12:26 +0100 Subject: [PATCH 01/12] Fix: Set the correct version when the desired version is missing This commit fixes a bug, where the returned version was set to the composite version if the version in the desired values was missing (e.g on the Nextcloud deploy function). Instead of just returning the composite version it should return the version of the composite or the version of the observed values, whichever is higher. Signed-off-by: Nicolas Bigler --- .../common/maintenance/maintenance.go | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/pkg/comp-functions/functions/common/maintenance/maintenance.go b/pkg/comp-functions/functions/common/maintenance/maintenance.go index e2868d8d15..8c4096f515 100644 --- a/pkg/comp-functions/functions/common/maintenance/maintenance.go +++ b/pkg/comp-functions/functions/common/maintenance/maintenance.go @@ -509,7 +509,7 @@ func (m *Maintenance) createInitialMaintenanceJob(_ context.Context) error { func SetReleaseVersion(ctx context.Context, version string, desiredValues map[string]interface{}, observedValues map[string]interface{}, fields []string) (string, error) { l := controllerruntime.LoggerFrom(ctx) - tag, _, err := unstructured.NestedString(observedValues, fields...) + observedValueVersion, _, err := unstructured.NestedString(observedValues, fields...) if err != nil { return "", fmt.Errorf("cannot get image tag from values in release: %v", err) } @@ -527,14 +527,24 @@ func SetReleaseVersion(ctx context.Context, version string, desiredValues map[st desiredVersion, err := semver.ParseTolerant(desiredValueVersion) if err != nil { - l.Info("failed to parse observed service version", "version", tag) - // If the observed version is not parsable, e.g. if it's empty, update to the desired version - return version, unstructured.SetNestedField(desiredValues, version, fields...) + l.Info("failed to parse desired values version, comparing composite and observed", "version", desiredValueVersion) + + observedVersion, err := semver.ParseTolerant(observedValueVersion) + if err != nil { + l.Info("failed to parse observed service version, using composite version", "version", version) + return version, unstructured.SetNestedField(desiredValues, version, fields...) + } + + // Return the higher of composite or observed version + if compVersion.GTE(observedVersion) { + return version, unstructured.SetNestedField(desiredValues, version, fields...) + } + return observedValueVersion, unstructured.SetNestedField(desiredValues, observedValueVersion, fields...) } - observedVersion, err := semver.ParseTolerant(tag) + observedVersion, err := semver.ParseTolerant(observedValueVersion) if err != nil { - l.Info("failed to parse observed service version", "version", tag) + l.Info("failed to parse observed service version, using composite version", "version", version) // If the observed version is not parsable, e.g. if it's empty, update to the desired version return version, unstructured.SetNestedField(desiredValues, version, fields...) } @@ -544,10 +554,10 @@ func SetReleaseVersion(ctx context.Context, version string, desiredValues map[st } if observedVersion.GTE(compVersion) { - // In case the overved tag is valid and greater than the desired version, keep the observed version - return tag, unstructured.SetNestedField(desiredValues, tag, fields...) + // In case the observed tag is valid and greater than the desired version, keep the observed version + return observedValueVersion, unstructured.SetNestedField(desiredValues, observedValueVersion, fields...) } - // In case the observed tag is smaller than the desired version, then set the version from the claim + // In case the observed tag is smaller than the desired version, then set the version from the claim return version, unstructured.SetNestedField(desiredValues, version, fields...) } From 53255063c539b2aaaa9335d1d64c1930fd37ca09 Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Tue, 7 Oct 2025 10:51:21 +0200 Subject: [PATCH 02/12] feat(): generate OpenBao API --- apis/vshn/v1/dbaas_vshn_OpenBao.go | 297 +++++++++++++++++++++++ apis/vshn/v1/zz_generated.deepcopy.go | 279 +++++++++++++++++++++ apis/vshn/v1/zz_generated.managed.go | 60 +++++ apis/vshn/v1/zz_generated.managedlist.go | 9 + 4 files changed, 645 insertions(+) create mode 100644 apis/vshn/v1/dbaas_vshn_OpenBao.go diff --git a/apis/vshn/v1/dbaas_vshn_OpenBao.go b/apis/vshn/v1/dbaas_vshn_OpenBao.go new file mode 100644 index 0000000000..8acaa1acee --- /dev/null +++ b/apis/vshn/v1/dbaas_vshn_OpenBao.go @@ -0,0 +1,297 @@ +package v1 + +import ( + "fmt" + + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" + +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.security.default={})" + + +// +kubebuilder:object:root=true + +// VSHNOpenBao is the API for creating OpenBao instances. +type VSHNOpenBao struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a VSHNOpenBao. + Spec VSHNOpenBaoSpec `json:"spec"` + + // Status reflects the observed state of a VSHNOpenBao. + Status VSHNOpenBaoStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true +type VSHNOpenBaoList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []VSHNOpenBao `json:"items,omitempty"` +} + +// VSHNOpenBaoSpec defines the desired state of a VSHNOpenBao. +type VSHNOpenBaoSpec struct { + // Parameters are the configurable fields of a VSHNOpenBao. + Parameters VSHNOpenBaoParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +// VSHNOpenBaoParameters are the configurable fields of a VSHNOpenBao. +type VSHNOpenBaoParameters struct { + // Service contains OpenBao DBaaS specific properties + Service VSHNOpenBaoServiceSpec `json:"service,omitempty"` + + // Size contains settings to control the sizing of a service. + Size VSHNSizeSpec `json:"size,omitempty"` + + // Scheduling contains settings to control the scheduling of an instance. + Scheduling VSHNDBaaSSchedulingSpec `json:"scheduling,omitempty"` + + // Backup contains settings to control how the instance should get backed up. + Backup K8upBackupSpec `json:"backup,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance VSHNDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Security contains settings to control the security of a service. + Security Security `json:"security,omitempty"` + + + // Monitoring contains settings to control the monitoring of a service. + Monitoring VSHNMonitoring `json:"monitoring,omitempty"` + + // Instances defines the number of instances to run. + Instances int `json:"instances,omitempty"` +} + +// VSHNOpenBaoServiceSpec contains OpenBao DBaaS specific properties +type VSHNOpenBaoServiceSpec struct { + // +kubebuilder:validation:Enum= + // +kubebuilder:default= + + // Version contains supported version of OpenBao. + // Multiple versions are supported. The latest version is the default version. + Version string `json:"version,omitempty"` + + // OpenBaoSettings contains additional OpenBao settings. + OpenBaoSettings string `json:"openBaoSettings,omitempty"` + + // +kubebuilder:validation:Enum="besteffort";"guaranteed" + // +kubebuilder:default="besteffort" + + // ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. + ServiceLevel VSHNDBaaSServiceLevel `json:"serviceLevel,omitempty"` +} + +// VSHNOpenBaoSizeSpec contains settings to control the sizing of a service. +type VSHNOpenBaoSizeSpec struct { + + // CPURequests defines the requests amount of Kubernetes CPUs for an instance. + CPURequests string `json:"cpuRequests,omitempty"` + + // CPULimits defines the limits amount of Kubernetes CPUs for an instance. + CPULimits string `json:"cpuLimits,omitempty"` + + // MemoryRequests defines the requests amount of memory in units of bytes for an instance. + MemoryRequests string `json:"memoryRequests,omitempty"` + + // MemoryLimits defines the limits amount of memory in units of bytes for an instance. + MemoryLimits string `json:"memoryLimits,omitempty"` + + // Disk defines the amount of disk space for an instance. + Disk string `json:"disk,omitempty"` + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + + + +// VSHNOpenBaoStatus reflects the observed state of a VSHNOpenBao. +type VSHNOpenBaoStatus struct { + NamespaceConditions []Condition `json:"namespaceConditions,omitempty"` + SelfSignedIssuerConditions []Condition `json:"selfSignedIssuerConditions,omitempty"` + LocalCAConditions []Condition `json:"localCAConditions,omitempty"` + CaCertificateConditions []Condition `json:"caCertificateConditions,omitempty"` + ServerCertificateConditions []Condition `json:"serverCertificateConditions,omitempty"` + ClientCertificateConditions []Condition `json:"clientCertificateConditions,omitempty"` + // InstanceNamespace contains the name of the namespace where the instance resides + InstanceNamespace string `json:"instanceNamespace,omitempty"` + // Schedules keeps track of random generated schedules, is overwriten by + // schedules set in the service's spec. + Schedules VSHNScheduleStatus `json:"schedules,omitempty"` +} + +func (v *VSHNOpenBao) GetClaimNamespace() string { + return v.GetLabels()["crossplane.io/claim-namespace"] +} + +func (v *VSHNOpenBao) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-openbao-%s", v.GetName()) +} + +func (v *VSHNOpenBao) SetInstanceNamespaceStatus() { + v.Status.InstanceNamespace = v.GetInstanceNamespace() +} + + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNOpenBao represents the internal composite of this claim +type XVSHNOpenBao struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec XVSHNOpenBaoSpec `json:"spec"` + Status XVSHNOpenBaoStatus `json:"status,omitempty"` +} + +// XVSHNOpenBaoSpec defines the desired state of a VSHNOpenBao. +type XVSHNOpenBaoSpec struct { + // Parameters are the configurable fields of a VSHNOpenBao. + Parameters VSHNOpenBaoParameters `json:"parameters,omitempty"` + + xpv1.ResourceSpec `json:",inline"` +} + +type XVSHNOpenBaoStatus struct { + VSHNOpenBaoStatus `json:",inline"` + xpv1.ResourceStatus `json:",inline"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNOpenBaoList represents a list of composites +type XVSHNOpenBaoList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []XVSHNOpenBao `json:"items"` +} +// GetMaintenanceDayOfWeek returns the currently set day of week +func (v *VSHNOpenBao) GetMaintenanceDayOfWeek() string { + if v.Spec.Parameters.Maintenance.DayOfWeek != "" { + return v.Spec.Parameters.Maintenance.DayOfWeek + } + return v.Status.Schedules.Maintenance.DayOfWeek +} + +// GetMaintenanceTimeOfDay returns the currently set time of day +func (v *VSHNOpenBao) GetMaintenanceTimeOfDay() TimeOfDay { + if v.Spec.Parameters.Maintenance.TimeOfDay != "" { + return v.Spec.Parameters.Maintenance.TimeOfDay + } + return v.Status.Schedules.Maintenance.TimeOfDay +} + +// SetMaintenanceDayOfWeek sets the day of week to the given value +func (v *VSHNOpenBao) SetMaintenanceDayOfWeek(dow string) { + v.Status.Schedules.Maintenance.DayOfWeek = dow +} + +// SetMaintenanceTimeOfDay sets the time of day to the given value +func (v *VSHNOpenBao) SetMaintenanceTimeOfDay(tod TimeOfDay) { + v.Status.Schedules.Maintenance.TimeOfDay = tod +} + +// GetFullMaintenanceSchedule returns +func (v *VSHNOpenBao) GetFullMaintenanceSchedule() VSHNDBaaSMaintenanceScheduleSpec { + schedule := v.Spec.Parameters.Maintenance + schedule.DayOfWeek = v.GetMaintenanceDayOfWeek() + schedule.TimeOfDay = v.GetMaintenanceTimeOfDay() + return schedule +} +// GetBackupRetention returns the retention definition for this backup. +func (v *VSHNOpenBao) GetBackupRetention() K8upRetentionPolicy { + return v.Spec.Parameters.Backup.Retention +} + +// GetBackupSchedule returns the current backup schedule +func (v *VSHNOpenBao) GetBackupSchedule() string { + if v.Spec.Parameters.Backup.Schedule != "" { + return v.Spec.Parameters.Backup.Schedule + } + return v.Status.Schedules.Backup +} + +// SetBackupSchedule overwrites the current backup schedule +func (v *VSHNOpenBao) SetBackupSchedule(schedule string) { + v.Status.Schedules.Backup = schedule +}// GetServiceName returns the name of this service +func (v *VSHNOpenBao) GetServiceName() string { + return "openbao" +} + +// GetPDBLabels returns the labels to be used for the PodDisruptionBudget +// it should match one unique label od pod running in instanceNamespace +// without this, the PDB will match all pods +func (v *VSHNOpenBao) GetPDBLabels() map[string]string { + return map[string]string{ + } +} +// GetAllowAllNamespaces returns the AllowAllNamespaces field of this service +func (v *VSHNOpenBao) GetAllowAllNamespaces() bool { + return v.Spec.Parameters.Security.AllowAllNamespaces +} + +// GetAllowedNamespaces returns the AllowedNamespaces array of this service +func (v *VSHNOpenBao) GetAllowedNamespaces() []string { + if v.Spec.Parameters.Security.AllowedNamespaces == nil { + v.Spec.Parameters.Security.AllowedNamespaces = []string{} + } + return append(v.Spec.Parameters.Security.AllowedNamespaces, v.GetClaimNamespace()) +} + + +func (v *VSHNOpenBao) GetSecurity() *Security { + return &v.Spec.Parameters.Security +} + +func (v *VSHNOpenBao) GetSize() VSHNSizeSpec { + return v.Spec.Parameters.Size +} + + +func (v *VSHNOpenBao) GetMonitoring() VSHNMonitoring { + return v.Spec.Parameters.Monitoring +} + +func (v *VSHNOpenBao) GetInstances() int { + return v.Spec.Parameters.Instances +} + + +func (v *VSHNOpenBao) GetBillingName() string { + return "appcat-" + v.GetServiceName() +} + +func (v *VSHNOpenBao) GetClaimName() string { + return v.GetLabels()["crossplane.io/claim-name"] +} + +func (v *VSHNOpenBao) GetSLA() string { + return string(v.Spec.Parameters.Service.ServiceLevel) +} + +func (v *VSHNOpenBao) GetWorkloadName() string { + return v.GetName() + "-openBaoDeployment" +} + +func (v *VSHNOpenBao) GetWorkloadPodTemplateLabelsManager() PodTemplateLabelsManager { + return &StatefulSetManager{} +} \ No newline at end of file diff --git a/apis/vshn/v1/zz_generated.deepcopy.go b/apis/vshn/v1/zz_generated.deepcopy.go index f9d9f45b8d..87c9e7dcfd 100644 --- a/apis/vshn/v1/zz_generated.deepcopy.go +++ b/apis/vshn/v1/zz_generated.deepcopy.go @@ -1460,6 +1460,192 @@ func (in *VSHNNextcloudStatus) DeepCopy() *VSHNNextcloudStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBao) DeepCopyInto(out *VSHNOpenBao) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBao. +func (in *VSHNOpenBao) DeepCopy() *VSHNOpenBao { + if in == nil { + return nil + } + out := new(VSHNOpenBao) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNOpenBao) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoList) DeepCopyInto(out *VSHNOpenBaoList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VSHNOpenBao, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoList. +func (in *VSHNOpenBaoList) DeepCopy() *VSHNOpenBaoList { + if in == nil { + return nil + } + out := new(VSHNOpenBaoList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNOpenBaoList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoParameters) DeepCopyInto(out *VSHNOpenBaoParameters) { + *out = *in + out.Service = in.Service + out.Size = in.Size + in.Scheduling.DeepCopyInto(&out.Scheduling) + in.Backup.DeepCopyInto(&out.Backup) + out.Maintenance = in.Maintenance + in.Security.DeepCopyInto(&out.Security) + in.Monitoring.DeepCopyInto(&out.Monitoring) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoParameters. +func (in *VSHNOpenBaoParameters) DeepCopy() *VSHNOpenBaoParameters { + if in == nil { + return nil + } + out := new(VSHNOpenBaoParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoServiceSpec) DeepCopyInto(out *VSHNOpenBaoServiceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoServiceSpec. +func (in *VSHNOpenBaoServiceSpec) DeepCopy() *VSHNOpenBaoServiceSpec { + if in == nil { + return nil + } + out := new(VSHNOpenBaoServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoSizeSpec) DeepCopyInto(out *VSHNOpenBaoSizeSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoSizeSpec. +func (in *VSHNOpenBaoSizeSpec) DeepCopy() *VSHNOpenBaoSizeSpec { + if in == nil { + return nil + } + out := new(VSHNOpenBaoSizeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoSpec) DeepCopyInto(out *VSHNOpenBaoSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoSpec. +func (in *VSHNOpenBaoSpec) DeepCopy() *VSHNOpenBaoSpec { + if in == nil { + return nil + } + out := new(VSHNOpenBaoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoStatus) DeepCopyInto(out *VSHNOpenBaoStatus) { + *out = *in + if in.NamespaceConditions != nil { + in, out := &in.NamespaceConditions, &out.NamespaceConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SelfSignedIssuerConditions != nil { + in, out := &in.SelfSignedIssuerConditions, &out.SelfSignedIssuerConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LocalCAConditions != nil { + in, out := &in.LocalCAConditions, &out.LocalCAConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CaCertificateConditions != nil { + in, out := &in.CaCertificateConditions, &out.CaCertificateConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ServerCertificateConditions != nil { + in, out := &in.ServerCertificateConditions, &out.ServerCertificateConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ClientCertificateConditions != nil { + in, out := &in.ClientCertificateConditions, &out.ClientCertificateConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Schedules.DeepCopyInto(&out.Schedules) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoStatus. +func (in *VSHNOpenBaoStatus) DeepCopy() *VSHNOpenBaoStatus { + if in == nil { + return nil + } + out := new(VSHNOpenBaoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VSHNPostgreSQL) DeepCopyInto(out *VSHNPostgreSQL) { *out = *in @@ -2513,6 +2699,99 @@ func (in *XVSHNNextcloudStatus) DeepCopy() *XVSHNNextcloudStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNOpenBao) DeepCopyInto(out *XVSHNOpenBao) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNOpenBao. +func (in *XVSHNOpenBao) DeepCopy() *XVSHNOpenBao { + if in == nil { + return nil + } + out := new(XVSHNOpenBao) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNOpenBao) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNOpenBaoList) DeepCopyInto(out *XVSHNOpenBaoList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]XVSHNOpenBao, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNOpenBaoList. +func (in *XVSHNOpenBaoList) DeepCopy() *XVSHNOpenBaoList { + if in == nil { + return nil + } + out := new(XVSHNOpenBaoList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNOpenBaoList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNOpenBaoSpec) DeepCopyInto(out *XVSHNOpenBaoSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + in.ResourceSpec.DeepCopyInto(&out.ResourceSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNOpenBaoSpec. +func (in *XVSHNOpenBaoSpec) DeepCopy() *XVSHNOpenBaoSpec { + if in == nil { + return nil + } + out := new(XVSHNOpenBaoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNOpenBaoStatus) DeepCopyInto(out *XVSHNOpenBaoStatus) { + *out = *in + in.VSHNOpenBaoStatus.DeepCopyInto(&out.VSHNOpenBaoStatus) + in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNOpenBaoStatus. +func (in *XVSHNOpenBaoStatus) DeepCopy() *XVSHNOpenBaoStatus { + if in == nil { + return nil + } + out := new(XVSHNOpenBaoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *XVSHNPostgreSQL) DeepCopyInto(out *XVSHNPostgreSQL) { *out = *in diff --git a/apis/vshn/v1/zz_generated.managed.go b/apis/vshn/v1/zz_generated.managed.go index 61772967b2..d1bd8e765f 100644 --- a/apis/vshn/v1/zz_generated.managed.go +++ b/apis/vshn/v1/zz_generated.managed.go @@ -364,6 +364,66 @@ func (mg *XVSHNNextcloud) SetWriteConnectionSecretToReference(r *xpv1.SecretRefe mg.Spec.WriteConnectionSecretToReference = r } +// GetCondition of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetCondition(ct xpv1.ConditionType) xpv1.Condition { + return mg.Status.GetCondition(ct) +} + +// GetDeletionPolicy of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetDeletionPolicy() xpv1.DeletionPolicy { + return mg.Spec.DeletionPolicy +} + +// GetManagementPolicies of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetManagementPolicies() xpv1.ManagementPolicies { + return mg.Spec.ManagementPolicies +} + +// GetProviderConfigReference of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetProviderConfigReference() *xpv1.Reference { + return mg.Spec.ProviderConfigReference +} + +// GetPublishConnectionDetailsTo of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo { + return mg.Spec.PublishConnectionDetailsTo +} + +// GetWriteConnectionSecretToReference of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) GetWriteConnectionSecretToReference() *xpv1.SecretReference { + return mg.Spec.WriteConnectionSecretToReference +} + +// SetConditions of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetConditions(c ...xpv1.Condition) { + mg.Status.SetConditions(c...) +} + +// SetDeletionPolicy of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetDeletionPolicy(r xpv1.DeletionPolicy) { + mg.Spec.DeletionPolicy = r +} + +// SetManagementPolicies of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetManagementPolicies(r xpv1.ManagementPolicies) { + mg.Spec.ManagementPolicies = r +} + +// SetProviderConfigReference of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetProviderConfigReference(r *xpv1.Reference) { + mg.Spec.ProviderConfigReference = r +} + +// SetPublishConnectionDetailsTo of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetPublishConnectionDetailsTo(r *xpv1.PublishConnectionDetailsTo) { + mg.Spec.PublishConnectionDetailsTo = r +} + +// SetWriteConnectionSecretToReference of this XVSHNOpenBao. +func (mg *XVSHNOpenBao) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { + mg.Spec.WriteConnectionSecretToReference = r +} + // GetCondition of this XVSHNPostgreSQL. func (mg *XVSHNPostgreSQL) GetCondition(ct xpv1.ConditionType) xpv1.Condition { return mg.Status.GetCondition(ct) diff --git a/apis/vshn/v1/zz_generated.managedlist.go b/apis/vshn/v1/zz_generated.managedlist.go index 2e25f94e66..f3e54395b8 100644 --- a/apis/vshn/v1/zz_generated.managedlist.go +++ b/apis/vshn/v1/zz_generated.managedlist.go @@ -58,6 +58,15 @@ func (l *XVSHNNextcloudList) GetItems() []resource.Managed { return items } +// GetItems of this XVSHNOpenBaoList. +func (l *XVSHNOpenBaoList) GetItems() []resource.Managed { + items := make([]resource.Managed, len(l.Items)) + for i := range l.Items { + items[i] = &l.Items[i] + } + return items +} + // GetItems of this XVSHNPostgreSQLList. func (l *XVSHNPostgreSQLList) GetItems() []resource.Managed { items := make([]resource.Managed, len(l.Items)) From 08109536af6e1e24c05020ad917693f8503cd9c2 Mon Sep 17 00:00:00 2001 From: Yannik Daellenbach Date: Tue, 7 Oct 2025 11:44:30 +0200 Subject: [PATCH 03/12] Fix crd generation --- ..._vshn_OpenBao.go => dbaas_vshn_openbao.go} | 32 +- crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml | 4972 ++++++++++++++ crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml | 5901 +++++++++++++++++ 3 files changed, 10886 insertions(+), 19 deletions(-) rename apis/vshn/v1/{dbaas_vshn_OpenBao.go => dbaas_vshn_openbao.go} (92%) create mode 100644 crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml create mode 100644 crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml diff --git a/apis/vshn/v1/dbaas_vshn_OpenBao.go b/apis/vshn/v1/dbaas_vshn_openbao.go similarity index 92% rename from apis/vshn/v1/dbaas_vshn_OpenBao.go rename to apis/vshn/v1/dbaas_vshn_openbao.go index 8acaa1acee..562846e532 100644 --- a/apis/vshn/v1/dbaas_vshn_OpenBao.go +++ b/apis/vshn/v1/dbaas_vshn_openbao.go @@ -9,13 +9,12 @@ import ( // Workaround to make nested defaulting work. // kubebuilder is unable to set a {} default -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" - -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.security.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.security.default={})" // +kubebuilder:object:root=true @@ -69,7 +68,6 @@ type VSHNOpenBaoParameters struct { // Security contains settings to control the security of a service. Security Security `json:"security,omitempty"` - // Monitoring contains settings to control the monitoring of a service. Monitoring VSHNMonitoring `json:"monitoring,omitempty"` @@ -118,8 +116,6 @@ type VSHNOpenBaoSizeSpec struct { Plan string `json:"plan,omitempty"` } - - // VSHNOpenBaoStatus reflects the observed state of a VSHNOpenBao. type VSHNOpenBaoStatus struct { NamespaceConditions []Condition `json:"namespaceConditions,omitempty"` @@ -147,7 +143,6 @@ func (v *VSHNOpenBao) SetInstanceNamespaceStatus() { v.Status.InstanceNamespace = v.GetInstanceNamespace() } - // +kubebuilder:object:generate=true // +kubebuilder:object:root=true @@ -169,7 +164,7 @@ type XVSHNOpenBaoSpec struct { } type XVSHNOpenBaoStatus struct { - VSHNOpenBaoStatus `json:",inline"` + VSHNOpenBaoStatus `json:",inline"` xpv1.ResourceStatus `json:",inline"` } @@ -183,6 +178,7 @@ type XVSHNOpenBaoList struct { Items []XVSHNOpenBao `json:"items"` } + // GetMaintenanceDayOfWeek returns the currently set day of week func (v *VSHNOpenBao) GetMaintenanceDayOfWeek() string { if v.Spec.Parameters.Maintenance.DayOfWeek != "" { @@ -216,6 +212,7 @@ func (v *VSHNOpenBao) GetFullMaintenanceSchedule() VSHNDBaaSMaintenanceScheduleS schedule.TimeOfDay = v.GetMaintenanceTimeOfDay() return schedule } + // GetBackupRetention returns the retention definition for this backup. func (v *VSHNOpenBao) GetBackupRetention() K8upRetentionPolicy { return v.Spec.Parameters.Backup.Retention @@ -232,7 +229,7 @@ func (v *VSHNOpenBao) GetBackupSchedule() string { // SetBackupSchedule overwrites the current backup schedule func (v *VSHNOpenBao) SetBackupSchedule(schedule string) { v.Status.Schedules.Backup = schedule -}// GetServiceName returns the name of this service +} // GetServiceName returns the name of this service func (v *VSHNOpenBao) GetServiceName() string { return "openbao" } @@ -241,9 +238,9 @@ func (v *VSHNOpenBao) GetServiceName() string { // it should match one unique label od pod running in instanceNamespace // without this, the PDB will match all pods func (v *VSHNOpenBao) GetPDBLabels() map[string]string { - return map[string]string{ - } + return map[string]string{} } + // GetAllowAllNamespaces returns the AllowAllNamespaces field of this service func (v *VSHNOpenBao) GetAllowAllNamespaces() bool { return v.Spec.Parameters.Security.AllowAllNamespaces @@ -257,7 +254,6 @@ func (v *VSHNOpenBao) GetAllowedNamespaces() []string { return append(v.Spec.Parameters.Security.AllowedNamespaces, v.GetClaimNamespace()) } - func (v *VSHNOpenBao) GetSecurity() *Security { return &v.Spec.Parameters.Security } @@ -266,16 +262,14 @@ func (v *VSHNOpenBao) GetSize() VSHNSizeSpec { return v.Spec.Parameters.Size } - func (v *VSHNOpenBao) GetMonitoring() VSHNMonitoring { return v.Spec.Parameters.Monitoring } - + func (v *VSHNOpenBao) GetInstances() int { return v.Spec.Parameters.Instances } - func (v *VSHNOpenBao) GetBillingName() string { return "appcat-" + v.GetServiceName() } @@ -294,4 +288,4 @@ func (v *VSHNOpenBao) GetWorkloadName() string { func (v *VSHNOpenBao) GetWorkloadPodTemplateLabelsManager() PodTemplateLabelsManager { return &StatefulSetManager{} -} \ No newline at end of file +} diff --git a/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml new file mode 100644 index 0000000000..0411d0df6e --- /dev/null +++ b/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml @@ -0,0 +1,4972 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.5 + name: vshnopenbaoes.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: VSHNOpenBao + listKind: VSHNOpenBaoList + plural: vshnopenbaoes + singular: vshnopenbao + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: VSHNOpenBao is the API for creating OpenBao instances. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of a VSHNOpenBao. + properties: + parameters: + description: Parameters are the configurable fields of a VSHNOpenBao. + properties: + backup: + description: Backup contains settings to control how the instance should get backed up. + properties: + enabled: + default: true + description: |- + Enabled specifies if automatic backups are enabled for the instance. + If disabled, no backup bucket, repository password, or K8up schedule will be deployed. + type: boolean + retention: + description: K8upRetentionPolicy describes the retention configuration for a K8up backup. + properties: + keepDaily: + default: 6 + type: integer + keepHourly: + type: integer + keepLast: + type: integer + keepMonthly: + type: integer + keepWeekly: + type: integer + keepYearly: + type: integer + type: object + schedule: + pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + type: string + type: object + default: {} + instances: + description: Instances defines the number of instances to run. + type: integer + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + description: |- + DayOfWeek specifies at which weekday the maintenance is held place. + Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: |- + TimeOfDay for installing updates in UTC. + Format: "hh:mm:ss". + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + monitoring: + description: Monitoring contains settings to control the monitoring of a service. + properties: + alertmanagerConfigRef: + description: |- + AlertmanagerConfigRef contains the name of the AlertmanagerConfig that should be copied over to the + namespace of the instance. + type: string + alertmanagerConfigSecretRef: + description: |- + AlertmanagerConfigSecretRef contains the name of the secret that is used + in the referenced AlertmanagerConfig + type: string + alertmanagerConfigTemplate: + description: |- + AlertmanagerConfigSpecTemplate takes an AlertmanagerConfigSpec object. + This takes precedence over the AlertmanagerConfigRef. + properties: + inhibitRules: + description: |- + List of inhibition rules. The rules will only apply to alerts matching + the resource's namespace. + items: + description: |- + InhibitRule defines an inhibition rule that allows to mute alerts when other + alerts are already firing. + See https://prometheus.io/docs/alerting/latest/configuration/#inhibit_rule + properties: + equal: + description: |- + Labels that must have an equal value in the source and target alert for + the inhibition to take effect. + items: + type: string + type: array + sourceMatch: + description: |- + Matchers for which one or more alerts have to exist for the inhibition + to take effect. The operator enforces that the alert matches the + resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + targetMatch: + description: |- + Matchers that have to be fulfilled in the alerts to be muted. The + operator enforces that the alert matches the resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + type: object + type: array + muteTimeIntervals: + description: List of MuteTimeInterval specifying when the routes should be muted. + items: + description: MuteTimeInterval specifies the periods in time when notifications will be muted + properties: + name: + description: Name of the time interval + type: string + timeIntervals: + description: TimeIntervals is a list of TimeInterval + items: + description: TimeInterval describes intervals of time + properties: + daysOfMonth: + description: DaysOfMonth is a list of DayOfMonthRange + items: + description: DayOfMonthRange is an inclusive range of days of the month beginning at 1 + properties: + end: + description: End of the inclusive range + maximum: 31 + minimum: -31 + type: integer + start: + description: Start of the inclusive range + maximum: 31 + minimum: -31 + type: integer + type: object + type: array + months: + description: Months is a list of MonthRange + items: + description: |- + MonthRange is an inclusive range of months of the year beginning in January + Months can be specified by name (e.g 'January') by numerical month (e.g '1') or as an inclusive range (e.g 'January:March', '1:3', '1:March') + pattern: ^((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12])(?:((:((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12]))$)|$) + type: string + type: array + times: + description: Times is a list of TimeRange + items: + description: TimeRange defines a start and end time in 24hr format + properties: + endTime: + description: EndTime is the end time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + startTime: + description: StartTime is the start time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + type: object + type: array + weekdays: + description: Weekdays is a list of WeekdayRange + items: + description: |- + WeekdayRange is an inclusive range of days of the week beginning on Sunday + Days can be specified by name (e.g 'Sunday') or as an inclusive range (e.g 'Monday:Friday') + pattern: ^((?i)sun|mon|tues|wednes|thurs|fri|satur)day(?:((:(sun|mon|tues|wednes|thurs|fri|satur)day)$)|$) + type: string + type: array + years: + description: Years is a list of YearRange + items: + description: YearRange is an inclusive range of years + pattern: ^2\d{3}(?::2\d{3}|$) + type: string + type: array + type: object + type: array + required: + - name + type: object + type: array + receivers: + description: List of receivers. + items: + description: Receiver defines one or more notification integrations. + properties: + emailConfigs: + description: List of Email configurations. + items: + description: EmailConfig configures notifications via Email. + properties: + authIdentity: + description: The identity to use for authentication. + type: string + authPassword: + description: |- + The secret's key that contains the password to use for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + authSecret: + description: |- + The secret's key that contains the CRAM-MD5 secret. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + authUsername: + description: The username to use for authentication. + type: string + from: + description: The sender address. + type: string + headers: + description: |- + Further headers email header key/value pairs. Overrides any headers + previously set by the notification implementation. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + hello: + description: The hostname to identify to the SMTP server. + type: string + html: + description: The HTML body of the email notification. + type: string + requireTLS: + description: |- + The SMTP TLS requirement. + Note that Go does not support unencrypted connections to remote SMTP endpoints. + type: boolean + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + smarthost: + description: The SMTP host and port through which emails are sent. E.g. example.com:25 + type: string + text: + description: The text body of the email notification. + type: string + tlsConfig: + description: TLS configuration + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + to: + description: The email address to send notifications to. + type: string + type: object + type: array + name: + description: Name of the receiver. Must be unique across all items from the list. + minLength: 1 + type: string + opsgenieConfigs: + description: List of OpsGenie configurations. + items: + description: |- + OpsGenieConfig configures notifications via OpsGenie. + See https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config + properties: + actions: + description: Comma separated list of actions that will be available for the alert. + type: string + apiKey: + description: |- + The secret's key that contains the OpsGenie API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiURL: + description: The URL to send OpsGenie API requests to. + type: string + description: + description: Description of the incident. + type: string + details: + description: A set of arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entity: + description: Optional field that can be used to specify which domain alert is related to. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Alert text limited to 130 characters. + type: string + note: + description: Additional alert note. + type: string + priority: + description: Priority level of alert. Possible values are P1, P2, P3, P4, and P5. + type: string + responders: + description: List of responders responsible for notifications. + items: + description: |- + OpsGenieConfigResponder defines a responder to an incident. + One of `id`, `name` or `username` has to be defined. + properties: + id: + description: ID of the responder. + type: string + name: + description: Name of the responder. + type: string + type: + description: Type of responder. + enum: + - team + - teams + - user + - escalation + - schedule + minLength: 1 + type: string + username: + description: Username of the responder. + type: string + required: + - type + type: object + type: array + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + source: + description: Backlink to the sender of the notification. + type: string + tags: + description: Comma separated list of tags attached to the notifications. + type: string + updateAlerts: + description: |- + Whether to update message and description of the alert in OpsGenie if it already exists + By default, the alert is never updated in OpsGenie, the new message only appears in activity log. + type: boolean + type: object + type: array + pagerdutyConfigs: + description: List of PagerDuty configurations. + items: + description: |- + PagerDutyConfig configures notifications via PagerDuty. + See https://prometheus.io/docs/alerting/latest/configuration/#pagerduty_config + properties: + class: + description: The class/type of the event. + type: string + client: + description: Client identification. + type: string + clientURL: + description: Backlink to the sender of notification. + type: string + component: + description: The part or component of the affected system that is broken. + type: string + description: + description: Description of the incident. + type: string + details: + description: Arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + group: + description: A cluster or grouping of sources. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + pagerDutyImageConfigs: + description: A list of image details to attach that provide further detail about an incident. + items: + description: PagerDutyImageConfig attaches images to an incident + properties: + alt: + description: Alt is the optional alternative text for the image. + type: string + href: + description: Optional URL; makes the image a clickable link. + type: string + src: + description: Src of the image being attached to the incident + type: string + type: object + type: array + pagerDutyLinkConfigs: + description: A list of link details to attach that provide further detail about an incident. + items: + description: PagerDutyLinkConfig attaches text links to an incident + properties: + alt: + description: Text that describes the purpose of the link, and can be used as the link's text. + type: string + href: + description: Href is the URL of the link to be attached + type: string + type: object + type: array + routingKey: + description: |- + The secret's key that contains the PagerDuty integration key (when using + Events API v2). Either this field or `serviceKey` needs to be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + serviceKey: + description: |- + The secret's key that contains the PagerDuty service key (when using + integration type "Prometheus"). Either this field or `routingKey` needs to + be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + severity: + description: Severity of the incident. + type: string + url: + description: The URL to send requests to. + type: string + type: object + type: array + pushoverConfigs: + description: List of Pushover configurations. + items: + description: |- + PushoverConfig configures notifications via Pushover. + See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config + properties: + expire: + description: |- + How long your notification will continue to be retried for, unless the user + acknowledges the notification. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + html: + description: Whether notification message is HTML or plain text. + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Notification message. + type: string + priority: + description: Priority, see https://pushover.net/api#priority + type: string + retry: + description: |- + How often the Pushover servers will send the same notification to the user. + Must be at least 30 seconds. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sound: + description: The name of one of the sounds supported by device clients to override the user's default sound choice + type: string + title: + description: Notification title. + type: string + token: + description: |- + The secret's key that contains the registered application's API token, see https://pushover.net/apps. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + url: + description: A supplementary URL shown alongside the message. + type: string + urlTitle: + description: A title for supplementary URL, otherwise just the URL is shown + type: string + userKey: + description: |- + The secret's key that contains the recipient user's user key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + required: + - token + - userKey + type: object + type: array + slackConfigs: + description: List of Slack configurations. + items: + description: |- + SlackConfig configures notifications via Slack. + See https://prometheus.io/docs/alerting/latest/configuration/#slack_config + properties: + actions: + description: A list of Slack actions that are sent with each notification. + items: + description: |- + SlackAction configures a single Slack action that is sent with each + notification. + See https://api.slack.com/docs/message-attachments#action_fields and + https://api.slack.com/docs/message-buttons for more information. + properties: + confirm: + description: |- + SlackConfirmationField protect users from destructive actions or + particularly distinguished decisions by asking them to confirm their button + click one more time. + See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields + for more information. + properties: + dismissText: + type: string + okText: + type: string + text: + minLength: 1 + type: string + title: + type: string + required: + - text + type: object + name: + type: string + style: + type: string + text: + minLength: 1 + type: string + type: + minLength: 1 + type: string + url: + type: string + value: + type: string + required: + - text + - type + type: object + type: array + apiURL: + description: |- + The secret's key that contains the Slack webhook URL. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + callbackId: + type: string + channel: + description: The channel or user to send notifications to. + type: string + color: + type: string + fallback: + type: string + fields: + description: A list of Slack fields that are sent with each notification. + items: + description: |- + SlackField configures a single Slack field that is sent with each notification. + Each field must contain a title, value, and optionally, a boolean value to indicate if the field + is short enough to be displayed next to other fields designated as short. + See https://api.slack.com/docs/message-attachments#fields for more information. + properties: + short: + type: boolean + title: + minLength: 1 + type: string + value: + minLength: 1 + type: string + required: + - title + - value + type: object + type: array + footer: + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + iconEmoji: + type: string + iconURL: + type: string + imageURL: + type: string + linkNames: + type: boolean + mrkdwnIn: + items: + type: string + type: array + pretext: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + shortFields: + type: boolean + text: + type: string + thumbURL: + type: string + title: + type: string + titleLink: + type: string + username: + type: string + type: object + type: array + snsConfigs: + description: List of SNS configurations + items: + description: |- + SNSConfig configures notifications via AWS SNS. + See https://prometheus.io/docs/alerting/latest/configuration/#sns_configs + properties: + apiURL: + description: |- + The SNS API URL i.e. https://sns.us-east-2.amazonaws.com. + If not specified, the SNS API URL from the SNS SDK will be used. + type: string + attributes: + additionalProperties: + type: string + description: SNS message attributes. + type: object + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: The message content of the SNS notification. + type: string + phoneNumber: + description: |- + Phone number if message is delivered via SMS in E.164 format. + If you don't specify this value, you must specify a value for the TopicARN or TargetARN. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sigv4: + description: Configures AWS's Signature Verification 4 signing process to sign requests. + properties: + accessKey: + description: AccessKey is the AWS API key. If blank, the environment variable `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: SecretKey is the AWS API secret. If blank, the environment variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + subject: + description: Subject line when the message is delivered to email endpoints. + type: string + targetARN: + description: |- + The mobile platform endpoint ARN if message is delivered via mobile notifications. + If you don't specify this value, you must specify a value for the topic_arn or PhoneNumber. + type: string + topicARN: + description: |- + SNS topic ARN, i.e. arn:aws:sns:us-east-2:698519295917:My-Topic + If you don't specify this value, you must specify a value for the PhoneNumber or TargetARN. + type: string + type: object + type: array + telegramConfigs: + description: List of Telegram configurations. + items: + description: |- + TelegramConfig configures notifications via Telegram. + See https://prometheus.io/docs/alerting/latest/configuration/#telegram_config + properties: + apiURL: + description: |- + The Telegram API URL i.e. https://api.telegram.org. + If not specified, default API URL will be used. + type: string + botToken: + description: |- + Telegram bot token + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + chatID: + description: The Telegram chat ID. + format: int64 + type: integer + disableNotifications: + description: Disable telegram notifications + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Message template + type: string + parseMode: + description: Parse mode for telegram message + enum: + - MarkdownV2 + - Markdown + - HTML + type: string + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + type: object + type: array + victoropsConfigs: + description: List of VictorOps configurations. + items: + description: |- + VictorOpsConfig configures notifications via VictorOps. + See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config + properties: + apiKey: + description: |- + The secret's key that contains the API key to use when talking to the VictorOps API. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiUrl: + description: The VictorOps API URL. + type: string + customFields: + description: Additional custom fields for notification. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entityDisplayName: + description: Contains summary of the alerted problem. + type: string + httpConfig: + description: The HTTP client's configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + messageType: + description: Describes the behavior of the alert (CRITICAL, WARNING, INFO). + type: string + monitoringTool: + description: The monitoring tool the state message is from. + type: string + routingKey: + description: A key used to map the alert to a team. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + stateMessage: + description: Contains long explanation of the alerted problem. + type: string + type: object + type: array + webhookConfigs: + description: List of webhook configurations. + items: + description: |- + WebhookConfig configures notifications via a generic receiver supporting the webhook payload. + See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + maxAlerts: + description: Maximum number of alerts to be sent per webhook message. When 0, all alerts are included. + format: int32 + minimum: 0 + type: integer + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + url: + description: |- + The URL to send HTTP POST requests to. `urlSecret` takes precedence over + `url`. One of `urlSecret` and `url` should be defined. + type: string + urlSecret: + description: |- + The secret's key that contains the webhook URL to send HTTP requests to. + `urlSecret` takes precedence over `url`. One of `urlSecret` and `url` + should be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + wechatConfigs: + description: List of WeChat configurations. + items: + description: |- + WeChatConfig configures notifications via WeChat. + See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config + properties: + agentID: + type: string + apiSecret: + description: |- + The secret's key that contains the WeChat API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiURL: + description: The WeChat API URL. + type: string + corpID: + description: The corp id for authentication. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: API request data as defined by the WeChat API. + type: string + messageType: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + toParty: + type: string + toTag: + type: string + toUser: + type: string + type: object + type: array + required: + - name + type: object + type: array + route: + description: |- + The Alertmanager route definition for alerts matching the resource's + namespace. If present, it will be added to the generated Alertmanager + configuration as a first-level route. + properties: + activeTimeIntervals: + description: ActiveTimeIntervals is a list of MuteTimeInterval names when this route should be active. + items: + type: string + type: array + continue: + description: |- + Boolean indicating whether an alert should continue matching subsequent + sibling nodes. It will always be overridden to true for the first-level + route by the Prometheus operator. + type: boolean + groupBy: + description: |- + List of labels to group by. + Labels must not be repeated (unique list). + Special label "..." (aggregate by all possible labels), if provided, must be the only element in the list. + items: + type: string + type: array + groupInterval: + description: |- + How long to wait before sending an updated notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "5m" + type: string + groupWait: + description: |- + How long to wait before sending the initial notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "30s" + type: string + matchers: + description: |- + List of matchers that the alert's labels should match. For the first + level route, the operator removes any existing equality and regexp + matcher on the `namespace` label and adds a `namespace: ` matcher. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + muteTimeIntervals: + description: |- + Note: this comment applies to the field definition above but appears + below otherwise it gets included in the generated manifest. + CRD schema doesn't support self-referential types for now (see + https://github.com/kubernetes/kubernetes/issues/62872). We have to use + an alternative type to circumvent the limitation. The downside is that + the Kube API can't validate the data beyond the fact that it is a valid + JSON representation. + MuteTimeIntervals is a list of MuteTimeInterval names that will mute this route when matched, + items: + type: string + type: array + receiver: + description: |- + Name of the receiver for this route. If not empty, it should be listed in + the `receivers` field. + type: string + repeatInterval: + description: |- + How long to wait before repeating the last notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "4h" + type: string + routes: + description: Child routes. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + email: + description: Email necessary to send alerts via email + type: string + type: object + scheduling: + description: Scheduling contains settings to control the scheduling of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a node’s labels for the pod to be scheduled on that node + type: object + type: object + security: + description: Security contains settings to control the security of a service. + properties: + allowAllNamespaces: + default: false + description: AllowAllNamespaces allows the service to be accessible from all namespaces, this supersedes the AllowedNamespaces field + type: boolean + allowedGroups: + description: AllowedGroups defines a list of Groups that have limited access to the instance namespace + items: + type: string + type: array + allowedNamespaces: + description: AllowedNamespaces defines a list of namespaces from where the service can be reached in the claim namespace + items: + type: string + type: array + allowedUsers: + description: AllowedUsers defines a list of Users that have limited access to instance namespace. + items: + type: string + type: array + deletionProtection: + default: true + description: DeletionProtection blocks the deletion of the instance if it is enabled (enabled by default) + type: boolean + type: object + default: {} + service: + description: Service contains OpenBao DBaaS specific properties + properties: + openBaoSettings: + description: OpenBaoSettings contains additional OpenBao settings. + type: string + serviceLevel: + default: besteffort + description: ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. + enum: + - besteffort + - guaranteed + type: string + version: + default: + description: |- + Version contains supported version of OpenBao. + Multiple versions are supported. The latest version is the default version. + enum: + - + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + disk: + description: Disk defines the amount of disk space for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines the compute resources. + type: string + requests: + description: Requests defines CPU and memory requests for an instance + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + type: object + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a VSHNOpenBao. + properties: + caCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + clientCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + instanceNamespace: + description: InstanceNamespace contains the name of the namespace where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + schedules: + description: |- + Schedules keeps track of random generated schedules, is overwriten by + schedules set in the service's spec. + properties: + backup: + description: Backup keeps track of the backup schedule. + type: string + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the last time this condition transitioned from one + status to another. + format: date-time + type: string + message: + description: |- + A Message containing details about this condition's last transition from + one status to another, if any. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + type: integer + reason: + description: A Reason for this condition's last transition from one status to another. + type: string + status: + description: Status of this condition; is it currently True, False, or Unknown? + type: string + type: + description: |- + Type of this condition. At most one of each condition type may apply to + a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + maintenance: + description: Maintenance keeps track of the maintenance schedule. + properties: + dayOfWeek: + description: |- + DayOfWeek specifies at which weekday the maintenance is held place. + Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: |- + TimeOfDay for installing updates in UTC. + Format: "hh:mm:ss". + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + observedGeneration: + description: |- + ObservedGeneration is the latest metadata.generation + which resulted in either a ready state, or stalled due to error + it can not recover from without human intervention. + format: int64 + type: integer + type: object + selfSignedIssuerConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + serverCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml new file mode 100644 index 0000000000..104ba4edb8 --- /dev/null +++ b/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml @@ -0,0 +1,5901 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.5 + name: xvshnopenbaoes.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: XVSHNOpenBao + listKind: XVSHNOpenBaoList + plural: xvshnopenbaoes + singular: xvshnopenbao + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: XVSHNOpenBao represents the internal composite of this claim + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: XVSHNOpenBaoSpec defines the desired state of a VSHNOpenBao. + properties: + deletionPolicy: + default: Delete + description: |- + DeletionPolicy specifies what will happen to the underlying external + when this managed resource is deleted - either "Delete" or "Orphan" the + external resource. + This field is planned to be deprecated in favor of the ManagementPolicies + field in a future release. Currently, both could be set independently and + non-default values would be honored if the feature flag is enabled. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + enum: + - Orphan + - Delete + type: string + managementPolicies: + default: + - '*' + description: |- + THIS IS A BETA FIELD. It is on by default but can be opted out + through a Crossplane feature flag. + ManagementPolicies specify the array of actions Crossplane is allowed to + take on the managed and external resources. + This field is planned to replace the DeletionPolicy field in a future + release. Currently, both could be set independently and non-default + values would be honored if the feature flag is enabled. If both are + custom, the DeletionPolicy field will be ignored. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md + items: + description: |- + A ManagementAction represents an action that the Crossplane controllers + can take on an external resource. + enum: + - Observe + - Create + - Update + - Delete + - LateInitialize + - '*' + type: string + type: array + parameters: + description: Parameters are the configurable fields of a VSHNOpenBao. + properties: + backup: + description: Backup contains settings to control how the instance + should get backed up. + properties: + enabled: + default: true + description: |- + Enabled specifies if automatic backups are enabled for the instance. + If disabled, no backup bucket, repository password, or K8up schedule will be deployed. + type: boolean + retention: + description: K8upRetentionPolicy describes the retention configuration + for a K8up backup. + properties: + keepDaily: + default: 6 + type: integer + keepHourly: + type: integer + keepLast: + type: integer + keepMonthly: + type: integer + keepWeekly: + type: integer + keepYearly: + type: integer + type: object + schedule: + pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) + (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) + (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + type: string + type: object + instances: + description: Instances defines the number of instances to run. + type: integer + maintenance: + description: Maintenance contains settings to control the maintenance + of an instance. + properties: + dayOfWeek: + description: |- + DayOfWeek specifies at which weekday the maintenance is held place. + Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: |- + TimeOfDay for installing updates in UTC. + Format: "hh:mm:ss". + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + monitoring: + description: Monitoring contains settings to control the monitoring + of a service. + properties: + alertmanagerConfigRef: + description: |- + AlertmanagerConfigRef contains the name of the AlertmanagerConfig that should be copied over to the + namespace of the instance. + type: string + alertmanagerConfigSecretRef: + description: |- + AlertmanagerConfigSecretRef contains the name of the secret that is used + in the referenced AlertmanagerConfig + type: string + alertmanagerConfigTemplate: + description: |- + AlertmanagerConfigSpecTemplate takes an AlertmanagerConfigSpec object. + This takes precedence over the AlertmanagerConfigRef. + properties: + inhibitRules: + description: |- + List of inhibition rules. The rules will only apply to alerts matching + the resource's namespace. + items: + description: |- + InhibitRule defines an inhibition rule that allows to mute alerts when other + alerts are already firing. + See https://prometheus.io/docs/alerting/latest/configuration/#inhibit_rule + properties: + equal: + description: |- + Labels that must have an equal value in the source and target alert for + the inhibition to take effect. + items: + type: string + type: array + sourceMatch: + description: |- + Matchers for which one or more alerts have to exist for the inhibition + to take effect. The operator enforces that the alert matches the + resource's namespace. + items: + description: Matcher defines how to match on alert's + labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + targetMatch: + description: |- + Matchers that have to be fulfilled in the alerts to be muted. The + operator enforces that the alert matches the resource's namespace. + items: + description: Matcher defines how to match on alert's + labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + type: object + type: array + muteTimeIntervals: + description: List of MuteTimeInterval specifying when + the routes should be muted. + items: + description: MuteTimeInterval specifies the periods + in time when notifications will be muted + properties: + name: + description: Name of the time interval + type: string + timeIntervals: + description: TimeIntervals is a list of TimeInterval + items: + description: TimeInterval describes intervals + of time + properties: + daysOfMonth: + description: DaysOfMonth is a list of DayOfMonthRange + items: + description: DayOfMonthRange is an inclusive + range of days of the month beginning at + 1 + properties: + end: + description: End of the inclusive range + maximum: 31 + minimum: -31 + type: integer + start: + description: Start of the inclusive + range + maximum: 31 + minimum: -31 + type: integer + type: object + type: array + months: + description: Months is a list of MonthRange + items: + description: |- + MonthRange is an inclusive range of months of the year beginning in January + Months can be specified by name (e.g 'January') by numerical month (e.g '1') or as an inclusive range (e.g 'January:March', '1:3', '1:March') + pattern: ^((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12])(?:((:((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12]))$)|$) + type: string + type: array + times: + description: Times is a list of TimeRange + items: + description: TimeRange defines a start and + end time in 24hr format + properties: + endTime: + description: EndTime is the end time + in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + startTime: + description: StartTime is the start + time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + type: object + type: array + weekdays: + description: Weekdays is a list of WeekdayRange + items: + description: |- + WeekdayRange is an inclusive range of days of the week beginning on Sunday + Days can be specified by name (e.g 'Sunday') or as an inclusive range (e.g 'Monday:Friday') + pattern: ^((?i)sun|mon|tues|wednes|thurs|fri|satur)day(?:((:(sun|mon|tues|wednes|thurs|fri|satur)day)$)|$) + type: string + type: array + years: + description: Years is a list of YearRange + items: + description: YearRange is an inclusive range + of years + pattern: ^2\d{3}(?::2\d{3}|$) + type: string + type: array + type: object + type: array + required: + - name + type: object + type: array + receivers: + description: List of receivers. + items: + description: Receiver defines one or more notification + integrations. + properties: + emailConfigs: + description: List of Email configurations. + items: + description: EmailConfig configures notifications + via Email. + properties: + authIdentity: + description: The identity to use for authentication. + type: string + authPassword: + description: |- + The secret's key that contains the password to use for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + authSecret: + description: |- + The secret's key that contains the CRAM-MD5 secret. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + authUsername: + description: The username to use for authentication. + type: string + from: + description: The sender address. + type: string + headers: + description: |- + Further headers email header key/value pairs. Overrides any headers + previously set by the notification implementation. + items: + description: KeyValue defines a (key, value) + tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + hello: + description: The hostname to identify to the + SMTP server. + type: string + html: + description: The HTML body of the email notification. + type: string + requireTLS: + description: |- + The SMTP TLS requirement. + Note that Go does not support unencrypted connections to remote SMTP endpoints. + type: boolean + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + smarthost: + description: The SMTP host and port through + which emails are sent. E.g. example.com:25 + type: string + text: + description: The text body of the email notification. + type: string + tlsConfig: + description: TLS configuration + properties: + ca: + description: Certificate authority used + when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the + ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to present + when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the + ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the client + key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + to: + description: The email address to send notifications + to. + type: string + type: object + type: array + name: + description: Name of the receiver. Must be unique + across all items from the list. + minLength: 1 + type: string + opsgenieConfigs: + description: List of OpsGenie configurations. + items: + description: |- + OpsGenieConfig configures notifications via OpsGenie. + See https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config + properties: + actions: + description: Comma separated list of actions + that will be available for the alert. + type: string + apiKey: + description: |- + The secret's key that contains the OpsGenie API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiURL: + description: The URL to send OpsGenie API + requests to. + type: string + description: + description: Description of the incident. + type: string + details: + description: A set of arbitrary key/value + pairs that provide further detail about + the incident. + items: + description: KeyValue defines a (key, value) + tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entity: + description: Optional field that can be used + to specify which domain alert is related + to. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + message: + description: Alert text limited to 130 characters. + type: string + note: + description: Additional alert note. + type: string + priority: + description: Priority level of alert. Possible + values are P1, P2, P3, P4, and P5. + type: string + responders: + description: List of responders responsible + for notifications. + items: + description: |- + OpsGenieConfigResponder defines a responder to an incident. + One of `id`, `name` or `username` has to be defined. + properties: + id: + description: ID of the responder. + type: string + name: + description: Name of the responder. + type: string + type: + description: Type of responder. + enum: + - team + - teams + - user + - escalation + - schedule + minLength: 1 + type: string + username: + description: Username of the responder. + type: string + required: + - type + type: object + type: array + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + source: + description: Backlink to the sender of the + notification. + type: string + tags: + description: Comma separated list of tags + attached to the notifications. + type: string + updateAlerts: + description: |- + Whether to update message and description of the alert in OpsGenie if it already exists + By default, the alert is never updated in OpsGenie, the new message only appears in activity log. + type: boolean + type: object + type: array + pagerdutyConfigs: + description: List of PagerDuty configurations. + items: + description: |- + PagerDutyConfig configures notifications via PagerDuty. + See https://prometheus.io/docs/alerting/latest/configuration/#pagerduty_config + properties: + class: + description: The class/type of the event. + type: string + client: + description: Client identification. + type: string + clientURL: + description: Backlink to the sender of notification. + type: string + component: + description: The part or component of the + affected system that is broken. + type: string + description: + description: Description of the incident. + type: string + details: + description: Arbitrary key/value pairs that + provide further detail about the incident. + items: + description: KeyValue defines a (key, value) + tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + group: + description: A cluster or grouping of sources. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + pagerDutyImageConfigs: + description: A list of image details to attach + that provide further detail about an incident. + items: + description: PagerDutyImageConfig attaches + images to an incident + properties: + alt: + description: Alt is the optional alternative + text for the image. + type: string + href: + description: Optional URL; makes the + image a clickable link. + type: string + src: + description: Src of the image being + attached to the incident + type: string + type: object + type: array + pagerDutyLinkConfigs: + description: A list of link details to attach + that provide further detail about an incident. + items: + description: PagerDutyLinkConfig attaches + text links to an incident + properties: + alt: + description: Text that describes the + purpose of the link, and can be used + as the link's text. + type: string + href: + description: Href is the URL of the + link to be attached + type: string + type: object + type: array + routingKey: + description: |- + The secret's key that contains the PagerDuty integration key (when using + Events API v2). Either this field or `serviceKey` needs to be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + serviceKey: + description: |- + The secret's key that contains the PagerDuty service key (when using + integration type "Prometheus"). Either this field or `routingKey` needs to + be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + severity: + description: Severity of the incident. + type: string + url: + description: The URL to send requests to. + type: string + type: object + type: array + pushoverConfigs: + description: List of Pushover configurations. + items: + description: |- + PushoverConfig configures notifications via Pushover. + See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config + properties: + expire: + description: |- + How long your notification will continue to be retried for, unless the user + acknowledges the notification. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + html: + description: Whether notification message + is HTML or plain text. + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + message: + description: Notification message. + type: string + priority: + description: Priority, see https://pushover.net/api#priority + type: string + retry: + description: |- + How often the Pushover servers will send the same notification to the user. + Must be at least 30 seconds. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + sound: + description: The name of one of the sounds + supported by device clients to override + the user's default sound choice + type: string + title: + description: Notification title. + type: string + token: + description: |- + The secret's key that contains the registered application's API token, see https://pushover.net/apps. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + url: + description: A supplementary URL shown alongside + the message. + type: string + urlTitle: + description: A title for supplementary URL, + otherwise just the URL is shown + type: string + userKey: + description: |- + The secret's key that contains the recipient user's user key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + required: + - token + - userKey + type: object + type: array + slackConfigs: + description: List of Slack configurations. + items: + description: |- + SlackConfig configures notifications via Slack. + See https://prometheus.io/docs/alerting/latest/configuration/#slack_config + properties: + actions: + description: A list of Slack actions that + are sent with each notification. + items: + description: |- + SlackAction configures a single Slack action that is sent with each + notification. + See https://api.slack.com/docs/message-attachments#action_fields and + https://api.slack.com/docs/message-buttons for more information. + properties: + confirm: + description: |- + SlackConfirmationField protect users from destructive actions or + particularly distinguished decisions by asking them to confirm their button + click one more time. + See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields + for more information. + properties: + dismissText: + type: string + okText: + type: string + text: + minLength: 1 + type: string + title: + type: string + required: + - text + type: object + name: + type: string + style: + type: string + text: + minLength: 1 + type: string + type: + minLength: 1 + type: string + url: + type: string + value: + type: string + required: + - text + - type + type: object + type: array + apiURL: + description: |- + The secret's key that contains the Slack webhook URL. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + callbackId: + type: string + channel: + description: The channel or user to send notifications + to. + type: string + color: + type: string + fallback: + type: string + fields: + description: A list of Slack fields that are + sent with each notification. + items: + description: |- + SlackField configures a single Slack field that is sent with each notification. + Each field must contain a title, value, and optionally, a boolean value to indicate if the field + is short enough to be displayed next to other fields designated as short. + See https://api.slack.com/docs/message-attachments#fields for more information. + properties: + short: + type: boolean + title: + minLength: 1 + type: string + value: + minLength: 1 + type: string + required: + - title + - value + type: object + type: array + footer: + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + iconEmoji: + type: string + iconURL: + type: string + imageURL: + type: string + linkNames: + type: boolean + mrkdwnIn: + items: + type: string + type: array + pretext: + type: string + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + shortFields: + type: boolean + text: + type: string + thumbURL: + type: string + title: + type: string + titleLink: + type: string + username: + type: string + type: object + type: array + snsConfigs: + description: List of SNS configurations + items: + description: |- + SNSConfig configures notifications via AWS SNS. + See https://prometheus.io/docs/alerting/latest/configuration/#sns_configs + properties: + apiURL: + description: |- + The SNS API URL i.e. https://sns.us-east-2.amazonaws.com. + If not specified, the SNS API URL from the SNS SDK will be used. + type: string + attributes: + additionalProperties: + type: string + description: SNS message attributes. + type: object + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + message: + description: The message content of the SNS + notification. + type: string + phoneNumber: + description: |- + Phone number if message is delivered via SMS in E.164 format. + If you don't specify this value, you must specify a value for the TopicARN or TargetARN. + type: string + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + sigv4: + description: Configures AWS's Signature Verification + 4 signing process to sign requests. + properties: + accessKey: + description: AccessKey is the AWS API + key. If blank, the environment variable + `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + profile: + description: Profile is the named AWS + profile used to authenticate. + type: string + region: + description: Region is the AWS region. + If blank, the region from the default + credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS + profile used to authenticate. + type: string + secretKey: + description: SecretKey is the AWS API + secret. If blank, the environment variable + `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + subject: + description: Subject line when the message + is delivered to email endpoints. + type: string + targetARN: + description: |- + The mobile platform endpoint ARN if message is delivered via mobile notifications. + If you don't specify this value, you must specify a value for the topic_arn or PhoneNumber. + type: string + topicARN: + description: |- + SNS topic ARN, i.e. arn:aws:sns:us-east-2:698519295917:My-Topic + If you don't specify this value, you must specify a value for the PhoneNumber or TargetARN. + type: string + type: object + type: array + telegramConfigs: + description: List of Telegram configurations. + items: + description: |- + TelegramConfig configures notifications via Telegram. + See https://prometheus.io/docs/alerting/latest/configuration/#telegram_config + properties: + apiURL: + description: |- + The Telegram API URL i.e. https://api.telegram.org. + If not specified, default API URL will be used. + type: string + botToken: + description: |- + Telegram bot token + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + chatID: + description: The Telegram chat ID. + format: int64 + type: integer + disableNotifications: + description: Disable telegram notifications + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + message: + description: Message template + type: string + parseMode: + description: Parse mode for telegram message + enum: + - MarkdownV2 + - Markdown + - HTML + type: string + sendResolved: + description: Whether to notify about resolved + alerts. + type: boolean + type: object + type: array + victoropsConfigs: + description: List of VictorOps configurations. + items: + description: |- + VictorOpsConfig configures notifications via VictorOps. + See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config + properties: + apiKey: + description: |- + The secret's key that contains the API key to use when talking to the VictorOps API. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiUrl: + description: The VictorOps API URL. + type: string + customFields: + description: Additional custom fields for + notification. + items: + description: KeyValue defines a (key, value) + tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entityDisplayName: + description: Contains summary of the alerted + problem. + type: string + httpConfig: + description: The HTTP client's configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + messageType: + description: Describes the behavior of the + alert (CRITICAL, WARNING, INFO). + type: string + monitoringTool: + description: The monitoring tool the state + message is from. + type: string + routingKey: + description: A key used to map the alert to + a team. + type: string + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + stateMessage: + description: Contains long explanation of + the alerted problem. + type: string + type: object + type: array + webhookConfigs: + description: List of webhook configurations. + items: + description: |- + WebhookConfig configures notifications via a generic receiver supporting the webhook payload. + See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + maxAlerts: + description: Maximum number of alerts to be + sent per webhook message. When 0, all alerts + are included. + format: int32 + minimum: 0 + type: integer + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + url: + description: |- + The URL to send HTTP POST requests to. `urlSecret` takes precedence over + `url`. One of `urlSecret` and `url` should be defined. + type: string + urlSecret: + description: |- + The secret's key that contains the webhook URL to send HTTP requests to. + `urlSecret` takes precedence over `url`. One of `urlSecret` and `url` + should be defined. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + wechatConfigs: + description: List of WeChat configurations. + items: + description: |- + WeChatConfig configures notifications via WeChat. + See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config + properties: + agentID: + type: string + apiSecret: + description: |- + The secret's key that contains the WeChat API key. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + apiURL: + description: The WeChat API URL. + type: string + corpID: + description: The corp id for authentication. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: |- + Authorization header configuration for the client. + This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that + contains the credentials of the + request + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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: + description: |- + Set the authentication type. Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: |- + BasicAuth for the client. + This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: |- + The secret in the service monitor namespace that contains the password + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: |- + The secret in the service monitor namespace that contains the username + for authentication. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearerTokenSecret: + description: |- + The secret's key that contains the bearer token to be used by the client + for authentication. + The secret needs to be in the same namespace as the AlertmanagerConfig + object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + followRedirects: + description: FollowRedirects specifies + whether the client should follow HTTP + 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials + used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + clientSecret: + description: The secret containing + the OAuth2 client secret + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpointParams: + additionalProperties: + type: string + description: Parameters to append + to the token URL + type: object + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the + token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the + client. + properties: + ca: + description: Certificate authority + used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + cert: + description: Client certificate to + present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing + data to use for the targets. + properties: + key: + description: The key of the + secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keySecret: + description: Secret containing the + client key file for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + message: + description: API request data as defined by + the WeChat API. + type: string + messageType: + type: string + sendResolved: + description: Whether or not to notify about + resolved alerts. + type: boolean + toParty: + type: string + toTag: + type: string + toUser: + type: string + type: object + type: array + required: + - name + type: object + type: array + route: + description: |- + The Alertmanager route definition for alerts matching the resource's + namespace. If present, it will be added to the generated Alertmanager + configuration as a first-level route. + properties: + activeTimeIntervals: + description: ActiveTimeIntervals is a list of MuteTimeInterval + names when this route should be active. + items: + type: string + type: array + continue: + description: |- + Boolean indicating whether an alert should continue matching subsequent + sibling nodes. It will always be overridden to true for the first-level + route by the Prometheus operator. + type: boolean + groupBy: + description: |- + List of labels to group by. + Labels must not be repeated (unique list). + Special label "..." (aggregate by all possible labels), if provided, must be the only element in the list. + items: + type: string + type: array + groupInterval: + description: |- + How long to wait before sending an updated notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "5m" + type: string + groupWait: + description: |- + How long to wait before sending the initial notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "30s" + type: string + matchers: + description: |- + List of matchers that the alert's labels should match. For the first + level route, the operator removes any existing equality and regexp + matcher on the `namespace` label and adds a `namespace: ` matcher. + items: + description: Matcher defines how to match on alert's + labels. + properties: + matchType: + description: |- + Match operation available with AlertManager >= v0.22.0 and + takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: |- + Whether to match on equality (false) or regular-expression (true). + Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + muteTimeIntervals: + description: |- + Note: this comment applies to the field definition above but appears + below otherwise it gets included in the generated manifest. + CRD schema doesn't support self-referential types for now (see + https://github.com/kubernetes/kubernetes/issues/62872). We have to use + an alternative type to circumvent the limitation. The downside is that + the Kube API can't validate the data beyond the fact that it is a valid + JSON representation. + MuteTimeIntervals is a list of MuteTimeInterval names that will mute this route when matched, + items: + type: string + type: array + receiver: + description: |- + Name of the receiver for this route. If not empty, it should be listed in + the `receivers` field. + type: string + repeatInterval: + description: |- + How long to wait before repeating the last notification. + Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` + Example: "4h" + type: string + routes: + description: Child routes. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + email: + description: Email necessary to send alerts via email + type: string + type: object + scheduling: + description: Scheduling contains settings to control the scheduling + of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a + node’s labels for the pod to be scheduled on that node + type: object + type: object + security: + description: Security contains settings to control the security + of a service. + properties: + allowAllNamespaces: + default: false + description: AllowAllNamespaces allows the service to be accessible + from all namespaces, this supersedes the AllowedNamespaces + field + type: boolean + allowedGroups: + description: AllowedGroups defines a list of Groups that have + limited access to the instance namespace + items: + type: string + type: array + allowedNamespaces: + description: AllowedNamespaces defines a list of namespaces + from where the service can be reached in the claim namespace + items: + type: string + type: array + allowedUsers: + description: AllowedUsers defines a list of Users that have + limited access to instance namespace. + items: + type: string + type: array + deletionProtection: + default: true + description: DeletionProtection blocks the deletion of the + instance if it is enabled (enabled by default) + type: boolean + type: object + service: + description: Service contains OpenBao DBaaS specific properties + properties: + openBaoSettings: + description: OpenBaoSettings contains additional OpenBao settings. + type: string + serviceLevel: + default: besteffort + description: ServiceLevel defines the service level of this + service. Either Best Effort or Guaranteed Availability is + allowed. + enum: + - besteffort + - guaranteed + type: string + version: + default: + description: |- + Version contains supported version of OpenBao. + Multiple versions are supported. The latest version is the default version. + enum: + - + type: string + type: object + size: + description: Size contains settings to control the sizing of a + service. + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for + an instance. + type: string + disk: + description: Disk defines the amount of disk space for an + instance. + type: string + memory: + description: Memory defines the amount of memory in units + of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines + the compute resources. + type: string + requests: + description: Requests defines CPU and memory requests for + an instance + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs + for an instance. + type: string + memory: + description: Memory defines the amount of memory in units + of bytes for an instance. + type: string + type: object + type: object + type: object + providerConfigRef: + default: + name: default + description: |- + ProviderConfigReference specifies how the provider that will be used to + create, observe, update, and delete this managed resource should be + configured. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: |- + Resolution specifies whether resolution of this reference is required. + The default is 'Required', which means the reconcile will fail if the + reference cannot be resolved. 'Optional' means this reference will be + a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: |- + Resolve specifies when this reference should be resolved. The default + is 'IfNotPresent', which will attempt to resolve the reference only when + the corresponding field is not present. Use 'Always' to resolve the + reference on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + publishConnectionDetailsTo: + description: |- + PublishConnectionDetailsTo specifies the connection secret config which + contains a name, metadata and a reference to secret store config to + which any connection details for this managed resource should be written. + Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + properties: + configRef: + default: + name: default + description: |- + SecretStoreConfigRef specifies which secret store config should be used + for this ConnectionSecret. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: |- + Resolution specifies whether resolution of this reference is required. + The default is 'Required', which means the reconcile will fail if the + reference cannot be resolved. 'Optional' means this reference will be + a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: |- + Resolve specifies when this reference should be resolved. The default + is 'IfNotPresent', which will attempt to resolve the reference only when + the corresponding field is not present. Use 'Always' to resolve the + reference on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + metadata: + description: Metadata is the metadata for connection secret. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations are the annotations to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.annotations". + - It is up to Secret Store implementation for others store types. + type: object + labels: + additionalProperties: + type: string + description: |- + Labels are the labels/tags to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.labels". + - It is up to Secret Store implementation for others store types. + type: object + type: + description: |- + Type is the SecretType for the connection secret. + - Only valid for Kubernetes Secret Stores. + type: string + type: object + name: + description: Name is the name of the connection secret. + type: string + required: + - name + type: object + writeConnectionSecretToRef: + description: |- + WriteConnectionSecretToReference specifies the namespace and name of a + Secret to which any connection details for this managed resource should + be written. Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + This field is planned to be replaced in a future release in favor of + PublishConnectionDetailsTo. Currently, both could be set independently + and connection details would be published to both without affecting + each other. + properties: + name: + description: Name of the secret. + type: string + namespace: + description: Namespace of the secret. + type: string + required: + - name + - namespace + type: object + type: object + status: + properties: + caCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + clientCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the last time this condition transitioned from one + status to another. + format: date-time + type: string + message: + description: |- + A Message containing details about this condition's last transition from + one status to another, if any. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + type: integer + reason: + description: A Reason for this condition's last transition from + one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: |- + Type of this condition. At most one of each condition type may apply to + a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceNamespace: + description: InstanceNamespace contains the name of the namespace + where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + observedGeneration: + description: |- + ObservedGeneration is the latest metadata.generation + which resulted in either a ready state, or stalled due to error + it can not recover from without human intervention. + format: int64 + type: integer + schedules: + description: |- + Schedules keeps track of random generated schedules, is overwriten by + schedules set in the service's spec. + properties: + backup: + description: Backup keeps track of the backup schedule. + type: string + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the last time this condition transitioned from one + status to another. + format: date-time + type: string + message: + description: |- + A Message containing details about this condition's last transition from + one status to another, if any. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + type: integer + reason: + description: A Reason for this condition's last transition + from one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: |- + Type of this condition. At most one of each condition type may apply to + a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + maintenance: + description: Maintenance keeps track of the maintenance schedule. + properties: + dayOfWeek: + description: |- + DayOfWeek specifies at which weekday the maintenance is held place. + Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: |- + TimeOfDay for installing updates in UTC. + Format: "hh:mm:ss". + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + observedGeneration: + description: |- + ObservedGeneration is the latest metadata.generation + which resulted in either a ready state, or stalled due to error + it can not recover from without human intervention. + format: int64 + type: integer + type: object + selfSignedIssuerConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + serverCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true From b71bcabff0d454172a852c39207a9f59a15c4f17 Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Wed, 22 Oct 2025 10:44:14 +0200 Subject: [PATCH 04/12] feat(openbao): implement example transformation --- apis/vshn/v1/dbaas_vshn_openbao.go | 6 + apis/vshn/v1/groupversion_info.go | 5 + cmd/functions.go | 1 + pkg/apiserver/vshn/openbao/vshnopenbao.go | 1 + .../functions/vshnopenbao/openbao_deploy.go | 137 ++++++++++++++++++ .../vshnopenbao/openbao_deploy_test.go | 49 +++++++ .../functions/vshnopenbao/register.go | 17 +++ .../vshnopenbao/deploy/01_default.yaml | 87 +++++++++++ 8 files changed, 303 insertions(+) create mode 100644 pkg/apiserver/vshn/openbao/vshnopenbao.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/register.go create mode 100644 test/functions/vshnopenbao/deploy/01_default.yaml diff --git a/apis/vshn/v1/dbaas_vshn_openbao.go b/apis/vshn/v1/dbaas_vshn_openbao.go index 562846e532..5bf91cb279 100644 --- a/apis/vshn/v1/dbaas_vshn_openbao.go +++ b/apis/vshn/v1/dbaas_vshn_openbao.go @@ -289,3 +289,9 @@ func (v *VSHNOpenBao) GetWorkloadName() string { func (v *VSHNOpenBao) GetWorkloadPodTemplateLabelsManager() PodTemplateLabelsManager { return &StatefulSetManager{} } + +// IsBackupEnabled returns true if backups are enabled for this instance +// MinIO doesn't currently support backups via K8up, so this always returns false +func (v *VSHNOpenBao) IsBackupEnabled() bool { + return false +} diff --git a/apis/vshn/v1/groupversion_info.go b/apis/vshn/v1/groupversion_info.go index fd967c62c5..5807b3c9da 100644 --- a/apis/vshn/v1/groupversion_info.go +++ b/apis/vshn/v1/groupversion_info.go @@ -59,5 +59,10 @@ func init() { &XVSHNForgejoList{}, &VSHNForgejo{}, &VSHNForgejoList{}, + + &XVSHNOpenBao{}, + &XVSHNOpenBaoList{}, + &VSHNOpenBao{}, + &VSHNOpenBaoList{}, ) } diff --git a/cmd/functions.go b/cmd/functions.go index b952be0fd6..7386b63075 100644 --- a/cmd/functions.go +++ b/cmd/functions.go @@ -15,6 +15,7 @@ import ( _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnmariadb" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnminio" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnnextcloud" + _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnopenbao" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnpostgres" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnpostgrescnpg" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnredis" diff --git a/pkg/apiserver/vshn/openbao/vshnopenbao.go b/pkg/apiserver/vshn/openbao/vshnopenbao.go new file mode 100644 index 0000000000..fc5acf43bc --- /dev/null +++ b/pkg/apiserver/vshn/openbao/vshnopenbao.go @@ -0,0 +1 @@ +package openbao diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go new file mode 100644 index 0000000000..37ce6f8d30 --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go @@ -0,0 +1,137 @@ +package vshnopenbao + +import ( + "context" + "encoding/json" + "fmt" + + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + xfnproto "github.com/crossplane/function-sdk-go/proto/v1" + xhelmbeta1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/common/utils" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/common" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" +) + +// DeployConfigMap creates a ConfigMap with a hello world message and today's date +func DeployOpenBao(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) *xfnproto.Result { + + serviceName := comp.GetServiceName() + err := svc.GetObservedComposite(comp) + if err != nil { + return runtime.NewFatalResult(fmt.Errorf("cannot get composite: %w", err)) + } + + svc.Log.Info("Bootstrapping instance namespace and rbac rules") + err = common.BootstrapInstanceNs(ctx, comp, serviceName, comp.GetName()+"-ns", svc) + if err != nil { + return runtime.NewWarningResult(fmt.Sprintf("cannot bootstrap instance namespace: %s", err)) + } + + svc.Log.Info("Creating helm release for OpenBao instance") + err = createObjectHelmRelease(ctx, comp, svc) + if err != nil { + err = fmt.Errorf("cannot create helm release: %w", err) + return runtime.NewFatalResult(err) + } + + return nil +} +func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { + + // The Components Appcat defines plans (how much CPU, memory etc) + // The XR object (created by user) defines only the plan. + // Users cannot choose exact CPU and memory request. That is defined in Components Appcat. + plan := comp.Spec.Parameters.Size.GetPlan(svc.Config.Data["defaultPlan"]) + + resouces, err := utils.FetchPlansFromConfig(ctx, svc, plan) + if err != nil { + err = fmt.Errorf("cannot fetch plans from the composition config, maybe they are not set: %w", err) + return err + } + + reqMem := comp.Spec.Parameters.Size.Requests.Memory + reqCPU := comp.Spec.Parameters.Size.Requests.CPU + mem := comp.Spec.Parameters.Size.Memory + cpu := comp.Spec.Parameters.Size.CPU + disk := comp.Spec.Parameters.Size.Disk + + if reqMem == "" { + reqMem = resouces.MemoryRequests.String() + } + if reqCPU == "" { + reqCPU = resouces.CPURequests.String() + } + if mem == "" { + mem = resouces.MemoryLimits.String() + } + if cpu == "" { + cpu = resouces.CPULimits.String() + } + if disk == "" { + disk = resouces.Disk.String() + } + + imageRegistry := svc.Config.Data["imageRegistry"] + + // Information like image registry and tag, can be stored as part of Components AppCat configuration + // It can differ from customer to customer. + if imageRegistry == "" { + err = fmt.Errorf("cannot fetch imageRegistry from the composition config, maybe they are not set: %w", err) + return err + } + + values := map[string]interface{}{ + "fullnameOverride": comp.GetName(), + "image": map[string]interface{}{ + "registry": imageRegistry, + }, + } + + vb, err := json.Marshal(values) + if err != nil { + err = fmt.Errorf("cannot marshal helm values: %w", err) + return err + } + + r := &xhelmbeta1.Release{ + ObjectMeta: metav1.ObjectMeta{ + Name: comp.GetName(), + }, + Spec: xhelmbeta1.ReleaseSpec{ + ForProvider: xhelmbeta1.ReleaseParameters{ + Chart: xhelmbeta1.ChartSpec{ + Repository: svc.Config.Data["chartRepository"], + Version: svc.Config.Data["chartVersion"], + Name: "openbao", + }, + Namespace: comp.GetInstanceNamespace(), + ValuesSpec: xhelmbeta1.ValuesSpec{ + Values: k8sruntime.RawExtension{ + Raw: vb, + }, + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "helm", + }, + WriteConnectionSecretToReference: &xpv1.SecretReference{ + Name: comp.GetName() + "-connection", + Namespace: comp.GetInstanceNamespace(), + }, + }, + ConnectionDetails: []xhelmbeta1.ConnectionDetail{}, + }, + } + + err = svc.AddObservedConnectionDetails(comp.Name + "-release") + if err != nil { + return err + } + + return svc.SetDesiredComposedResourceWithName(r, comp.Name+"-release") +} diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go new file mode 100644 index 0000000000..f31cb6e6cc --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go @@ -0,0 +1,49 @@ +package vshnopenbao + +import ( + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + xhelmbeta1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/commontest" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + corev1 "k8s.io/api/core/v1" +) + +func TestDeployOpenBao(t *testing.T) { + svc, comp := getOpenBaoTestComp(t) + + ctx := context.TODO() + + assert.Nil(t, DeployOpenBao(ctx, comp, svc)) + + ns := &corev1.Namespace{} + assert.NoError(t, svc.GetObservedKubeObject(ns, comp.Name+"-ns")) + + r := &xhelmbeta1.Release{} + assert.NoError(t, svc.GetDesiredComposedResourceByName(r, comp.Name+"-release")) + + var values map[string]interface{} + assert.NoError(t, json.Unmarshal(r.Spec.ForProvider.Values.Raw, &values)) + + assert.Contains(t, values, "image") + image := values["image"].(map[string]interface{}) + + assert.Contains(t, image, "registry") + imageRegistry := image["registry"].(string) + + assert.Equal(t, svc.Config.Data["imageRegistry"], imageRegistry) +} + +func getOpenBaoTestComp(t *testing.T) (*runtime.ServiceRuntime, *vshnv1.VSHNOpenBao) { + svc := commontest.LoadRuntimeFromFile(t, "vshnopenbao/deploy/01_default.yaml") + + comp := &vshnv1.VSHNOpenBao{} + err := svc.GetObservedComposite(comp) + assert.NoError(t, err) + + return svc, comp +} diff --git a/pkg/comp-functions/functions/vshnopenbao/register.go b/pkg/comp-functions/functions/vshnopenbao/register.go new file mode 100644 index 0000000000..69b70eb809 --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/register.go @@ -0,0 +1,17 @@ +package vshnopenbao + +import ( + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" +) + +func init() { + runtime.RegisterService[*vshnv1.VSHNOpenBao]("openbao", runtime.Service[*vshnv1.VSHNOpenBao]{ + Steps: []runtime.Step[*vshnv1.VSHNOpenBao]{ + { + Name: "deploy", + Execute: DeployOpenBao, + }, + }, + }) +} diff --git a/test/functions/vshnopenbao/deploy/01_default.yaml b/test/functions/vshnopenbao/deploy/01_default.yaml new file mode 100644 index 0000000000..293baea8c2 --- /dev/null +++ b/test/functions/vshnopenbao/deploy/01_default.yaml @@ -0,0 +1,87 @@ +desired: {} +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNOpenBao + metadata: + name: openbao-gc9x4 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: openbao + crossplane.io/claim-namespace: unit-test + spec: + parameters: + service: + version: "2.0.0" + size: + plan: standard-1 + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNOpenBao + name: openbao + namespace: unit-test + compositionRef: + name: vshnopenbao.vshn.appcat.vshn.io + compositionUpdatePolicy: Automatic + resources: + openbao-gc9x4-claim-ns-observer: + resource: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + name: openbao-gc9x4-claim-ns-observer + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Namespace + metadata: + name: unit-test + labels: + 'appuio.io/organization': 'vshn' + status: + atProvider: + manifest: + apiVersion: v1 + kind: Namespace + metadata: + name: unit-test + labels: + 'appuio.io/organization': 'vshn' + openbao-gc9x4-ns: + resource: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + name: vshn-openbao-openbao-gc9x4 + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Namespace + metadata: + name: vshn-openbao-openbao-gc9x4 + status: + atProvider: + manifest: + apiVersion: v1 + kind: Namespace + metadata: + name: vshn-openbao-openbao-gc9x4 +input: + apiVersion: v1 + data: + defaultPlan: standard-1 + openBaoChartRepo: https://openbao.github.io/openbao-helm + openBaoChartVersion: 0.4.0 + controlNamespace: appcat-control + plans: '{"standard-1": {"size": {"cpu": "250m", "disk": "16Gi", "enabled": true, "memory": "1Gi"}}}' + imageRegistry: ghcr.io/openbao + providerEnabled: "true" + kind: ConfigMap + metadata: + annotations: {} + labels: + name: xfn-config + name: xfn-config From a494424b1c848880bd23269047de771a5dfe7f25 Mon Sep 17 00:00:00 2001 From: Yannik Daellenbach Date: Fri, 31 Oct 2025 17:38:45 +0100 Subject: [PATCH 05/12] feat(openbao): add auto-unseal configuration support Add structured OpenBaoSettings type with support for multiple auto-unseal methods including AWS KMS, Azure Key Vault, GCP KMS, and Transit. Update CRDs and generate corresponding deepcopy methods. --- apis/vshn/v1/dbaas_vshn_openbao.go | 22 ++++++- apis/vshn/v1/zz_generated.deepcopy.go | 36 ++++++++++++ crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml | 55 +++++++++++++++++- crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml | 61 +++++++++++++++++++- 4 files changed, 170 insertions(+), 4 deletions(-) diff --git a/apis/vshn/v1/dbaas_vshn_openbao.go b/apis/vshn/v1/dbaas_vshn_openbao.go index 5bf91cb279..53266d6199 100644 --- a/apis/vshn/v1/dbaas_vshn_openbao.go +++ b/apis/vshn/v1/dbaas_vshn_openbao.go @@ -75,7 +75,7 @@ type VSHNOpenBaoParameters struct { Instances int `json:"instances,omitempty"` } -// VSHNOpenBaoServiceSpec contains OpenBao DBaaS specific properties +// VSHNOpenBaoServiceSpec contains OpenBao specific properties type VSHNOpenBaoServiceSpec struct { // +kubebuilder:validation:Enum= // +kubebuilder:default= @@ -85,7 +85,7 @@ type VSHNOpenBaoServiceSpec struct { Version string `json:"version,omitempty"` // OpenBaoSettings contains additional OpenBao settings. - OpenBaoSettings string `json:"openBaoSettings,omitempty"` + OpenBaoSettings VSHNOpenBaoSettings `json:"openBaoSettings,omitempty"` // +kubebuilder:validation:Enum="besteffort";"guaranteed" // +kubebuilder:default="besteffort" @@ -94,6 +94,24 @@ type VSHNOpenBaoServiceSpec struct { ServiceLevel VSHNDBaaSServiceLevel `json:"serviceLevel,omitempty"` } +// VSHNOpenBaoSettings contains OpenBao settings +type VSHNOpenBaoSettings struct { + // AutoUnseal configures various auto unseal methods. + AutoUnseal VSHNOpenBaoSettingsAutoUnseal `json:"version,omitempty"` +} + +// VSHNOpenBaoSettingsAutoUnseal contains OpenBao auto-unseal configuration +type VSHNOpenBaoSettingsAutoUnseal struct { + // AWSKmsSecretRef references to secret containing AWS KMS credentials and configuration + AWSKmsSecretRef LocalObjectReference `json:"awsKmsSecretRef,omitempty"` + // AzureKeyVaultSecretRef references to secret containing Azure Key Vault credentials and configuration + AzureKeyVaultSecretRef LocalObjectReference `json:"azureKeyVaultSecretRef,omitempty"` + // GCPKmsSecretRef references to secret containing GCP KMS credentials and configuration + GCPKmsSecretRef LocalObjectReference `json:"gcpKmsSecretRef,omitempty"` + // TransitSecretRef references to secret containing Transit auto-unseal configuration + TransitSecretRef LocalObjectReference `json:"transitSecretRef,omitempty"` +} + // VSHNOpenBaoSizeSpec contains settings to control the sizing of a service. type VSHNOpenBaoSizeSpec struct { diff --git a/apis/vshn/v1/zz_generated.deepcopy.go b/apis/vshn/v1/zz_generated.deepcopy.go index 87c9e7dcfd..cbd31bbff5 100644 --- a/apis/vshn/v1/zz_generated.deepcopy.go +++ b/apis/vshn/v1/zz_generated.deepcopy.go @@ -1544,6 +1544,7 @@ func (in *VSHNOpenBaoParameters) DeepCopy() *VSHNOpenBaoParameters { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VSHNOpenBaoServiceSpec) DeepCopyInto(out *VSHNOpenBaoServiceSpec) { *out = *in + out.OpenBaoSettings = in.OpenBaoSettings } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoServiceSpec. @@ -1556,6 +1557,41 @@ func (in *VSHNOpenBaoServiceSpec) DeepCopy() *VSHNOpenBaoServiceSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoSettings) DeepCopyInto(out *VSHNOpenBaoSettings) { + *out = *in + out.AutoUnseal = in.AutoUnseal +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoSettings. +func (in *VSHNOpenBaoSettings) DeepCopy() *VSHNOpenBaoSettings { + if in == nil { + return nil + } + out := new(VSHNOpenBaoSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNOpenBaoSettingsAutoUnseal) DeepCopyInto(out *VSHNOpenBaoSettingsAutoUnseal) { + *out = *in + out.AWSKmsSecretRef = in.AWSKmsSecretRef + out.AzureKeyVaultSecretRef = in.AzureKeyVaultSecretRef + out.GCPKmsSecretRef = in.GCPKmsSecretRef + out.TransitSecretRef = in.TransitSecretRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNOpenBaoSettingsAutoUnseal. +func (in *VSHNOpenBaoSettingsAutoUnseal) DeepCopy() *VSHNOpenBaoSettingsAutoUnseal { + if in == nil { + return nil + } + out := new(VSHNOpenBaoSettingsAutoUnseal) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VSHNOpenBaoSizeSpec) DeepCopyInto(out *VSHNOpenBaoSizeSpec) { *out = *in diff --git a/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml index 0411d0df6e..703c837713 100644 --- a/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml +++ b/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml @@ -4593,7 +4593,60 @@ spec: properties: openBaoSettings: description: OpenBaoSettings contains additional OpenBao settings. - type: string + properties: + version: + description: AutoUnseal configures various auto unseal methods. + properties: + awsKmsSecretRef: + description: AWSKmsSecretRef references to secret containing AWS KMS credentials and configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + azureKeyVaultSecretRef: + description: AzureKeyVaultSecretRef references to secret containing Azure Key Vault credentials and configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + gcpKmsSecretRef: + description: GCPKmsSecretRef references to secret containing GCP KMS credentials and configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + transitSecretRef: + description: TransitSecretRef references to secret containing Transit auto-unseal configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: object serviceLevel: default: besteffort description: ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. diff --git a/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml index 104ba4edb8..f609f830b3 100644 --- a/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml +++ b/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml @@ -5317,7 +5317,66 @@ spec: properties: openBaoSettings: description: OpenBaoSettings contains additional OpenBao settings. - type: string + properties: + version: + description: AutoUnseal configures various auto unseal + methods. + properties: + awsKmsSecretRef: + description: AWSKmsSecretRef references to secret + containing AWS KMS credentials and configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + azureKeyVaultSecretRef: + description: AzureKeyVaultSecretRef references to + secret containing Azure Key Vault credentials and + configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + gcpKmsSecretRef: + description: GCPKmsSecretRef references to secret + containing GCP KMS credentials and configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + transitSecretRef: + description: TransitSecretRef references to secret + containing Transit auto-unseal configuration + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: object serviceLevel: default: besteffort description: ServiceLevel defines the service level of this From 7012a58fd9f96006378a977086e1bb409d530ea3 Mon Sep 17 00:00:00 2001 From: Yannik Daellenbach Date: Tue, 25 Nov 2025 15:50:08 +0100 Subject: [PATCH 06/12] Fix OpenBao resource plural naming --- apis/vshn/v1/dbaas_vshn_openbao.go | 12 +++++++----- ...es.yaml => vshn.appcat.vshn.io_vshnopenbaos.yaml} | 4 ++-- ...s.yaml => vshn.appcat.vshn.io_xvshnopenbaos.yaml} | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) rename crds/{vshn.appcat.vshn.io_vshnopenbaoes.yaml => vshn.appcat.vshn.io_vshnopenbaos.yaml} (99%) rename crds/{vshn.appcat.vshn.io_xvshnopenbaoes.yaml => vshn.appcat.vshn.io_xvshnopenbaos.yaml} (99%) diff --git a/apis/vshn/v1/dbaas_vshn_openbao.go b/apis/vshn/v1/dbaas_vshn_openbao.go index 53266d6199..0c402c1859 100644 --- a/apis/vshn/v1/dbaas_vshn_openbao.go +++ b/apis/vshn/v1/dbaas_vshn_openbao.go @@ -9,16 +9,17 @@ import ( // Workaround to make nested defaulting work. // kubebuilder is unable to set a {} default -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" -//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaoes.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.security.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnopenbaos.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.security.default={})" // +kubebuilder:object:root=true // VSHNOpenBao is the API for creating OpenBao instances. +// +kubebuilder:resource:path=vshnopenbaos type VSHNOpenBao struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -165,6 +166,7 @@ func (v *VSHNOpenBao) SetInstanceNamespaceStatus() { // +kubebuilder:object:root=true // XVSHNOpenBao represents the internal composite of this claim +// +kubebuilder:resource:path=xvshnopenbaos type XVSHNOpenBao struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_vshnopenbaos.yaml similarity index 99% rename from crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml rename to crds/vshn.appcat.vshn.io_vshnopenbaos.yaml index 703c837713..23d60174c5 100644 --- a/crds/vshn.appcat.vshn.io_vshnopenbaoes.yaml +++ b/crds/vshn.appcat.vshn.io_vshnopenbaos.yaml @@ -4,13 +4,13 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.5 - name: vshnopenbaoes.vshn.appcat.vshn.io + name: vshnopenbaos.vshn.appcat.vshn.io spec: group: vshn.appcat.vshn.io names: kind: VSHNOpenBao listKind: VSHNOpenBaoList - plural: vshnopenbaoes + plural: vshnopenbaos singular: vshnopenbao scope: Namespaced versions: diff --git a/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml b/crds/vshn.appcat.vshn.io_xvshnopenbaos.yaml similarity index 99% rename from crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml rename to crds/vshn.appcat.vshn.io_xvshnopenbaos.yaml index f609f830b3..5c69bea041 100644 --- a/crds/vshn.appcat.vshn.io_xvshnopenbaoes.yaml +++ b/crds/vshn.appcat.vshn.io_xvshnopenbaos.yaml @@ -4,13 +4,13 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.16.5 - name: xvshnopenbaoes.vshn.appcat.vshn.io + name: xvshnopenbaos.vshn.appcat.vshn.io spec: group: vshn.appcat.vshn.io names: kind: XVSHNOpenBao listKind: XVSHNOpenBaoList - plural: xvshnopenbaoes + plural: xvshnopenbaos singular: xvshnopenbao scope: Namespaced versions: From aae7c6dda7f710291839d6c3b731de40d1c7e6c0 Mon Sep 17 00:00:00 2001 From: Yannik Daellenbach Date: Wed, 26 Nov 2025 11:05:13 +0100 Subject: [PATCH 07/12] Init sample `VSHNOpenBao` manifest --- hack/openbao.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 hack/openbao.yaml diff --git a/hack/openbao.yaml b/hack/openbao.yaml new file mode 100644 index 0000000000..56b75a48ac --- /dev/null +++ b/hack/openbao.yaml @@ -0,0 +1,7 @@ +apiVersion: vshn.appcat.vshn.io/v1 +kind: VSHNOpenBao +metadata: + name: openbao-test +spec: + writeConnectionSecretToRef: + name: "openbao-test" \ No newline at end of file From 2d3d8d7b22268fbac119c8efedd39eb402b82b80 Mon Sep 17 00:00:00 2001 From: Yannik Daellenbach Date: Wed, 26 Nov 2025 11:31:12 +0100 Subject: [PATCH 08/12] Refactor OpenBao Helm configuration and simplify resource assignment Simplifies resource default handling using cmp.Or() and restructures the Helm values to properly configure OpenBao server settings including resource limits and data storage, while disabling agent and injector components. --- .../functions/vshnopenbao/openbao_deploy.go | 62 +++++++++---------- .../vshnopenbao/openbao_deploy_test.go | 8 --- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go index 37ce6f8d30..eb98554df9 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go @@ -1,6 +1,7 @@ package vshnopenbao import ( + "cmp" "context" "encoding/json" "fmt" @@ -53,41 +54,38 @@ func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc return err } - reqMem := comp.Spec.Parameters.Size.Requests.Memory - reqCPU := comp.Spec.Parameters.Size.Requests.CPU - mem := comp.Spec.Parameters.Size.Memory - cpu := comp.Spec.Parameters.Size.CPU - disk := comp.Spec.Parameters.Size.Disk - - if reqMem == "" { - reqMem = resouces.MemoryRequests.String() - } - if reqCPU == "" { - reqCPU = resouces.CPURequests.String() - } - if mem == "" { - mem = resouces.MemoryLimits.String() - } - if cpu == "" { - cpu = resouces.CPULimits.String() - } - if disk == "" { - disk = resouces.Disk.String() - } - - imageRegistry := svc.Config.Data["imageRegistry"] - - // Information like image registry and tag, can be stored as part of Components AppCat configuration - // It can differ from customer to customer. - if imageRegistry == "" { - err = fmt.Errorf("cannot fetch imageRegistry from the composition config, maybe they are not set: %w", err) - return err - } + reqMem := cmp.Or(comp.Spec.Parameters.Size.Requests.Memory, resouces.MemoryRequests.String()) + reqCPU := cmp.Or(comp.Spec.Parameters.Size.Requests.CPU, resouces.CPURequests.String()) + mem := cmp.Or(comp.Spec.Parameters.Size.Memory, resouces.MemoryLimits.String()) + cpu := cmp.Or(comp.Spec.Parameters.Size.CPU, resouces.CPULimits.String()) + disk := cmp.Or(comp.Spec.Parameters.Size.Disk, resouces.Disk.String()) values := map[string]interface{}{ "fullnameOverride": comp.GetName(), - "image": map[string]interface{}{ - "registry": imageRegistry, + "agent": map[string]any{ + "enabled": false, + }, + "injector": map[string]any{ + "enabled": false, + }, + "server": map[string]any{ + "authDelegator": map[string]any{ + "enabled": false, + }, + "resources": map[string]any{ + "requests": map[string]any{ + "memory": reqMem, + "cpu": reqCPU, + }, + "limits": map[string]any{ + "memory": mem, + "cpu": cpu, + }, + }, + "dataStorage": map[string]any{ + "enabled": true, + "size": disk, + }, }, } diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go index f31cb6e6cc..00f5811b41 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy_test.go @@ -28,14 +28,6 @@ func TestDeployOpenBao(t *testing.T) { var values map[string]interface{} assert.NoError(t, json.Unmarshal(r.Spec.ForProvider.Values.Raw, &values)) - - assert.Contains(t, values, "image") - image := values["image"].(map[string]interface{}) - - assert.Contains(t, image, "registry") - imageRegistry := image["registry"].(string) - - assert.Equal(t, svc.Config.Data["imageRegistry"], imageRegistry) } func getOpenBaoTestComp(t *testing.T) (*runtime.ServiceRuntime, *vshnv1.VSHNOpenBao) { From d95e45ae8b297bda213faac43bd572eda9407b29 Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Fri, 5 Dec 2025 14:17:31 +0100 Subject: [PATCH 09/12] Implement HCL Structs and parsing functions --- go.mod | 7 +- go.sum | 4 + .../functions/vshnopenbao/openbao_config.go | 144 ++++++++++++++++++ .../vshnopenbao/openbao_config_test.go | 119 +++++++++++++++ .../functions/vshnopenbao/openbao_deploy.go | 7 + .../functions/vshnopenbao/utils.go | 19 +++ .../vshnopenbao/deploy/01_default.yaml | 4 +- 7 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 pkg/comp-functions/functions/vshnopenbao/openbao_config.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/utils.go diff --git a/go.mod b/go.mod index ebcfd52d92..3c527e6ddc 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/hashicorp/go-version v1.7.0 + github.com/hashicorp/hcl/v2 v2.21.0 github.com/iancoleman/strcase v0.2.0 github.com/jackc/pgx/v5 v5.7.1 github.com/k8up-io/k8up/v2 v2.7.1 @@ -43,6 +44,7 @@ require ( github.com/vshn/provider-cloudscale v0.5.2 github.com/vshn/provider-exoscale v0.11.2-0.20240730092820-016cddb3d704 github.com/vshn/provider-minio v0.3.0 + github.com/zclconf/go-cty v1.14.4 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 golang.org/x/text v0.22.0 @@ -77,12 +79,14 @@ require ( github.com/Masterminds/semver v1.5.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/agext/levenshtein v1.2.3 // indirect github.com/alecthomas/kingpin/v2 v2.4.0 // indirect github.com/alecthomas/kong v0.9.0 // indirect github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.30.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.21 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.21 // indirect @@ -153,6 +157,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/openshift/api v0.0.0-20230213134911-7ba313770556 // indirect @@ -266,7 +271,7 @@ require ( golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/term v0.29.0 // indirect - golang.org/x/time v0.6.0 // indirect + golang.org/x/time v0.6.0 golang.org/x/tools v0.26.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.35.1 diff --git a/go.sum b/go.sum index 391b17302e..8c42e80580 100644 --- a/go.sum +++ b/go.sum @@ -269,6 +269,8 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -649,6 +651,8 @@ github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0= diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go new file mode 100644 index 0000000000..f477471a57 --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go @@ -0,0 +1,144 @@ +package vshnopenbao + +import ( + "fmt" + + "github.com/hashicorp/hcl/v2/gohcl" + "github.com/hashicorp/hcl/v2/hclparse" + "github.com/hashicorp/hcl/v2/hclwrite" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type OpenBaoConfig struct { + UI bool `hcl:"ui,optional"` + LogLevel string `hcl:"log_level,optional"` + LogFormat string `hcl:"log_format,optional"` + ClusterName string `hcl:"cluster_name,optional"` + APIAddr string `hcl:"api_addr,optional"` + ClusterAddr string `hcl:"cluster_addr,optional"` + PidFile string `hcl:"pid_file,optional"` + Listeners []ListenerBlock `hcl:"listener,block"` +} + +type OpenBaoConfigOption func(*OpenBaoConfig) + +type ListenerBlock struct { + Type string `hcl:"type,label"` + Address string `hcl:"address"` + ClusterAddress string `hcl:"cluster_address,optional"` + TLSDisable bool `hcl:"tls_disable,optional"` + TLSCertFile string `hcl:"tls_cert_file,optional"` + TLSKeyFile string `hcl:"tls_key_file,optional"` + TLSMinVersion string `hcl:"tls_min_version,optional"` + TLSMaxVersion string `hcl:"tls_max_version,optional"` + MaxRequestSize *int64 `hcl:"max_request_size,optional"` + MaxRequestDuration string `hcl:"max_request_duration,optional"` +} + +func NewOpenBaoConfig(opts ...OpenBaoConfigOption) *OpenBaoConfig { + config := &OpenBaoConfig{} + + for _, opt := range opts { + opt(config) + } + + return config +} + +func EmptyOption() OpenBaoConfigOption { + return func(config *OpenBaoConfig) {} +} + +func WithDefaultOptions() OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.UI = true + + config.LogLevel = "info" + config.LogFormat = "json" + + config.APIAddr = "https://openbao:8200" + config.ClusterAddr = "https://openbao:8201" + + config.PidFile = "/var/run/openbao.pid" + + config.Listeners = []ListenerBlock{ + { + Type: "tcp", + Address: "0.0.0.0:8200", + ClusterAddress: "0.0.0.0:8201", + TLSDisable: false, + TLSCertFile: "/etc/openbao/tls/cåert.pem", + TLSKeyFile: "/etc/openbao/tls/key.pem", + TLSMinVersion: "tls12", + }, + } + } +} + +func WithClusterName(clusterName string) OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.ClusterName = clusterName + } +} + +func writeHCLConfig(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { + configSecretResourceName := fmt.Sprintf("%s-config", comp.Name) + + config := buildHclConfig(comp) + hclBytes := EncodeHCL(config) + + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: configSecretResourceName, + Namespace: comp.GetInstanceNamespace(), + }, + Data: map[string][]byte{ + "config.hcl": hclBytes, + }, + } + + err := svc.SetDesiredKubeObject(secret, configSecretResourceName) + if err != nil { + return fmt.Errorf("cannot add %s secret object: %w", configSecretResourceName, err) + } + + return nil +} + +func buildHclConfig(comp *vshnv1.VSHNOpenBao) *OpenBaoConfig { + serviceName := comp.GetServiceName() + + return NewOpenBaoConfig( + WithDefaultOptions(), + WithClusterName(serviceName), + ) +} + +// EncodeHCL encodes an OpenBaoConfig struct into HCL format bytes. +// Returns the HCL-formatted byte slice. +func EncodeHCL(config *OpenBaoConfig) []byte { + hclFile := hclwrite.NewEmptyFile() + gohcl.EncodeIntoBody(config, hclFile.Body()) + return hclFile.Bytes() +} + +// DecodeHCL decodes HCL format bytes into an OpenBaoConfig struct. +// Returns the decoded config and an error if parsing or decoding fails. +func DecodeHCL(hclBytes []byte, filename string) (*OpenBaoConfig, error) { + parser := hclparse.NewParser() + hclFile, diag := parser.ParseHCL(hclBytes, filename) + if diag.HasErrors() { + return nil, fmt.Errorf("failed to parse HCL: %w", diag) + } + + var config OpenBaoConfig + diag = gohcl.DecodeBody(hclFile.Body, nil, &config) + if diag.HasErrors() { + return nil, fmt.Errorf("failed to decode HCL: %w", diag) + } + + return &config, nil +} diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go new file mode 100644 index 0000000000..34bd8cfc09 --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go @@ -0,0 +1,119 @@ +package vshnopenbao + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" +) + +func TestBuildHclConfig(t *testing.T) { + svc, comp := getOpenBaoTestComp(t) + + ctx := context.TODO() + + // Deploy OpenBao and all related resources + assert.Nil(t, DeployOpenBao(ctx, comp, svc)) + + ns := &corev1.Namespace{} + assert.NoError(t, svc.GetObservedKubeObject(ns, comp.Name+"-ns")) + + // Test HCL config secret creation + configSecretName := comp.Name + "-config" + secret := &corev1.Secret{} + assert.NoError(t, svc.GetDesiredKubeObject(secret, configSecretName)) + + // Verify secret has the expected namespace + assert.Equal(t, comp.GetInstanceNamespace(), secret.Namespace) + assert.Equal(t, configSecretName, secret.Name) + + // Verify secret contains the HCL config data + require.Contains(t, secret.Data, "config.hcl", "Secret should contain config.hcl key") + hclBytes := secret.Data["config.hcl"] + require.NotEmpty(t, hclBytes, "HCL config should not be empty") + + // Parse and validate the HCL configuration using the DecodeHCL helper + parsedConfig, err := DecodeHCL(hclBytes, "config.hcl") + require.NoError(t, err, "HCL should decode properly") + require.NotNil(t, parsedConfig, "Parsed config should not be nil") + + // Verify the configuration values + assert.True(t, parsedConfig.UI, "UI should be enabled") + assert.Equal(t, "info", parsedConfig.LogLevel) + assert.Equal(t, "json", parsedConfig.LogFormat) + assert.Equal(t, comp.GetServiceName(), parsedConfig.ClusterName, "ClusterName should match service name") + assert.Equal(t, "https://openbao:8200", parsedConfig.APIAddr) + assert.Equal(t, "https://openbao:8201", parsedConfig.ClusterAddr) + assert.Equal(t, "/var/run/openbao.pid", parsedConfig.PidFile) + + // Verify listener configuration + require.Len(t, parsedConfig.Listeners, 1, "Should have exactly one listener") + listener := parsedConfig.Listeners[0] + assert.Equal(t, "tcp", listener.Type) + assert.Equal(t, "0.0.0.0:8200", listener.Address) + assert.Equal(t, "0.0.0.0:8201", listener.ClusterAddress) + assert.False(t, listener.TLSDisable, "TLS should be enabled") + assert.NotEmpty(t, listener.TLSCertFile, "TLS cert file should be set") + assert.NotEmpty(t, listener.TLSKeyFile, "TLS key file should be set") + assert.Equal(t, "tls12", listener.TLSMinVersion) +} + +// TestEncodeDecodeHCL tests the EncodeHCL and DecodeHCL helper functions +func TestEncodeDecodeHCL(t *testing.T) { + // Create a test config + originalConfig := NewOpenBaoConfig( + WithDefaultOptions(), + WithClusterName("test-cluster"), + ) + + // Encode to HCL + hclBytes := EncodeHCL(originalConfig) + require.NotEmpty(t, hclBytes, "Encoded HCL should not be empty") + + // Decode back to config + decodedConfig, err := DecodeHCL(hclBytes, "config.hcl") + require.NoError(t, err, "Decoding should succeed") + require.NotNil(t, decodedConfig, "Decoded config should not be nil") + + // Verify the round-trip encoding/decoding preserves values + assert.Equal(t, originalConfig.UI, decodedConfig.UI) + assert.Equal(t, originalConfig.LogLevel, decodedConfig.LogLevel) + assert.Equal(t, originalConfig.LogFormat, decodedConfig.LogFormat) + assert.Equal(t, originalConfig.ClusterName, decodedConfig.ClusterName) + assert.Equal(t, originalConfig.APIAddr, decodedConfig.APIAddr) + assert.Equal(t, originalConfig.ClusterAddr, decodedConfig.ClusterAddr) + assert.Equal(t, originalConfig.PidFile, decodedConfig.PidFile) + assert.Len(t, decodedConfig.Listeners, len(originalConfig.Listeners)) + + // Verify listener details + if len(originalConfig.Listeners) > 0 && len(decodedConfig.Listeners) > 0 { + origListener := originalConfig.Listeners[0] + decListener := decodedConfig.Listeners[0] + assert.Equal(t, origListener.Type, decListener.Type) + assert.Equal(t, origListener.Address, decListener.Address) + assert.Equal(t, origListener.ClusterAddress, decListener.ClusterAddress) + assert.Equal(t, origListener.TLSDisable, decListener.TLSDisable) + assert.Equal(t, origListener.TLSCertFile, decListener.TLSCertFile) + assert.Equal(t, origListener.TLSKeyFile, decListener.TLSKeyFile) + assert.Equal(t, origListener.TLSMinVersion, decListener.TLSMinVersion) + } +} + +// TestDecodeHCLInvalidInput tests DecodeHCL with invalid input +func TestDecodeHCLInvalidInput(t *testing.T) { + // Test with invalid HCL + invalidHCL := []byte("this is not valid HCL {{{") + config, err := DecodeHCL(invalidHCL, "config.hcl") + assert.Error(t, err, "Should return error for invalid HCL") + assert.Nil(t, config, "Config should be nil on error") + + // Test with empty input + emptyHCL := []byte("") + config, err = DecodeHCL(emptyHCL, "config.hcl") + // Empty HCL might be valid but result in empty config + if err == nil { + assert.NotNil(t, config, "Config should not be nil if no error") + } +} diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go index eb98554df9..71d478dcdb 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go @@ -32,6 +32,13 @@ func DeployOpenBao(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.S return runtime.NewWarningResult(fmt.Sprintf("cannot bootstrap instance namespace: %s", err)) } + svc.Log.Info("Creating HCL Configuration and saving it as a Secret") + err = writeHCLConfig(comp, svc) + if err != nil { + err = fmt.Errorf("cannot create HCL Config: %w", err) + return runtime.NewFatalResult(err) + } + svc.Log.Info("Creating helm release for OpenBao instance") err = createObjectHelmRelease(ctx, comp, svc) if err != nil { diff --git a/pkg/comp-functions/functions/vshnopenbao/utils.go b/pkg/comp-functions/functions/vshnopenbao/utils.go new file mode 100644 index 0000000000..8e7ed406aa --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/utils.go @@ -0,0 +1,19 @@ +package vshnopenbao + +type OpenBaoTLSCertificate struct { + // CACert string + // Key string + // ClientCA string + + CACertFile string + KeyFile string + ClientCAFile string +} + +func NewOpenBaoTLSCertificate() *OpenBaoTLSCertificate { + return &OpenBaoTLSCertificate{ + CACertFile: "/etc/ssl/certs/ca.crt", + KeyFile: "/etc/ssl/private/key.pem", + ClientCAFile: "/etc/ssl/certs/client-ca.crt", + } +} diff --git a/test/functions/vshnopenbao/deploy/01_default.yaml b/test/functions/vshnopenbao/deploy/01_default.yaml index 293baea8c2..2cd171be72 100644 --- a/test/functions/vshnopenbao/deploy/01_default.yaml +++ b/test/functions/vshnopenbao/deploy/01_default.yaml @@ -73,8 +73,8 @@ input: apiVersion: v1 data: defaultPlan: standard-1 - openBaoChartRepo: https://openbao.github.io/openbao-helm - openBaoChartVersion: 0.4.0 + chartRepository: https://openbao.github.io/openbao-helm + chartVersion: 0.4.0 controlNamespace: appcat-control plans: '{"standard-1": {"size": {"cpu": "250m", "disk": "16Gi", "enabled": true, "memory": "1Gi"}}}' imageRegistry: ghcr.io/openbao From 493bfbfdb8a898c7f7f294a6dc665ef8e5e20de8 Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Tue, 6 Jan 2026 10:21:12 +0100 Subject: [PATCH 10/12] Bootstrap TLS Certificates for OpenBao --- .../functions/vshnopenbao/tls.go | 244 ++++++++++++++ .../functions/vshnopenbao/tls_test.go | 312 ++++++++++++++++++ 2 files changed, 556 insertions(+) create mode 100644 pkg/comp-functions/functions/vshnopenbao/tls.go create mode 100644 pkg/comp-functions/functions/vshnopenbao/tls_test.go diff --git a/pkg/comp-functions/functions/vshnopenbao/tls.go b/pkg/comp-functions/functions/vshnopenbao/tls.go new file mode 100644 index 0000000000..30d12e382b --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/tls.go @@ -0,0 +1,244 @@ +package vshnopenbao + +import ( + "context" + "fmt" + "time" + + cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" + xkube "github.com/vshn/appcat/v4/apis/kubernetes/v1alpha2" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/common" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { + serviceName := comp.GetName() + ns := comp.GetInstanceNamespace() + + selfSignedIssuerName := serviceName + "-selfsigned-issuer" + + rootCAName := serviceName + "-ca" + rootCASecretName := serviceName + "-ca-tls" + rootCAIssuerName := serviceName + "-ca-issuer" + + openBaoServerCertName := serviceName + "-server" + openBaoServerCertSecretName := serviceName + "-server-tls" + + selfSignedIssuerOpts := &common.TLSOptions{ + IssuerOptions: []common.IssuerOption{ + withIssuerOfTypeSelfSigned(), + }, + } + selfSignedIssuer := createIssuer(ns, selfSignedIssuerName, selfSignedIssuerOpts) + err := svc.SetDesiredKubeObject(selfSignedIssuer, selfSignedIssuerName, selfSignedIssuerOpts.KubeOptions...) + if err != nil { + err = fmt.Errorf("cannot create Self Signed Issuer for OpenBao %w", err) + return err + } + + rootCAOpts := &common.TLSOptions{ + CertOptions: []common.CertOptions{ + withCertificateSecretName(rootCASecretName), + withCertificateDuration(time.Duration(87600 * time.Hour)), + withCertificateRenewBefore(time.Duration(2400 * time.Hour)), + withCertificateIssuerRef(selfSignedIssuerName), + withCertificateIsCA(true), + }, + KubeOptions: []runtime.KubeObjectOption{}, + } + rootCA := createCertificate(ns, rootCAName, rootCAOpts) + err = svc.SetDesiredKubeObject(rootCA, rootCAName, rootCAOpts.KubeOptions...) + if err != nil { + err = fmt.Errorf("cannot create Root CA with Self Signed Issuer for OpenBao %w", err) + return err + } + + rootCAIssuerOpts := &common.TLSOptions{ + IssuerOptions: []common.IssuerOption{ + withIssuerOfTypeCA(rootCASecretName), + }, + } + rootCAIssuer := createIssuer(ns, rootCAIssuerName, rootCAIssuerOpts) + err = svc.SetDesiredKubeObject(rootCAIssuer, rootCAIssuerName, rootCAIssuerOpts.KubeOptions...) + if err != nil { + err = fmt.Errorf("cannot create Root CA Issuer for OpenBao %w", err) + return err + } + + openBaoServerCertOpts := &common.TLSOptions{ + CertOptions: []common.CertOptions{ + withCertificateSecretName(openBaoServerCertSecretName), + withCertificateDuration(time.Duration(87600 * time.Hour)), + withCertificateRenewBefore(time.Duration(2400 * time.Hour)), + withCertificateIssuerRef(rootCAIssuerName), + withCertificateDNSName(serviceName + "." + ns + ".svc.cluster.local"), + withCertificateDNSName(serviceName + "." + ns + ".svc"), + withCertificateUsages([]cmv1.KeyUsage{"server auth", "client auth"}), + }, + KubeOptions: []runtime.KubeObjectOption{ + runtime.KubeOptionAddConnectionDetails(ns, + xkube.ConnectionDetail{ + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Secret", + Namespace: ns, + Name: openBaoServerCertSecretName, + FieldPath: "data[ca.crt]", + }, + ToConnectionSecretKey: "ca.crt", + }, + xkube.ConnectionDetail{ + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Secret", + Namespace: ns, + Name: openBaoServerCertSecretName, + FieldPath: "data[tls.crt]", + }, + ToConnectionSecretKey: "tls.crt", + }, + xkube.ConnectionDetail{ + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Secret", + Namespace: ns, + Name: openBaoServerCertSecretName, + FieldPath: "data[tls.key]", + }, + ToConnectionSecretKey: "tls.key", + }, + ), + }, + } + openBaoServerCert := createCertificate(ns, openBaoServerCertName, openBaoServerCertOpts) + err = svc.SetDesiredKubeObject(openBaoServerCert, openBaoServerCertName, openBaoServerCertOpts.KubeOptions...) + if err != nil { + err = fmt.Errorf("cannot create Server Certificate for OpenBao %w", err) + return err + } + + return nil +} + +func withIssuerOfTypeCA(secretName string) common.IssuerOption { + return func(issuer *cmv1.Issuer) { + issuer.Spec.CA = &cmv1.CAIssuer{ + SecretName: secretName, + } + } +} + +func withIssuerOfTypeSelfSigned() common.IssuerOption { + return func(issuer *cmv1.Issuer) { + issuer.Spec.SelfSigned = &cmv1.SelfSignedIssuer{ + CRLDistributionPoints: []string{}, + } + } +} + +func withCertificateSecretName(secretName string) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.SecretName = secretName + } +} + +func withCertificateDNSName(dnsName string) common.CertOptions { + return func(cert *cmv1.Certificate) { + if cert.Spec.DNSNames == nil { + cert.Spec.DNSNames = []string{} + } + cert.Spec.DNSNames = append(cert.Spec.DNSNames, dnsName) + } +} + +func withCertificateIsCA(isCA bool) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.IsCA = isCA + } +} + +func withCertificateIssuerRef(issuerName string) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.IssuerRef = certmgrv1.ObjectReference{ + Name: issuerName, + Kind: "Issuer", + Group: "cert-manager.io", + } + } +} + +func withCertificateDuration(time time.Duration) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.Duration = &metav1.Duration{ + Duration: time, + } + } +} + +func withCertificateRenewBefore(time time.Duration) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.RenewBefore = &metav1.Duration{ + Duration: time, + } + } +} + +func withCertificateUsages(usages []cmv1.KeyUsage) common.CertOptions { + return func(cert *cmv1.Certificate) { + cert.Spec.Usages = usages + } +} + +func createIssuer(namespace string, issuerName string, opts *common.TLSOptions) *cmv1.Issuer { + resource := &cmv1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: issuerName, + Namespace: namespace, + }, + Spec: cmv1.IssuerSpec{ + IssuerConfig: cmv1.IssuerConfig{}, + }, + } + + if opts.IssuerOptions != nil { + for _, opt := range opts.IssuerOptions { + opt(resource) + } + } + + return resource +} + +func createCertificate(namespace string, certName string, opts *common.TLSOptions) *cmv1.Certificate { + resource := &cmv1.Certificate{ + ObjectMeta: metav1.ObjectMeta{ + Name: certName, + Namespace: namespace, + }, + Spec: cmv1.CertificateSpec{ + PrivateKey: &cmv1.CertificatePrivateKey{ + Algorithm: cmv1.RSAKeyAlgorithm, + Encoding: cmv1.PKCS1, + Size: 4096, + }, + CommonName: certName + "-ca", + Subject: &cmv1.X509Subject{ + Organizations: []string{ + "vshn-appcat-ca", + }, + }, + }, + } + + if opts.CertOptions != nil { + for _, opt := range opts.CertOptions { + opt(resource) + } + } + + return resource +} diff --git a/pkg/comp-functions/functions/vshnopenbao/tls_test.go b/pkg/comp-functions/functions/vshnopenbao/tls_test.go new file mode 100644 index 0000000000..b7ab3a6211 --- /dev/null +++ b/pkg/comp-functions/functions/vshnopenbao/tls_test.go @@ -0,0 +1,312 @@ +package vshnopenbao + +import ( + "context" + "testing" + "time" + + cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + xkube "github.com/vshn/appcat/v4/apis/kubernetes/v1alpha2" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/common" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/commontest" +) + +func TestEnableOpenBaoTLSSupport(t *testing.T) { + svc := commontest.LoadRuntimeFromFile(t, "vshnopenbao/deploy/01_default.yaml") + + comp := &vshnv1.VSHNOpenBao{} + err := svc.GetObservedComposite(comp) + assert.NoError(t, err) + + ctx := context.TODO() + + err = enableOpenBaoTLSSupport(ctx, comp, svc) + assert.NoError(t, err) + + serviceName := comp.GetName() + ns := comp.GetInstanceNamespace() + + // Test self-signed issuer + selfSignedIssuer := &cmv1.Issuer{} + err = svc.GetDesiredKubeObject(selfSignedIssuer, serviceName+"-selfsigned-issuer") + assert.NoError(t, err) + assert.NotNil(t, selfSignedIssuer.Spec.SelfSigned) + assert.Equal(t, ns, selfSignedIssuer.Namespace) + + // Test root CA certificate + rootCA := &cmv1.Certificate{} + err = svc.GetDesiredKubeObject(rootCA, serviceName+"-ca") + assert.NoError(t, err) + assert.Equal(t, serviceName+"-ca-tls", rootCA.Spec.SecretName) + assert.True(t, rootCA.Spec.IsCA) + assert.Equal(t, serviceName+"-selfsigned-issuer", rootCA.Spec.IssuerRef.Name) + assert.Equal(t, "Issuer", rootCA.Spec.IssuerRef.Kind) + assert.Equal(t, time.Duration(87600*time.Hour), rootCA.Spec.Duration.Duration) + assert.Equal(t, time.Duration(2400*time.Hour), rootCA.Spec.RenewBefore.Duration) + + // Test root CA issuer + rootCAIssuer := &cmv1.Issuer{} + err = svc.GetDesiredKubeObject(rootCAIssuer, serviceName+"-ca-issuer") + assert.NoError(t, err) + assert.NotNil(t, rootCAIssuer.Spec.CA) + assert.Equal(t, serviceName+"-ca-tls", rootCAIssuer.Spec.CA.SecretName) + + // Test OpenBao server certificate + serverCert := &cmv1.Certificate{} + err = svc.GetDesiredKubeObject(serverCert, serviceName+"-server") + assert.NoError(t, err) + assert.Equal(t, serviceName+"-server-tls", serverCert.Spec.SecretName) + assert.Equal(t, serviceName+"-ca-issuer", serverCert.Spec.IssuerRef.Name) + assert.Contains(t, serverCert.Spec.DNSNames, serviceName+"."+ns+".svc.cluster.local") + assert.Contains(t, serverCert.Spec.DNSNames, serviceName+"."+ns+".svc") + assert.Contains(t, serverCert.Spec.Usages, cmv1.KeyUsage("server auth")) + assert.Contains(t, serverCert.Spec.Usages, cmv1.KeyUsage("client auth")) + + // Test connection details + obj := &xkube.Object{} + err = svc.GetDesiredComposedResourceByName(obj, serviceName+"-server") + assert.NoError(t, err) + require.NotNil(t, obj.Spec.ConnectionDetails) + assert.Len(t, obj.Spec.ConnectionDetails, 3) + + // Verify ca.crt connection detail + caCrtDetail := findConnectionDetail(obj.Spec.ConnectionDetails, "ca.crt") + assert.NotNil(t, caCrtDetail) + assert.Equal(t, serviceName+"-server-tls", caCrtDetail.ObjectReference.Name) + assert.Equal(t, "data[ca.crt]", caCrtDetail.ObjectReference.FieldPath) + + // Verify tls.crt connection detail + tlsCrtDetail := findConnectionDetail(obj.Spec.ConnectionDetails, "tls.crt") + assert.NotNil(t, tlsCrtDetail) + assert.Equal(t, serviceName+"-server-tls", tlsCrtDetail.ObjectReference.Name) + assert.Equal(t, "data[tls.crt]", tlsCrtDetail.ObjectReference.FieldPath) + + // Verify tls.key connection detail + tlsKeyDetail := findConnectionDetail(obj.Spec.ConnectionDetails, "tls.key") + assert.NotNil(t, tlsKeyDetail) + assert.Equal(t, serviceName+"-server-tls", tlsKeyDetail.ObjectReference.Name) + assert.Equal(t, "data[tls.key]", tlsKeyDetail.ObjectReference.FieldPath) +} + +func TestCreateIssuer(t *testing.T) { + svc := commontest.LoadRuntimeFromFile(t, "vshnopenbao/deploy/01_default.yaml") + + comp := &vshnv1.VSHNOpenBao{} + err := svc.GetObservedComposite(comp) + assert.NoError(t, err) + + ns := comp.GetInstanceNamespace() + + tests := []struct { + name string + issuerName string + setupOpts func() *common.TLSOptions + validateFunc func(*testing.T, *cmv1.Issuer) + }{ + { + name: "self-signed issuer", + issuerName: "test-selfsigned", + setupOpts: func() *common.TLSOptions { + return &common.TLSOptions{ + IssuerOptions: []common.IssuerOption{ + withIssuerOfTypeSelfSigned(), + }, + } + }, + validateFunc: func(t *testing.T, issuer *cmv1.Issuer) { + assert.NotNil(t, issuer.Spec.SelfSigned) + assert.Equal(t, []string{}, issuer.Spec.SelfSigned.CRLDistributionPoints) + }, + }, + { + name: "CA issuer", + issuerName: "test-ca", + setupOpts: func() *common.TLSOptions { + return &common.TLSOptions{ + IssuerOptions: []common.IssuerOption{ + withIssuerOfTypeCA("test-secret"), + }, + } + }, + validateFunc: func(t *testing.T, issuer *cmv1.Issuer) { + assert.NotNil(t, issuer.Spec.CA) + assert.Equal(t, "test-secret", issuer.Spec.CA.SecretName) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := tt.setupOpts() + issuer := createIssuer(ns, tt.issuerName, opts) + + assert.Equal(t, tt.issuerName, issuer.Name) + assert.Equal(t, ns, issuer.Namespace) + tt.validateFunc(t, issuer) + }) + } +} + +func TestCreateCertificate(t *testing.T) { + svc := commontest.LoadRuntimeFromFile(t, "vshnopenbao/deploy/01_default.yaml") + + comp := &vshnv1.VSHNOpenBao{} + err := svc.GetObservedComposite(comp) + assert.NoError(t, err) + + ns := comp.GetInstanceNamespace() + + tests := []struct { + name string + certName string + setupOpts func() *common.TLSOptions + validateFunc func(*testing.T, *cmv1.Certificate) + }{ + { + name: "basic certificate", + certName: "test-cert", + setupOpts: func() *common.TLSOptions { + return &common.TLSOptions{ + CertOptions: []common.CertOptions{ + withCertificateSecretName("test-secret"), + }, + } + }, + validateFunc: func(t *testing.T, cert *cmv1.Certificate) { + assert.Equal(t, "test-secret", cert.Spec.SecretName) + assert.Equal(t, cmv1.RSAKeyAlgorithm, cert.Spec.PrivateKey.Algorithm) + assert.Equal(t, cmv1.PKCS1, cert.Spec.PrivateKey.Encoding) + assert.Equal(t, 4096, cert.Spec.PrivateKey.Size) + }, + }, + { + name: "CA certificate", + certName: "test-ca", + setupOpts: func() *common.TLSOptions { + return &common.TLSOptions{ + CertOptions: []common.CertOptions{ + withCertificateSecretName("test-ca-secret"), + withCertificateIsCA(true), + withCertificateDuration(time.Duration(87600 * time.Hour)), + withCertificateRenewBefore(time.Duration(2400 * time.Hour)), + withCertificateIssuerRef("selfsigned-issuer"), + }, + } + }, + validateFunc: func(t *testing.T, cert *cmv1.Certificate) { + assert.Equal(t, "test-ca-secret", cert.Spec.SecretName) + assert.True(t, cert.Spec.IsCA) + assert.Equal(t, time.Duration(87600*time.Hour), cert.Spec.Duration.Duration) + assert.Equal(t, time.Duration(2400*time.Hour), cert.Spec.RenewBefore.Duration) + assert.Equal(t, "selfsigned-issuer", cert.Spec.IssuerRef.Name) + }, + }, + { + name: "server certificate with DNS names", + certName: "test-server", + setupOpts: func() *common.TLSOptions { + return &common.TLSOptions{ + CertOptions: []common.CertOptions{ + withCertificateSecretName("test-server-secret"), + withCertificateDNSName("service.namespace.svc.cluster.local"), + withCertificateDNSName("service.namespace.svc"), + withCertificateUsages([]cmv1.KeyUsage{"server auth", "client auth"}), + withCertificateIssuerRef("ca-issuer"), + }, + } + }, + validateFunc: func(t *testing.T, cert *cmv1.Certificate) { + assert.Equal(t, "test-server-secret", cert.Spec.SecretName) + assert.Contains(t, cert.Spec.DNSNames, "service.namespace.svc.cluster.local") + assert.Contains(t, cert.Spec.DNSNames, "service.namespace.svc") + assert.Contains(t, cert.Spec.Usages, cmv1.KeyUsage("server auth")) + assert.Contains(t, cert.Spec.Usages, cmv1.KeyUsage("client auth")) + assert.Equal(t, "ca-issuer", cert.Spec.IssuerRef.Name) + assert.Equal(t, "Issuer", cert.Spec.IssuerRef.Kind) + assert.Equal(t, "cert-manager.io", cert.Spec.IssuerRef.Group) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := tt.setupOpts() + cert := createCertificate(ns, tt.certName, opts) + + assert.Equal(t, tt.certName, cert.Name) + assert.Equal(t, ns, cert.Namespace) + assert.Equal(t, tt.certName+"-ca", cert.Spec.CommonName) + assert.Contains(t, cert.Spec.Subject.Organizations, "vshn-appcat-ca") + tt.validateFunc(t, cert) + }) + } +} + +func TestCertificateOptions(t *testing.T) { + cert := &cmv1.Certificate{ + Spec: cmv1.CertificateSpec{}, + } + + // Test withCertificateSecretName + withCertificateSecretName("test-secret")(cert) + assert.Equal(t, "test-secret", cert.Spec.SecretName) + + // Test withCertificateDNSName + withCertificateDNSName("test1.example.com")(cert) + withCertificateDNSName("test2.example.com")(cert) + assert.Len(t, cert.Spec.DNSNames, 2) + assert.Contains(t, cert.Spec.DNSNames, "test1.example.com") + assert.Contains(t, cert.Spec.DNSNames, "test2.example.com") + + // Test withCertificateIsCA + withCertificateIsCA(true)(cert) + assert.True(t, cert.Spec.IsCA) + + // Test withCertificateIssuerRef + withCertificateIssuerRef("test-issuer")(cert) + assert.Equal(t, "test-issuer", cert.Spec.IssuerRef.Name) + assert.Equal(t, "Issuer", cert.Spec.IssuerRef.Kind) + assert.Equal(t, "cert-manager.io", cert.Spec.IssuerRef.Group) + + // Test withCertificateDuration + duration := time.Duration(87600 * time.Hour) + withCertificateDuration(duration)(cert) + assert.Equal(t, duration, cert.Spec.Duration.Duration) + + // Test withCertificateRenewBefore + renewBefore := time.Duration(2400 * time.Hour) + withCertificateRenewBefore(renewBefore)(cert) + assert.Equal(t, renewBefore, cert.Spec.RenewBefore.Duration) + + // Test withCertificateUsages + usages := []cmv1.KeyUsage{"server auth", "client auth"} + withCertificateUsages(usages)(cert) + assert.Equal(t, usages, cert.Spec.Usages) +} + +func TestIssuerOptions(t *testing.T) { + // Test withIssuerOfTypeSelfSigned + issuer := &cmv1.Issuer{} + withIssuerOfTypeSelfSigned()(issuer) + assert.NotNil(t, issuer.Spec.SelfSigned) + assert.Equal(t, []string{}, issuer.Spec.SelfSigned.CRLDistributionPoints) + + // Test withIssuerOfTypeCA + issuer2 := &cmv1.Issuer{} + withIssuerOfTypeCA("ca-secret")(issuer2) + assert.NotNil(t, issuer2.Spec.CA) + assert.Equal(t, "ca-secret", issuer2.Spec.CA.SecretName) +} + +// Helper function to find connection detail by key +func findConnectionDetail(details []xkube.ConnectionDetail, key string) *xkube.ConnectionDetail { + for _, detail := range details { + if detail.ToConnectionSecretKey == key { + return &detail + } + } + return nil +} From 0a19479f54f0012897ce7edd79730d110f32dfc7 Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Fri, 9 Jan 2026 14:45:59 +0100 Subject: [PATCH 11/12] Make HCL config and Helm values to use TLS secrets --- .../functions/vshnopenbao/openbao_config.go | 76 ++++++++++--------- .../vshnopenbao/openbao_config_test.go | 23 +++--- .../functions/vshnopenbao/openbao_deploy.go | 51 ++++++++++++- .../functions/vshnopenbao/tls.go | 46 +++++------ .../functions/vshnopenbao/tls_test.go | 5 +- .../functions/vshnopenbao/utils.go | 38 +++++++--- 6 files changed, 149 insertions(+), 90 deletions(-) diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go index f477471a57..c61480bd83 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_config.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go @@ -55,26 +55,9 @@ func EmptyOption() OpenBaoConfigOption { func WithDefaultOptions() OpenBaoConfigOption { return func(config *OpenBaoConfig) { config.UI = true - config.LogLevel = "info" config.LogFormat = "json" - - config.APIAddr = "https://openbao:8200" - config.ClusterAddr = "https://openbao:8201" - config.PidFile = "/var/run/openbao.pid" - - config.Listeners = []ListenerBlock{ - { - Type: "tcp", - Address: "0.0.0.0:8200", - ClusterAddress: "0.0.0.0:8201", - TLSDisable: false, - TLSCertFile: "/etc/openbao/tls/cåert.pem", - TLSKeyFile: "/etc/openbao/tls/key.pem", - TLSMinVersion: "tls12", - }, - } } } @@ -84,39 +67,64 @@ func WithClusterName(clusterName string) OpenBaoConfigOption { } } -func writeHCLConfig(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { - configSecretResourceName := fmt.Sprintf("%s-config", comp.Name) +func WithAPIAddr(addr string) OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.APIAddr = addr + } +} + +func WithClusterAddr(addr string) OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.ClusterAddr = addr + } +} + +func WithTLSListener(listener ListenerBlock) OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.Listeners = append(config.Listeners, listener) + } +} + +func createHCLConfig(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { + serviceName := comp.GetName() + ns := comp.GetInstanceNamespace() + rsn := newOpenBaoResourceNames(serviceName) + + config := NewOpenBaoConfig( + WithDefaultOptions(), + WithAPIAddr(fmt.Sprintf("https://%s:8200", serviceName)), + WithClusterAddr(fmt.Sprintf("https://%s:8201", serviceName)), + WithTLSListener(ListenerBlock{ + Type: "tcp", + Address: "[::]:8200", + ClusterAddress: "[::]:8201", + TLSDisable: false, + TLSCertFile: fmt.Sprintf("%s/tls.crt", TlsCertsMountPath), + TLSKeyFile: fmt.Sprintf("%s/tls.key", TlsCertsMountPath), + }), + WithClusterName(serviceName), + ) - config := buildHclConfig(comp) hclBytes := EncodeHCL(config) secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: configSecretResourceName, - Namespace: comp.GetInstanceNamespace(), + Name: rsn.HclConfigSecretName, + Namespace: ns, }, Data: map[string][]byte{ - "config.hcl": hclBytes, + HclConfigFileName: hclBytes, }, } - err := svc.SetDesiredKubeObject(secret, configSecretResourceName) + err := svc.SetDesiredKubeObject(secret, rsn.HclConfigSecretName) if err != nil { - return fmt.Errorf("cannot add %s secret object: %w", configSecretResourceName, err) + return fmt.Errorf("cannot add %s secret object: %w", rsn.HclConfigSecretName, err) } return nil } -func buildHclConfig(comp *vshnv1.VSHNOpenBao) *OpenBaoConfig { - serviceName := comp.GetServiceName() - - return NewOpenBaoConfig( - WithDefaultOptions(), - WithClusterName(serviceName), - ) -} - // EncodeHCL encodes an OpenBaoConfig struct into HCL format bytes. // Returns the HCL-formatted byte slice. func EncodeHCL(config *OpenBaoConfig) []byte { diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go index 34bd8cfc09..8bf3c8c1a2 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go @@ -2,6 +2,7 @@ package vshnopenbao import ( "context" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -14,6 +15,8 @@ func TestBuildHclConfig(t *testing.T) { ctx := context.TODO() + rsn := newOpenBaoResourceNames(comp.GetName()) + // Deploy OpenBao and all related resources assert.Nil(t, DeployOpenBao(ctx, comp, svc)) @@ -21,21 +24,20 @@ func TestBuildHclConfig(t *testing.T) { assert.NoError(t, svc.GetObservedKubeObject(ns, comp.Name+"-ns")) // Test HCL config secret creation - configSecretName := comp.Name + "-config" + configSecretName := rsn.HclConfigSecretName secret := &corev1.Secret{} assert.NoError(t, svc.GetDesiredKubeObject(secret, configSecretName)) // Verify secret has the expected namespace assert.Equal(t, comp.GetInstanceNamespace(), secret.Namespace) - assert.Equal(t, configSecretName, secret.Name) // Verify secret contains the HCL config data - require.Contains(t, secret.Data, "config.hcl", "Secret should contain config.hcl key") - hclBytes := secret.Data["config.hcl"] + require.Contains(t, secret.Data, HclConfigFileName, "Secret should contain config.hcl key") + hclBytes := secret.Data[HclConfigFileName] require.NotEmpty(t, hclBytes, "HCL config should not be empty") // Parse and validate the HCL configuration using the DecodeHCL helper - parsedConfig, err := DecodeHCL(hclBytes, "config.hcl") + parsedConfig, err := DecodeHCL(hclBytes, HclConfigFileName) require.NoError(t, err, "HCL should decode properly") require.NotNil(t, parsedConfig, "Parsed config should not be nil") @@ -43,21 +45,20 @@ func TestBuildHclConfig(t *testing.T) { assert.True(t, parsedConfig.UI, "UI should be enabled") assert.Equal(t, "info", parsedConfig.LogLevel) assert.Equal(t, "json", parsedConfig.LogFormat) - assert.Equal(t, comp.GetServiceName(), parsedConfig.ClusterName, "ClusterName should match service name") - assert.Equal(t, "https://openbao:8200", parsedConfig.APIAddr) - assert.Equal(t, "https://openbao:8201", parsedConfig.ClusterAddr) + assert.Equal(t, comp.GetName(), parsedConfig.ClusterName, "ClusterName should match instance name") + assert.Equal(t, fmt.Sprintf("https://%s:8200", comp.GetName()), parsedConfig.APIAddr) + assert.Equal(t, fmt.Sprintf("https://%s:8201", comp.GetName()), parsedConfig.ClusterAddr) assert.Equal(t, "/var/run/openbao.pid", parsedConfig.PidFile) // Verify listener configuration require.Len(t, parsedConfig.Listeners, 1, "Should have exactly one listener") listener := parsedConfig.Listeners[0] assert.Equal(t, "tcp", listener.Type) - assert.Equal(t, "0.0.0.0:8200", listener.Address) - assert.Equal(t, "0.0.0.0:8201", listener.ClusterAddress) + assert.Equal(t, "[::]:8200", listener.Address) + assert.Equal(t, "[::]:8201", listener.ClusterAddress) assert.False(t, listener.TLSDisable, "TLS should be enabled") assert.NotEmpty(t, listener.TLSCertFile, "TLS cert file should be set") assert.NotEmpty(t, listener.TLSKeyFile, "TLS key file should be set") - assert.Equal(t, "tls12", listener.TLSMinVersion) } // TestEncodeDecodeHCL tests the EncodeHCL and DecodeHCL helper functions diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go index 71d478dcdb..a1dcf0ffcd 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go @@ -17,6 +17,10 @@ import ( k8sruntime "k8s.io/apimachinery/pkg/runtime" ) +const ( + serverCertificateSecretName = "tls-server-certificate" +) + // DeployConfigMap creates a ConfigMap with a hello world message and today's date func DeployOpenBao(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) *xfnproto.Result { @@ -33,12 +37,19 @@ func DeployOpenBao(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.S } svc.Log.Info("Creating HCL Configuration and saving it as a Secret") - err = writeHCLConfig(comp, svc) + err = createHCLConfig(comp, svc) if err != nil { err = fmt.Errorf("cannot create HCL Config: %w", err) return runtime.NewFatalResult(err) } + svc.Log.Info("Creating TLS certificates for OpenBao") + err = enableOpenBaoTLSSupport(comp, svc) + if err != nil { + err = fmt.Errorf("cannot create TLS certificates: %w", err) + return runtime.NewFatalResult(err) + } + svc.Log.Info("Creating helm release for OpenBao instance") err = createObjectHelmRelease(ctx, comp, svc) if err != nil { @@ -49,6 +60,8 @@ func DeployOpenBao(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.S return nil } func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { + serviceName := comp.GetName() + rsn := newOpenBaoResourceNames(serviceName) // The Components Appcat defines plans (how much CPU, memory etc) // The XR object (created by user) defines only the plan. @@ -68,7 +81,7 @@ func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc disk := cmp.Or(comp.Spec.Parameters.Size.Disk, resouces.Disk.String()) values := map[string]interface{}{ - "fullnameOverride": comp.GetName(), + "fullnameOverride": serviceName, "agent": map[string]any{ "enabled": false, }, @@ -76,6 +89,11 @@ func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc "enabled": false, }, "server": map[string]any{ + "ha": map[string]any{ + "enabled": true, + // The config is placed in the "openbao-storage-config" secret + "config": map[string]any{}, + }, "authDelegator": map[string]any{ "enabled": false, }, @@ -93,6 +111,35 @@ func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc "enabled": true, "size": disk, }, + "extraArgs": fmt.Sprintf("-config=%s/%s", HclConfigMountPath, HclConfigFileName), + "volumes": []map[string]any{ + { + "name": HclVolumeName, + "secret": map[string]any{ + "defaultMode": 420, + "secretName": rsn.HclConfigSecretName, + }, + }, + { + "name": TlsVolumeName, + "secret": map[string]any{ + "defaultMode": 420, + "secretName": rsn.ServerCertSecretName, + }, + }, + }, + "volumeMounts": []map[string]any{ + { + "mountPath": HclConfigMountPath, + "name": HclVolumeName, + "readOnly": true, + }, + { + "mountPath": TlsCertsMountPath, + "name": TlsVolumeName, + "readOnly": true, + }, + }, }, } diff --git a/pkg/comp-functions/functions/vshnopenbao/tls.go b/pkg/comp-functions/functions/vshnopenbao/tls.go index 30d12e382b..f86e8302fb 100644 --- a/pkg/comp-functions/functions/vshnopenbao/tls.go +++ b/pkg/comp-functions/functions/vshnopenbao/tls.go @@ -1,7 +1,6 @@ package vshnopenbao import ( - "context" "fmt" "time" @@ -15,26 +14,18 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { +func enableOpenBaoTLSSupport(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { serviceName := comp.GetName() ns := comp.GetInstanceNamespace() - - selfSignedIssuerName := serviceName + "-selfsigned-issuer" - - rootCAName := serviceName + "-ca" - rootCASecretName := serviceName + "-ca-tls" - rootCAIssuerName := serviceName + "-ca-issuer" - - openBaoServerCertName := serviceName + "-server" - openBaoServerCertSecretName := serviceName + "-server-tls" + rsn := newOpenBaoResourceNames(serviceName) selfSignedIssuerOpts := &common.TLSOptions{ IssuerOptions: []common.IssuerOption{ withIssuerOfTypeSelfSigned(), }, } - selfSignedIssuer := createIssuer(ns, selfSignedIssuerName, selfSignedIssuerOpts) - err := svc.SetDesiredKubeObject(selfSignedIssuer, selfSignedIssuerName, selfSignedIssuerOpts.KubeOptions...) + selfSignedIssuer := createIssuer(ns, rsn.SelfSignedIssuerName, selfSignedIssuerOpts) + err := svc.SetDesiredKubeObject(selfSignedIssuer, rsn.SelfSignedIssuerName, selfSignedIssuerOpts.KubeOptions...) if err != nil { err = fmt.Errorf("cannot create Self Signed Issuer for OpenBao %w", err) return err @@ -42,16 +33,16 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc rootCAOpts := &common.TLSOptions{ CertOptions: []common.CertOptions{ - withCertificateSecretName(rootCASecretName), + withCertificateSecretName(rsn.RootCASecretName), withCertificateDuration(time.Duration(87600 * time.Hour)), withCertificateRenewBefore(time.Duration(2400 * time.Hour)), - withCertificateIssuerRef(selfSignedIssuerName), + withCertificateIssuerRef(rsn.SelfSignedIssuerName), withCertificateIsCA(true), }, KubeOptions: []runtime.KubeObjectOption{}, } - rootCA := createCertificate(ns, rootCAName, rootCAOpts) - err = svc.SetDesiredKubeObject(rootCA, rootCAName, rootCAOpts.KubeOptions...) + rootCA := createCertificate(ns, rsn.RootCAName, rootCAOpts) + err = svc.SetDesiredKubeObject(rootCA, rsn.RootCAName, rootCAOpts.KubeOptions...) if err != nil { err = fmt.Errorf("cannot create Root CA with Self Signed Issuer for OpenBao %w", err) return err @@ -59,11 +50,11 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc rootCAIssuerOpts := &common.TLSOptions{ IssuerOptions: []common.IssuerOption{ - withIssuerOfTypeCA(rootCASecretName), + withIssuerOfTypeCA(rsn.RootCASecretName), }, } - rootCAIssuer := createIssuer(ns, rootCAIssuerName, rootCAIssuerOpts) - err = svc.SetDesiredKubeObject(rootCAIssuer, rootCAIssuerName, rootCAIssuerOpts.KubeOptions...) + rootCAIssuer := createIssuer(ns, rsn.RootCAIssuerName, rootCAIssuerOpts) + err = svc.SetDesiredKubeObject(rootCAIssuer, rsn.RootCAIssuerName, rootCAIssuerOpts.KubeOptions...) if err != nil { err = fmt.Errorf("cannot create Root CA Issuer for OpenBao %w", err) return err @@ -71,13 +62,14 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc openBaoServerCertOpts := &common.TLSOptions{ CertOptions: []common.CertOptions{ - withCertificateSecretName(openBaoServerCertSecretName), + withCertificateSecretName(rsn.ServerCertSecretName), withCertificateDuration(time.Duration(87600 * time.Hour)), withCertificateRenewBefore(time.Duration(2400 * time.Hour)), - withCertificateIssuerRef(rootCAIssuerName), + withCertificateIssuerRef(rsn.RootCAIssuerName), withCertificateDNSName(serviceName + "." + ns + ".svc.cluster.local"), withCertificateDNSName(serviceName + "." + ns + ".svc"), withCertificateUsages([]cmv1.KeyUsage{"server auth", "client auth"}), + withCertificateIsCA(false), }, KubeOptions: []runtime.KubeObjectOption{ runtime.KubeOptionAddConnectionDetails(ns, @@ -86,7 +78,7 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc APIVersion: "v1", Kind: "Secret", Namespace: ns, - Name: openBaoServerCertSecretName, + Name: rsn.ServerCertSecretName, FieldPath: "data[ca.crt]", }, ToConnectionSecretKey: "ca.crt", @@ -96,7 +88,7 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc APIVersion: "v1", Kind: "Secret", Namespace: ns, - Name: openBaoServerCertSecretName, + Name: rsn.ServerCertSecretName, FieldPath: "data[tls.crt]", }, ToConnectionSecretKey: "tls.crt", @@ -106,7 +98,7 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc APIVersion: "v1", Kind: "Secret", Namespace: ns, - Name: openBaoServerCertSecretName, + Name: rsn.ServerCertSecretName, FieldPath: "data[tls.key]", }, ToConnectionSecretKey: "tls.key", @@ -114,8 +106,8 @@ func enableOpenBaoTLSSupport(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc ), }, } - openBaoServerCert := createCertificate(ns, openBaoServerCertName, openBaoServerCertOpts) - err = svc.SetDesiredKubeObject(openBaoServerCert, openBaoServerCertName, openBaoServerCertOpts.KubeOptions...) + openBaoServerCert := createCertificate(ns, rsn.ServerCertName, openBaoServerCertOpts) + err = svc.SetDesiredKubeObject(openBaoServerCert, rsn.ServerCertName, openBaoServerCertOpts.KubeOptions...) if err != nil { err = fmt.Errorf("cannot create Server Certificate for OpenBao %w", err) return err diff --git a/pkg/comp-functions/functions/vshnopenbao/tls_test.go b/pkg/comp-functions/functions/vshnopenbao/tls_test.go index b7ab3a6211..33fdf4b0e7 100644 --- a/pkg/comp-functions/functions/vshnopenbao/tls_test.go +++ b/pkg/comp-functions/functions/vshnopenbao/tls_test.go @@ -1,7 +1,6 @@ package vshnopenbao import ( - "context" "testing" "time" @@ -21,9 +20,7 @@ func TestEnableOpenBaoTLSSupport(t *testing.T) { err := svc.GetObservedComposite(comp) assert.NoError(t, err) - ctx := context.TODO() - - err = enableOpenBaoTLSSupport(ctx, comp, svc) + err = enableOpenBaoTLSSupport(comp, svc) assert.NoError(t, err) serviceName := comp.GetName() diff --git a/pkg/comp-functions/functions/vshnopenbao/utils.go b/pkg/comp-functions/functions/vshnopenbao/utils.go index 8e7ed406aa..d24da69b77 100644 --- a/pkg/comp-functions/functions/vshnopenbao/utils.go +++ b/pkg/comp-functions/functions/vshnopenbao/utils.go @@ -1,19 +1,33 @@ package vshnopenbao -type OpenBaoTLSCertificate struct { - // CACert string - // Key string - // ClientCA string +const ( + HclConfigFileName = "config.hcl" + HclConfigMountPath = "/openbao/userconfig/openbao-hcl-config" + HclVolumeName = "userconfig-openbao-storage-config" + TlsCertsMountPath = "/openbao/userconfig/openbao-tls" + TlsVolumeName = "userconfig-openbao-tls-secret" +) - CACertFile string - KeyFile string - ClientCAFile string +type OpenBaoResourceNames struct { + ServiceName string + SelfSignedIssuerName string + RootCAIssuerName string + RootCAName string + ServerCertName string + RootCASecretName string + ServerCertSecretName string + HclConfigSecretName string } -func NewOpenBaoTLSCertificate() *OpenBaoTLSCertificate { - return &OpenBaoTLSCertificate{ - CACertFile: "/etc/ssl/certs/ca.crt", - KeyFile: "/etc/ssl/private/key.pem", - ClientCAFile: "/etc/ssl/certs/client-ca.crt", +func newOpenBaoResourceNames(serviceName string) *OpenBaoResourceNames { + return &OpenBaoResourceNames{ + ServiceName: serviceName, + SelfSignedIssuerName: serviceName + "-selfsigned-issuer", + RootCAIssuerName: serviceName + "-ca-issuer", + RootCAName: serviceName + "-ca", + RootCASecretName: serviceName + "-ca-tls", + ServerCertName: serviceName + "-server", + ServerCertSecretName: serviceName + "-server-tls", + HclConfigSecretName: serviceName + "-hcl-config", } } From cfa07350871e95b1da518b5148967e41b5c8cb0e Mon Sep 17 00:00:00 2001 From: Norbert Gruszka Date: Thu, 29 Jan 2026 21:41:34 +0100 Subject: [PATCH 12/12] Correct HCL config and fix open bao pods --- .../functions/vshnopenbao/openbao_config.go | 74 ++++++++++--------- .../vshnopenbao/openbao_config_test.go | 12 ++- .../functions/vshnopenbao/openbao_deploy.go | 7 +- .../functions/vshnopenbao/utils.go | 1 + 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go index c61480bd83..42725b35c5 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_config.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config.go @@ -13,33 +13,45 @@ import ( ) type OpenBaoConfig struct { - UI bool `hcl:"ui,optional"` - LogLevel string `hcl:"log_level,optional"` - LogFormat string `hcl:"log_format,optional"` - ClusterName string `hcl:"cluster_name,optional"` - APIAddr string `hcl:"api_addr,optional"` - ClusterAddr string `hcl:"cluster_addr,optional"` - PidFile string `hcl:"pid_file,optional"` - Listeners []ListenerBlock `hcl:"listener,block"` + UI bool `hcl:"ui,optional"` + LogLevel string `hcl:"log_level,optional"` + LogFormat string `hcl:"log_format,optional"` + ClusterName string `hcl:"cluster_name,optional"` + APIAddr string `hcl:"api_addr,optional"` + ClusterAddr string `hcl:"cluster_addr,optional"` + // PidFile string `hcl:"pid_file,optional"` + Listeners []ListenerBlock `hcl:"listener,block"` + Storage []StorageBlock `hcl:"storage,block"` } type OpenBaoConfigOption func(*OpenBaoConfig) type ListenerBlock struct { - Type string `hcl:"type,label"` - Address string `hcl:"address"` - ClusterAddress string `hcl:"cluster_address,optional"` - TLSDisable bool `hcl:"tls_disable,optional"` - TLSCertFile string `hcl:"tls_cert_file,optional"` - TLSKeyFile string `hcl:"tls_key_file,optional"` - TLSMinVersion string `hcl:"tls_min_version,optional"` - TLSMaxVersion string `hcl:"tls_max_version,optional"` - MaxRequestSize *int64 `hcl:"max_request_size,optional"` - MaxRequestDuration string `hcl:"max_request_duration,optional"` + Type string `hcl:"type,label"` + Address string `hcl:"address"` + ClusterAddress string `hcl:"cluster_address,optional"` + TLSDisable bool `hcl:"tls_disable"` + TLSCertFile string `hcl:"tls_cert_file,optional"` + TLSKeyFile string `hcl:"tls_key_file,optional"` +} + +type StorageBlock struct { + Type string `hcl:"type,label"` + Path string `hcl:"path"` + RetryJoin []RetryJoin `hcl:"retry_join,block"` +} + +type RetryJoin struct { + AutoJoin *string `hcl:"auto_join,optional"` } func NewOpenBaoConfig(opts ...OpenBaoConfigOption) *OpenBaoConfig { - config := &OpenBaoConfig{} + config := &OpenBaoConfig{ + UI: true, + LogLevel: "info", + LogFormat: "json", + // PidFile: "/var/run/openbao.pid", + } for _, opt := range opts { opt(config) @@ -48,19 +60,6 @@ func NewOpenBaoConfig(opts ...OpenBaoConfigOption) *OpenBaoConfig { return config } -func EmptyOption() OpenBaoConfigOption { - return func(config *OpenBaoConfig) {} -} - -func WithDefaultOptions() OpenBaoConfigOption { - return func(config *OpenBaoConfig) { - config.UI = true - config.LogLevel = "info" - config.LogFormat = "json" - config.PidFile = "/var/run/openbao.pid" - } -} - func WithClusterName(clusterName string) OpenBaoConfigOption { return func(config *OpenBaoConfig) { config.ClusterName = clusterName @@ -85,13 +84,18 @@ func WithTLSListener(listener ListenerBlock) OpenBaoConfigOption { } } +func WithStorage(storage StorageBlock) OpenBaoConfigOption { + return func(config *OpenBaoConfig) { + config.Storage = append(config.Storage, storage) + } +} + func createHCLConfig(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) error { serviceName := comp.GetName() ns := comp.GetInstanceNamespace() rsn := newOpenBaoResourceNames(serviceName) config := NewOpenBaoConfig( - WithDefaultOptions(), WithAPIAddr(fmt.Sprintf("https://%s:8200", serviceName)), WithClusterAddr(fmt.Sprintf("https://%s:8201", serviceName)), WithTLSListener(ListenerBlock{ @@ -103,6 +107,10 @@ func createHCLConfig(comp *vshnv1.VSHNOpenBao, svc *runtime.ServiceRuntime) erro TLSKeyFile: fmt.Sprintf("%s/tls.key", TlsCertsMountPath), }), WithClusterName(serviceName), + WithStorage(StorageBlock{ + Type: "raft", + Path: RaftDataPath, + }), ) hclBytes := EncodeHCL(config) diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go index 8bf3c8c1a2..330c7a676b 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_config_test.go @@ -48,7 +48,6 @@ func TestBuildHclConfig(t *testing.T) { assert.Equal(t, comp.GetName(), parsedConfig.ClusterName, "ClusterName should match instance name") assert.Equal(t, fmt.Sprintf("https://%s:8200", comp.GetName()), parsedConfig.APIAddr) assert.Equal(t, fmt.Sprintf("https://%s:8201", comp.GetName()), parsedConfig.ClusterAddr) - assert.Equal(t, "/var/run/openbao.pid", parsedConfig.PidFile) // Verify listener configuration require.Len(t, parsedConfig.Listeners, 1, "Should have exactly one listener") @@ -65,8 +64,15 @@ func TestBuildHclConfig(t *testing.T) { func TestEncodeDecodeHCL(t *testing.T) { // Create a test config originalConfig := NewOpenBaoConfig( - WithDefaultOptions(), WithClusterName("test-cluster"), + WithTLSListener(ListenerBlock{ + Type: "tcp", + Address: "[::]:8200", + ClusterAddress: "[::]:8201", + TLSDisable: false, + TLSCertFile: "/certs/tls.crt", + TLSKeyFile: "/certs/tls.key", + }), ) // Encode to HCL @@ -85,7 +91,6 @@ func TestEncodeDecodeHCL(t *testing.T) { assert.Equal(t, originalConfig.ClusterName, decodedConfig.ClusterName) assert.Equal(t, originalConfig.APIAddr, decodedConfig.APIAddr) assert.Equal(t, originalConfig.ClusterAddr, decodedConfig.ClusterAddr) - assert.Equal(t, originalConfig.PidFile, decodedConfig.PidFile) assert.Len(t, decodedConfig.Listeners, len(originalConfig.Listeners)) // Verify listener details @@ -98,7 +103,6 @@ func TestEncodeDecodeHCL(t *testing.T) { assert.Equal(t, origListener.TLSDisable, decListener.TLSDisable) assert.Equal(t, origListener.TLSCertFile, decListener.TLSCertFile) assert.Equal(t, origListener.TLSKeyFile, decListener.TLSKeyFile) - assert.Equal(t, origListener.TLSMinVersion, decListener.TLSMinVersion) } } diff --git a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go index a1dcf0ffcd..8d5e1a7225 100644 --- a/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go +++ b/pkg/comp-functions/functions/vshnopenbao/openbao_deploy.go @@ -91,8 +91,11 @@ func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNOpenBao, svc "server": map[string]any{ "ha": map[string]any{ "enabled": true, - // The config is placed in the "openbao-storage-config" secret - "config": map[string]any{}, + "config": "# Config provided via external file\n", + "raft": map[string]any{ + "enabled": true, + "config": "# Config provided via external file\n", + }, }, "authDelegator": map[string]any{ "enabled": false, diff --git a/pkg/comp-functions/functions/vshnopenbao/utils.go b/pkg/comp-functions/functions/vshnopenbao/utils.go index d24da69b77..91adf99612 100644 --- a/pkg/comp-functions/functions/vshnopenbao/utils.go +++ b/pkg/comp-functions/functions/vshnopenbao/utils.go @@ -6,6 +6,7 @@ const ( HclVolumeName = "userconfig-openbao-storage-config" TlsCertsMountPath = "/openbao/userconfig/openbao-tls" TlsVolumeName = "userconfig-openbao-tls-secret" + RaftDataPath = "/openbao/data" ) type OpenBaoResourceNames struct {