From 63c234ba87b272d42b69866c707f85c9e6291493 Mon Sep 17 00:00:00 2001 From: Andrii Chubatiuk Date: Fri, 29 May 2026 09:39:25 +0300 Subject: [PATCH] vmalertmanagerconfig: add incidentio_config file-based properties support --- .../v1beta1/vmalertmanagerconfig_types.go | 28 +++++++++++- config/crd/overlay/crd.descriptionless.yaml | 4 ++ config/crd/overlay/crd.yaml | 16 ++++++- docs/CHANGELOG.md | 1 + docs/api.md | 6 ++- .../operator/factory/vmalertmanager/config.go | 2 + .../factory/vmalertmanager/config_test.go | 43 +++++++++++++++++++ 7 files changed, 94 insertions(+), 6 deletions(-) diff --git a/api/operator/v1beta1/vmalertmanagerconfig_types.go b/api/operator/v1beta1/vmalertmanagerconfig_types.go index 9b477a9b2..41d18b4fd 100644 --- a/api/operator/v1beta1/vmalertmanagerconfig_types.go +++ b/api/operator/v1beta1/vmalertmanagerconfig_types.go @@ -189,7 +189,7 @@ func (cr *VMAlertmanagerConfig) ValidateArbitraryFSAccess() error { } } for j, rc := range r.IncidentioConfigs { - if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + if err := rc.validateArbitraryFSAccess(); err != nil { return fmt.Errorf("spec.receivers[%d].incidentio_configs[%d]: found prohibited properties: %w", i, j, err) } } @@ -1449,10 +1449,21 @@ type IncidentioConfig struct { SendResolved *bool `json:"send_resolved,omitempty" yaml:"send_resolved,omitempty"` // The URL to send the incident.io alert. This would typically be provided by the // incident.io team when setting up an alert source. + // Mutually exclusive with URLFile. + // +optional URL string `json:"url,omitempty" yaml:"url,omitempty"` - // AlertSourceToken is used to authenticate with incident.io + // URLFile defines the path to a file that holds the incident.io alert URL. + // Mutually exclusive with URL. + // +optional + URLFile string `json:"url_file,omitempty" yaml:"url_file,omitempty"` + // AlertSourceToken is used to authenticate with incident.io. + // Mutually exclusive with AlertSourceTokenFile. // +optional AlertSourceToken *corev1.SecretKeySelector `yaml:"alert_source_token,omitempty" json:"alert_source_token,omitempty"` + // AlertSourceTokenFile defines the path to a file that contains the alert source token. + // Mutually exclusive with AlertSourceToken. + // +optional + AlertSourceTokenFile string `json:"alert_source_token_file,omitempty" yaml:"alert_source_token_file,omitempty"` // MaxAlerts defines maximum number of alerts to be sent per incident.io message. // +optional MaxAlerts int `json:"max_alerts,omitempty" yaml:"max_alerts,omitempty"` @@ -1466,6 +1477,12 @@ type IncidentioConfig struct { } func (c *IncidentioConfig) validate() error { + if len(c.URL) != 0 && len(c.URLFile) != 0 { + return fmt.Errorf("url and url_file are mutually exclusive") + } + if c.AlertSourceToken != nil && len(c.AlertSourceTokenFile) != 0 { + return fmt.Errorf("alert_source_token and alert_source_token_file are mutually exclusive") + } if len(c.URL) != 0 { if _, err := url.Parse(c.URL); err != nil { return fmt.Errorf("incorrect url=%q: %w", c.URL, err) @@ -1477,6 +1494,13 @@ func (c *IncidentioConfig) validate() error { return nil } +func (c *IncidentioConfig) validateArbitraryFSAccess() error { + if c.AlertSourceTokenFile != "" { + return fmt.Errorf("alertSourceTokenFile is prohibited") + } + return c.HTTPConfig.validateArbitraryFSAccess() +} + // RocketchatConfig configures notifications via Rocketchat. // https://prometheus.io/docs/alerting/latest/configuration/#rocketchat_config // available from v0.55.0 operator version diff --git a/config/crd/overlay/crd.descriptionless.yaml b/config/crd/overlay/crd.descriptionless.yaml index f7517dfcf..f29799fad 100644 --- a/config/crd/overlay/crd.descriptionless.yaml +++ b/config/crd/overlay/crd.descriptionless.yaml @@ -7587,6 +7587,8 @@ spec: - key type: object x-kubernetes-map-type: atomic + alert_source_token_file: + type: string http_config: x-kubernetes-preserve-unknown-fields: true max_alerts: @@ -7597,6 +7599,8 @@ spec: type: string url: type: string + url_file: + type: string type: object type: array jira_configs: diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml index fac8d7b89..26f2e15d8 100644 --- a/config/crd/overlay/crd.yaml +++ b/config/crd/overlay/crd.yaml @@ -15002,8 +15002,9 @@ spec: and v0.29.0 alertmanager version properties: alert_source_token: - description: AlertSourceToken is used to authenticate - with incident.io + description: |- + AlertSourceToken is used to authenticate with incident.io. + Mutually exclusive with AlertSourceTokenFile. properties: key: description: The key of the secret to select from. Must @@ -15026,6 +15027,11 @@ spec: - key type: object x-kubernetes-map-type: atomic + alert_source_token_file: + description: |- + AlertSourceTokenFile defines the path to a file that contains the alert source token. + Mutually exclusive with AlertSourceToken. + type: string http_config: x-kubernetes-preserve-unknown-fields: true max_alerts: @@ -15044,6 +15050,12 @@ spec: description: |- The URL to send the incident.io alert. This would typically be provided by the incident.io team when setting up an alert source. + Mutually exclusive with URLFile. + type: string + url_file: + description: |- + URLFile defines the path to a file that holds the incident.io alert URL. + Mutually exclusive with URL. type: string type: object type: array diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ab0c11ecd..07c0a3039 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,7 @@ aliases: * Dependency: [vmoperator](https://docs.victoriametrics.com/operator/): Updated default versions for VM apps to [v1.144.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.144.0) version * FEATURE: [vmoperator](https://docs.victoriametrics.com/operator/): added `VM_COMMON_LABELS` and `VM_COMMON_ANNOTATIONS` environment variables to apply common labels/annotations to all Kubernetes resources managed by the operator. These cannot override labels/annotations already set by the operator or via `spec.managedMetadata`. This also ensures HTTPRoutes and PVCs include ManagedMetadata labels and annotations * FEATURE: [vmoperator](https://docs.victoriametrics.com/operator/): support enableServiceLinks property in all CRs. See [#2194](https://github.com/VictoriaMetrics/operator/pull/2194). +* FEATURE: [vmalertmanagerconfig](https://docs.victoriametrics.com/operator/resources/vmalertmanagerconfig/): add `url_file` and `alert_source_token_file` fields to `IncidentioConfig`, as file-based alternatives to `url` and `alert_source_token`. See [#2222](https://github.com/VictoriaMetrics/operator/issues/2222). * BUGFIX: [vmoperator](https://docs.victoriametrics.com/operator/): update status currentRevision and currentReplicas for StatefulSet with OnDelete update strategy. See [#1242](https://github.com/VictoriaMetrics/operator/issues/1242). diff --git a/docs/api.md b/docs/api.md index 78469794f..cd56d5ec3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2165,12 +2165,14 @@ Appears in: [Receiver](#receiver) | Field | Description | | --- | --- | -| alert_source_token#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
AlertSourceToken is used to authenticate with incident.io | +| alert_source_token#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
AlertSourceToken is used to authenticate with incident.io.
Mutually exclusive with AlertSourceTokenFile. | +| alert_source_token_file#
_string_ | _(Optional)_
AlertSourceTokenFile defines the path to a file that contains the alert source token.
Mutually exclusive with AlertSourceToken. | | http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
| | max_alerts#
_integer_ | _(Optional)_
MaxAlerts defines maximum number of alerts to be sent per incident.io message. | | send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | | timeout#
_string_ | _(Optional)_
Timeout is the maximum time allowed to invoke incident.io | -| url#
_string_ | _(Required)_
The URL to send the incident.io alert. This would typically be provided by the
incident.io team when setting up an alert source. | +| url#
_string_ | _(Optional)_
The URL to send the incident.io alert. This would typically be provided by the
incident.io team when setting up an alert source.
Mutually exclusive with URLFile. | +| url_file#
_string_ | _(Optional)_
URLFile defines the path to a file that holds the incident.io alert URL.
Mutually exclusive with URL. | #### InhibitRule diff --git a/internal/controller/operator/factory/vmalertmanager/config.go b/internal/controller/operator/factory/vmalertmanager/config.go index 04c231918..3e6fd0782 100644 --- a/internal/controller/operator/factory/vmalertmanager/config.go +++ b/internal/controller/operator/factory/vmalertmanager/config.go @@ -807,10 +807,12 @@ func buildIncidentio(rc vmv1beta1.IncidentioConfig, ns string, ac *build.AssetsC } r.set("alert_source_token", secret) } + r.set("alert_source_token_file", rc.AlertSourceTokenFile) if rc.SendResolved != nil { r.set("send_resolved", rc.SendResolved) } r.set("url", rc.URL) + r.set("url_file", rc.URLFile) r.set("timeout", rc.Timeout) r.set("max_alerts", rc.MaxAlerts) return r.items, nil diff --git a/internal/controller/operator/factory/vmalertmanager/config_test.go b/internal/controller/operator/factory/vmalertmanager/config_test.go index 62857c2f4..90aec95e3 100644 --- a/internal/controller/operator/factory/vmalertmanager/config_test.go +++ b/internal/controller/operator/factory/vmalertmanager/config_test.go @@ -1461,6 +1461,49 @@ templates: [] `, }) + // incidentio with file-based fields + f(opts{ + predefinedObjects: []runtime.Object{ + &vmv1beta1.VMAlertmanagerConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "incidentio-file", + Namespace: "default", + }, + Spec: vmv1beta1.VMAlertmanagerConfigSpec{ + Route: &vmv1beta1.Route{ + Receiver: "incidentio-file", + }, + Receivers: []vmv1beta1.Receiver{ + { + Name: "incidentio-file", + IncidentioConfigs: []vmv1beta1.IncidentioConfig{ + { + URLFile: "/etc/alertmanager/incidentio_url", + AlertSourceTokenFile: "/etc/alertmanager/incidentio_token", + }, + }, + }, + }, + }, + }, + }, + want: `route: + receiver: blackhole + routes: + - matchers: + - namespace = "default" + receiver: default-incidentio-file-incidentio-file + continue: true +receivers: +- name: blackhole +- name: default-incidentio-file-incidentio-file + incidentio_configs: + - alert_source_token_file: /etc/alertmanager/incidentio_token + url_file: /etc/alertmanager/incidentio_url +templates: [] +`, + }) + // msteamsv2 f(opts{ predefinedObjects: []runtime.Object{