diff --git a/Makefile b/Makefile index c0547bc39..0cc09ca94 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,7 @@ manifests: controller-gen api-docs: gen-crd-api-reference-docs $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/notification.md $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta3 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta3/notification.md + $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta4 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta4/notification.md $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1/notification.md # Run go mod tidy diff --git a/api/v1beta1/alert_types.go b/api/v1beta1/alert_types.go index 97bca9a99..5069da361 100644 --- a/api/v1beta1/alert_types.go +++ b/api/v1beta1/alert_types.go @@ -70,7 +70,7 @@ type AlertStatus struct { // +genclient:Namespaced // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:deprecatedversion:warning="v1beta1 Alert is deprecated, upgrade to v1beta3" +// +kubebuilder:deprecatedversion:warning="v1beta1 Alert is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" diff --git a/api/v1beta1/provider_types.go b/api/v1beta1/provider_types.go index 7cece20fb..07b63a826 100644 --- a/api/v1beta1/provider_types.go +++ b/api/v1beta1/provider_types.go @@ -113,7 +113,7 @@ type ProviderStatus struct { // +genclient:Namespaced // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:deprecatedversion:warning="v1beta1 Provider is deprecated, upgrade to v1beta3" +// +kubebuilder:deprecatedversion:warning="v1beta1 Provider is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" diff --git a/api/v1beta2/alert_types.go b/api/v1beta2/alert_types.go index f270837c3..a9847f117 100644 --- a/api/v1beta2/alert_types.go +++ b/api/v1beta2/alert_types.go @@ -91,7 +91,7 @@ type AlertStatus struct { // +genclient:Namespaced // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:deprecatedversion:warning="v1beta2 Alert is deprecated, upgrade to v1beta3" +// +kubebuilder:deprecatedversion:warning="v1beta2 Alert is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" diff --git a/api/v1beta2/provider_types.go b/api/v1beta2/provider_types.go index 10604b831..dea0177c2 100644 --- a/api/v1beta2/provider_types.go +++ b/api/v1beta2/provider_types.go @@ -134,7 +134,7 @@ type ProviderStatus struct { // +genclient:Namespaced // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:deprecatedversion:warning="v1beta2 Provider is deprecated, upgrade to v1beta3" +// +kubebuilder:deprecatedversion:warning="v1beta2 Provider is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" diff --git a/api/v1beta3/alert_types.go b/api/v1beta3/alert_types.go index b3d4b691f..d638fd71d 100644 --- a/api/v1beta3/alert_types.go +++ b/api/v1beta3/alert_types.go @@ -76,8 +76,9 @@ type AlertSpec struct { // +genclient // +genclient:Namespaced -// +kubebuilder:storageversion // +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:deprecatedversion:warning="v1beta3 Alert is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // Alert is the Schema for the alerts API diff --git a/api/v1beta3/provider_types.go b/api/v1beta3/provider_types.go index 23e4acead..b890c3082 100644 --- a/api/v1beta3/provider_types.go +++ b/api/v1beta3/provider_types.go @@ -123,8 +123,9 @@ type ProviderSpec struct { // +genclient // +genclient:Namespaced -// +kubebuilder:storageversion // +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:deprecatedversion:warning="v1beta3 Provider is deprecated, upgrade to v1beta4" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // Provider is the Schema for the providers API diff --git a/api/v1beta4/alert_types.go b/api/v1beta4/alert_types.go new file mode 100644 index 000000000..c04cd433e --- /dev/null +++ b/api/v1beta4/alert_types.go @@ -0,0 +1,108 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta4 + +import ( + "github.com/fluxcd/pkg/apis/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v1 "github.com/fluxcd/notification-controller/api/v1" +) + +const ( + AlertKind string = "Alert" +) + +// AlertSpec defines an alerting rule for events involving a list of objects. +type AlertSpec struct { + // ProviderRef specifies which Provider this Alert should use. + // +required + ProviderRef meta.NamespacedObjectReference `json:"providerRef"` + + // EventSeverity specifies how to filter events based on severity. + // If set to 'info' no events will be filtered. + // +kubebuilder:validation:Enum=info;error + // +kubebuilder:default:=info + // +optional + EventSeverity string `json:"eventSeverity,omitempty"` + + // EventSources specifies how to filter events based + // on the involved object kind, name and namespace. + // +required + EventSources []v1.CrossNamespaceObjectReference `json:"eventSources"` + + // InclusionList specifies a list of Golang regular expressions + // to be used for including messages. + // +optional + InclusionList []string `json:"inclusionList,omitempty"` + + // EventMetadata is an optional field for adding metadata to events dispatched by the + // controller. This can be used for enhancing the context of the event. If a field + // would override one already present on the original event as generated by the emitter, + // then the override doesn't happen, i.e. the original value is preserved, and an info + // log is printed. + // +optional + EventMetadata map[string]string `json:"eventMetadata,omitempty"` + + // ExclusionList specifies a list of Golang regular expressions + // to be used for excluding messages. + // +optional + ExclusionList []string `json:"exclusionList,omitempty"` + + // Summary holds a short description of the impact and affected cluster. + // +kubebuilder:validation:MaxLength:=255 + // +optional + Summary string `json:"summary,omitempty"` + + // Suspend tells the controller to suspend subsequent + // events handling for this Alert. + // +optional + Suspend bool `json:"suspend,omitempty"` + + // Channel specifies the destination channel where events should be posted. + // This will override any default channel that might be set in the provider + // +kubebuilder:validation:MaxLength:=2048 + // +optional + Channel string `json:"channel,omitempty"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:storageversion +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" + +// Alert is the Schema for the alerts API +type Alert struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AlertSpec `json:"spec,omitempty"` +} + +//+kubebuilder:object:root=true + +// AlertList contains a list of Alert +type AlertList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Alert `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Alert{}, &AlertList{}) +} diff --git a/api/v1beta4/doc.go b/api/v1beta4/doc.go new file mode 100644 index 000000000..cb889c2b8 --- /dev/null +++ b/api/v1beta4/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta4 contains API Schema definitions for the notification v1beta4 API group. +// +kubebuilder:object:generate=true +// +groupName=notification.toolkit.fluxcd.io +package v1beta4 diff --git a/api/v1beta4/groupversion_info.go b/api/v1beta4/groupversion_info.go new file mode 100644 index 000000000..69c672b80 --- /dev/null +++ b/api/v1beta4/groupversion_info.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta4 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "notification.toolkit.fluxcd.io", Version: "v1beta4"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1beta4/provider_types.go b/api/v1beta4/provider_types.go new file mode 100644 index 000000000..f029b1b48 --- /dev/null +++ b/api/v1beta4/provider_types.go @@ -0,0 +1,163 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta4 + +import ( + "time" + + "github.com/fluxcd/pkg/apis/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + ProviderKind string = "Provider" + GenericProvider string = "generic" + GenericHMACProvider string = "generic-hmac" + SlackProvider string = "slack" + GrafanaProvider string = "grafana" + DiscordProvider string = "discord" + MSTeamsProvider string = "msteams" + RocketProvider string = "rocket" + GitHubDispatchProvider string = "githubdispatch" + GitHubProvider string = "github" + GitLabProvider string = "gitlab" + GiteaProvider string = "gitea" + BitbucketServerProvider string = "bitbucketserver" + BitbucketProvider string = "bitbucket" + AzureDevOpsProvider string = "azuredevops" + GoogleChatProvider string = "googlechat" + GooglePubSubProvider string = "googlepubsub" + WebexProvider string = "webex" + SentryProvider string = "sentry" + AzureEventHubProvider string = "azureeventhub" + TelegramProvider string = "telegram" + LarkProvider string = "lark" + Matrix string = "matrix" + OpsgenieProvider string = "opsgenie" + AlertManagerProvider string = "alertmanager" + PagerDutyProvider string = "pagerduty" + DataDogProvider string = "datadog" + NATSProvider string = "nats" +) + +// ProviderSpec defines the desired state of the Provider. +type ProviderSpec struct { + // Type specifies which Provider implementation to use. + // +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;generic-hmac;github;gitlab;gitea;bitbucketserver;bitbucket;azuredevops;googlechat;googlepubsub;webex;sentry;azureeventhub;telegram;lark;matrix;opsgenie;alertmanager;grafana;githubdispatch;pagerduty;datadog;nats + // +required + Type string `json:"type"` + + // Interval at which to reconcile the Provider with its Secret references. + // Deprecated and not used in v1beta4. + // + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + // +optional + // +deprecated + Interval *metav1.Duration `json:"interval,omitempty"` + + // Channel specifies the destination channel where events should be posted. + // +kubebuilder:validation:MaxLength:=2048 + // +optional + Channel string `json:"channel,omitempty"` + + // Username specifies the name under which events are posted. + // +kubebuilder:validation:MaxLength:=2048 + // +optional + Username string `json:"username,omitempty"` + + // Address specifies the endpoint, in a generic sense, to where alerts are sent. + // What kind of endpoint depends on the specific Provider type being used. + // For the generic Provider, for example, this is an HTTP/S address. + // For other Provider types this could be a project ID or a namespace. + // +kubebuilder:validation:MaxLength:=2048 + // +kubebuilder:validation:Optional + // +optional + Address string `json:"address,omitempty"` + + // Timeout for sending alerts to the Provider. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" + // +optional + Timeout *metav1.Duration `json:"timeout,omitempty"` + + // Proxy the HTTP/S address of the proxy server. + // +kubebuilder:validation:Pattern="^(http|https)://.*$" + // +kubebuilder:validation:MaxLength:=2048 + // +kubebuilder:validation:Optional + // +optional + Proxy string `json:"proxy,omitempty"` + + // SecretRef specifies the Secret containing the authentication + // credentials for this Provider. + // +optional + SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"` + + // CertSecretRef specifies the Secret containing + // a PEM-encoded CA certificate (in the `ca.crt` key). + // +optional + // + // Note: Support for the `caFile` key has + // been deprecated. + CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"` + + // Suspend tells the controller to suspend subsequent + // events handling for this Provider. + // +optional + Suspend bool `json:"suspend,omitempty"` + + //CrossNamespace allows this provider to be made available to Alerts in other namespaces + // +optional + CrossNamespace bool `json:"crossNamespace,omitempty"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:storageversion +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" + +// Provider is the Schema for the providers API +type Provider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ProviderSpec `json:"spec,omitempty"` +} + +//+kubebuilder:object:root=true + +// ProviderList contains a list of Provider +type ProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Provider `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Provider{}, &ProviderList{}) +} + +// GetTimeout returns the timeout value with a default of 15s for this Provider. +func (in *Provider) GetTimeout() time.Duration { + duration := 15 * time.Second + if in.Spec.Timeout != nil { + duration = in.Spec.Timeout.Duration + } + + return duration +} diff --git a/api/v1beta4/zz_generated.deepcopy.go b/api/v1beta4/zz_generated.deepcopy.go new file mode 100644 index 000000000..f78ceda42 --- /dev/null +++ b/api/v1beta4/zz_generated.deepcopy.go @@ -0,0 +1,220 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta4 + +import ( + "github.com/fluxcd/notification-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Alert) DeepCopyInto(out *Alert) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Alert. +func (in *Alert) DeepCopy() *Alert { + if in == nil { + return nil + } + out := new(Alert) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Alert) 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 *AlertList) DeepCopyInto(out *AlertList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Alert, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlertList. +func (in *AlertList) DeepCopy() *AlertList { + if in == nil { + return nil + } + out := new(AlertList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AlertList) 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 *AlertSpec) DeepCopyInto(out *AlertSpec) { + *out = *in + out.ProviderRef = in.ProviderRef + if in.EventSources != nil { + in, out := &in.EventSources, &out.EventSources + *out = make([]v1.CrossNamespaceObjectReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.InclusionList != nil { + in, out := &in.InclusionList, &out.InclusionList + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.EventMetadata != nil { + in, out := &in.EventMetadata, &out.EventMetadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ExclusionList != nil { + in, out := &in.ExclusionList, &out.ExclusionList + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlertSpec. +func (in *AlertSpec) DeepCopy() *AlertSpec { + if in == nil { + return nil + } + out := new(AlertSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Provider) DeepCopyInto(out *Provider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Provider. +func (in *Provider) DeepCopy() *Provider { + if in == nil { + return nil + } + out := new(Provider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Provider) 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 *ProviderList) DeepCopyInto(out *ProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Provider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderList. +func (in *ProviderList) DeepCopy() *ProviderList { + if in == nil { + return nil + } + out := new(ProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProviderList) 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 *ProviderSpec) DeepCopyInto(out *ProviderSpec) { + *out = *in + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(metav1.Duration) + **out = **in + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(metav1.Duration) + **out = **in + } + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(meta.LocalObjectReference) + **out = **in + } + if in.CertSecretRef != nil { + in, out := &in.CertSecretRef, &out.CertSecretRef + *out = new(meta.LocalObjectReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderSpec. +func (in *ProviderSpec) DeepCopy() *ProviderSpec { + if in == nil { + return nil + } + out := new(ProviderSpec) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/notification.toolkit.fluxcd.io_alerts.yaml b/config/crd/bases/notification.toolkit.fluxcd.io_alerts.yaml index 9f52092f7..de6ee1633 100644 --- a/config/crd/bases/notification.toolkit.fluxcd.io_alerts.yaml +++ b/config/crd/bases/notification.toolkit.fluxcd.io_alerts.yaml @@ -438,6 +438,8 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date + deprecated: true + deprecationWarning: v1beta3 Alert is deprecated, upgrade to v1beta4 name: v1beta3 schema: openAPIV3Schema: @@ -563,5 +565,147 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta4 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + 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: AlertSpec defines an alerting rule for events involving a + list of objects. + properties: + channel: + description: Channel specifies the destination channel where events + should be posted. This will override any default channel that might + be set in the provider + maxLength: 2048 + type: string + eventMetadata: + additionalProperties: + type: string + description: EventMetadata is an optional field for adding metadata + to events dispatched by the controller. This can be used for enhancing + the context of the event. If a field would override one already + present on the original event as generated by the emitter, then + the override doesn't happen, i.e. the original value is preserved, + and an info log is printed. + type: object + eventSeverity: + default: info + description: EventSeverity specifies how to filter events based on + severity. If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: EventSources specifies how to filter events based on + the involved object kind, name and namespace. + items: + description: CrossNamespaceObjectReference contains enough information + to let you locate the typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + type: string + matchLabels: + additionalProperties: + type: string + description: MatchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. MatchLabels requires the name to be set to `*`. + type: object + name: + description: Name of the referent If multiple resources are + targeted `*` may be set. + maxLength: 53 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 53 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: ExclusionList specifies a list of Golang regular expressions + to be used for excluding messages. + items: + type: string + type: array + inclusionList: + description: InclusionList specifies a list of Golang regular expressions + to be used for including messages. + items: + type: string + type: array + providerRef: + description: ProviderRef specifies which Provider this Alert should + use. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + summary: + description: Summary holds a short description of the impact and affected + cluster. + maxLength: 255 + type: string + suspend: + description: Suspend tells the controller to suspend subsequent events + handling for this Alert. + type: boolean + required: + - eventSources + - providerRef + type: object + type: object + served: true storage: true subresources: {} diff --git a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml index 5b7645ced..64707df42 100644 --- a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml +++ b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml @@ -413,6 +413,8 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date + deprecated: true + deprecationWarning: v1beta3 Provider is deprecated, upgrade to v1beta4 name: v1beta3 schema: openAPIV3Schema: @@ -525,5 +527,128 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta4 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API + 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: ProviderSpec defines the desired state of the Provider. + properties: + address: + description: Address specifies the endpoint, in a generic sense, to + where alerts are sent. What kind of endpoint depends on the specific + Provider type being used. For the generic Provider, for example, + this is an HTTP/S address. For other Provider types this could be + a project ID or a namespace. + maxLength: 2048 + type: string + certSecretRef: + description: "CertSecretRef specifies the Secret containing a PEM-encoded + CA certificate (in the `ca.crt` key). \n Note: Support for the `caFile` + key has been deprecated." + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Channel specifies the destination channel where events + should be posted. + maxLength: 2048 + type: string + crossNamespace: + description: CrossNamespace allows this provider to be made available + to Alerts in other namespaces + type: boolean + interval: + description: Interval at which to reconcile the Provider with its + Secret references. Deprecated and not used in v1beta4. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + proxy: + description: Proxy the HTTP/S address of the proxy server. + maxLength: 2048 + pattern: ^(http|https)://.*$ + type: string + secretRef: + description: SecretRef specifies the Secret containing the authentication + credentials for this Provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: Suspend tells the controller to suspend subsequent events + handling for this Provider. + type: boolean + timeout: + description: Timeout for sending alerts to the Provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type specifies which Provider implementation to use. + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - gitea + - bitbucketserver + - bitbucket + - azuredevops + - googlechat + - googlepubsub + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + - pagerduty + - datadog + - nats + type: string + username: + description: Username specifies the name under which events are posted. + maxLength: 2048 + type: string + required: + - type + type: object + type: object + served: true storage: true subresources: {} diff --git a/docs/api/v1beta4/notification.md b/docs/api/v1beta4/notification.md new file mode 100644 index 000000000..9ad871a27 --- /dev/null +++ b/docs/api/v1beta4/notification.md @@ -0,0 +1,724 @@ +

Notification API reference v1beta4

+

Packages:

+ +

notification.toolkit.fluxcd.io/v1beta4

+

Package v1beta4 contains API Schema definitions for the notification v1beta4 API group.

+Resource Types: + +

Alert +

+

Alert is the Schema for the alerts API

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+notification.toolkit.fluxcd.io/v1beta4 +
+kind
+string +
+Alert +
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +AlertSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+providerRef
+ + +github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference + + +
+

ProviderRef specifies which Provider this Alert should use.

+
+eventSeverity
+ +string + +
+(Optional) +

EventSeverity specifies how to filter events based on severity. +If set to ‘info’ no events will be filtered.

+
+eventSources
+ + +[]github.com/fluxcd/notification-controller/api/v1.CrossNamespaceObjectReference + + +
+

EventSources specifies how to filter events based +on the involved object kind, name and namespace.

+
+inclusionList
+ +[]string + +
+(Optional) +

InclusionList specifies a list of Golang regular expressions +to be used for including messages.

+
+eventMetadata
+ +map[string]string + +
+(Optional) +

EventMetadata is an optional field for adding metadata to events dispatched by the +controller. This can be used for enhancing the context of the event. If a field +would override one already present on the original event as generated by the emitter, +then the override doesn’t happen, i.e. the original value is preserved, and an info +log is printed.

+
+exclusionList
+ +[]string + +
+(Optional) +

ExclusionList specifies a list of Golang regular expressions +to be used for excluding messages.

+
+summary
+ +string + +
+(Optional) +

Summary holds a short description of the impact and affected cluster.

+
+suspend
+ +bool + +
+(Optional) +

Suspend tells the controller to suspend subsequent +events handling for this Alert.

+
+channel
+ +string + +
+(Optional) +

Channel specifies the destination channel where events should be posted. +This will override any default channel that might be set in the provider

+
+
+
+
+

Provider +

+

Provider is the Schema for the providers API

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+notification.toolkit.fluxcd.io/v1beta4 +
+kind
+string +
+Provider +
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ProviderSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+type
+ +string + +
+

Type specifies which Provider implementation to use.

+
+interval
+ + +Kubernetes meta/v1.Duration + + +
+(Optional) +

Interval at which to reconcile the Provider with its Secret references. +Deprecated and not used in v1beta4.

+
+channel
+ +string + +
+(Optional) +

Channel specifies the destination channel where events should be posted.

+
+username
+ +string + +
+(Optional) +

Username specifies the name under which events are posted.

+
+address
+ +string + +
+(Optional) +

Address specifies the endpoint, in a generic sense, to where alerts are sent. +What kind of endpoint depends on the specific Provider type being used. +For the generic Provider, for example, this is an HTTP/S address. +For other Provider types this could be a project ID or a namespace.

+
+timeout
+ + +Kubernetes meta/v1.Duration + + +
+(Optional) +

Timeout for sending alerts to the Provider.

+
+proxy
+ +string + +
+(Optional) +

Proxy the HTTP/S address of the proxy server.

+
+secretRef
+ + +github.com/fluxcd/pkg/apis/meta.LocalObjectReference + + +
+(Optional) +

SecretRef specifies the Secret containing the authentication +credentials for this Provider.

+
+certSecretRef
+ + +github.com/fluxcd/pkg/apis/meta.LocalObjectReference + + +
+(Optional) +

CertSecretRef specifies the Secret containing +a PEM-encoded CA certificate (in the ca.crt key).

+

Note: Support for the caFile key has +been deprecated.

+
+suspend
+ +bool + +
+(Optional) +

Suspend tells the controller to suspend subsequent +events handling for this Provider.

+
+crossNamespace
+ +bool + +
+(Optional) +

CrossNamespace allows this provider to be made available to Alerts in other namespaces

+
+
+
+
+

AlertSpec +

+

+(Appears on: +Alert) +

+

AlertSpec defines an alerting rule for events involving a list of objects.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+providerRef
+ + +github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference + + +
+

ProviderRef specifies which Provider this Alert should use.

+
+eventSeverity
+ +string + +
+(Optional) +

EventSeverity specifies how to filter events based on severity. +If set to ‘info’ no events will be filtered.

+
+eventSources
+ + +[]github.com/fluxcd/notification-controller/api/v1.CrossNamespaceObjectReference + + +
+

EventSources specifies how to filter events based +on the involved object kind, name and namespace.

+
+inclusionList
+ +[]string + +
+(Optional) +

InclusionList specifies a list of Golang regular expressions +to be used for including messages.

+
+eventMetadata
+ +map[string]string + +
+(Optional) +

EventMetadata is an optional field for adding metadata to events dispatched by the +controller. This can be used for enhancing the context of the event. If a field +would override one already present on the original event as generated by the emitter, +then the override doesn’t happen, i.e. the original value is preserved, and an info +log is printed.

+
+exclusionList
+ +[]string + +
+(Optional) +

ExclusionList specifies a list of Golang regular expressions +to be used for excluding messages.

+
+summary
+ +string + +
+(Optional) +

Summary holds a short description of the impact and affected cluster.

+
+suspend
+ +bool + +
+(Optional) +

Suspend tells the controller to suspend subsequent +events handling for this Alert.

+
+channel
+ +string + +
+(Optional) +

Channel specifies the destination channel where events should be posted. +This will override any default channel that might be set in the provider

+
+
+
+

ProviderSpec +

+

+(Appears on: +Provider) +

+

ProviderSpec defines the desired state of the Provider.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type
+ +string + +
+

Type specifies which Provider implementation to use.

+
+interval
+ + +Kubernetes meta/v1.Duration + + +
+(Optional) +

Interval at which to reconcile the Provider with its Secret references. +Deprecated and not used in v1beta4.

+
+channel
+ +string + +
+(Optional) +

Channel specifies the destination channel where events should be posted.

+
+username
+ +string + +
+(Optional) +

Username specifies the name under which events are posted.

+
+address
+ +string + +
+(Optional) +

Address specifies the endpoint, in a generic sense, to where alerts are sent. +What kind of endpoint depends on the specific Provider type being used. +For the generic Provider, for example, this is an HTTP/S address. +For other Provider types this could be a project ID or a namespace.

+
+timeout
+ + +Kubernetes meta/v1.Duration + + +
+(Optional) +

Timeout for sending alerts to the Provider.

+
+proxy
+ +string + +
+(Optional) +

Proxy the HTTP/S address of the proxy server.

+
+secretRef
+ + +github.com/fluxcd/pkg/apis/meta.LocalObjectReference + + +
+(Optional) +

SecretRef specifies the Secret containing the authentication +credentials for this Provider.

+
+certSecretRef
+ + +github.com/fluxcd/pkg/apis/meta.LocalObjectReference + + +
+(Optional) +

CertSecretRef specifies the Secret containing +a PEM-encoded CA certificate (in the ca.crt key).

+

Note: Support for the caFile key has +been deprecated.

+
+suspend
+ +bool + +
+(Optional) +

Suspend tells the controller to suspend subsequent +events handling for this Provider.

+
+crossNamespace
+ +bool + +
+(Optional) +

CrossNamespace allows this provider to be made available to Alerts in other namespaces

+
+
+
+
+

This page was automatically generated with gen-crd-api-reference-docs

+
diff --git a/internal/controller/alert_controller.go b/internal/controller/alert_controller.go index 360dd8923..77467623c 100644 --- a/internal/controller/alert_controller.go +++ b/internal/controller/alert_controller.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" "github.com/fluxcd/pkg/runtime/patch" ) @@ -44,14 +44,14 @@ type AlertReconciler struct { func (r *AlertReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&apiv1beta3.Alert{}, builder.WithPredicates(finalizerPredicate{})). + For(&apiv1beta4.Alert{}, builder.WithPredicates(finalizerPredicate{})). Complete(r) } func (r *AlertReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) { log := ctrl.LoggerFrom(ctx) - obj := &apiv1beta3.Alert{} + obj := &apiv1beta4.Alert{} if err := r.Get(ctx, req.NamespacedName, obj); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) } diff --git a/internal/controller/alert_controller_test.go b/internal/controller/alert_controller_test.go index fdd8717a8..a01755782 100644 --- a/internal/controller/alert_controller_test.go +++ b/internal/controller/alert_controller_test.go @@ -30,7 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" ) func TestAlertReconciler(t *testing.T) { @@ -45,7 +45,7 @@ func TestAlertReconciler(t *testing.T) { g.Expect(testEnv.Cleanup(ctx, testns)).ToNot(HaveOccurred()) }) - alert := &apiv1beta3.Alert{ + alert := &apiv1beta4.Alert{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("alert-%s", randStringRunes(5)), Namespace: testns.Name, @@ -56,8 +56,8 @@ func TestAlertReconciler(t *testing.T) { // Remove finalizer at create. alert.ObjectMeta.Finalizers = append(alert.ObjectMeta.Finalizers, "foo.bar", apiv1.NotificationFinalizer) - alert.Spec = apiv1beta3.AlertSpec{ - ProviderRef: meta.LocalObjectReference{Name: "foo-provider"}, + alert.Spec = apiv1beta4.AlertSpec{ + ProviderRef: meta.NamespacedObjectReference{Name: "foo-provider"}, EventSources: []apiv1.CrossNamespaceObjectReference{}, } g.Expect(testEnv.Create(ctx, alert)).ToNot(HaveOccurred()) diff --git a/internal/controller/finalizer_predicate_test.go b/internal/controller/finalizer_predicate_test.go index a86557d47..3669c5758 100644 --- a/internal/controller/finalizer_predicate_test.go +++ b/internal/controller/finalizer_predicate_test.go @@ -25,11 +25,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" ) -func getAlertWithFinalizers(finalizers []string) *apiv1beta3.Alert { - return &apiv1beta3.Alert{ +func getAlertWithFinalizers(finalizers []string) *apiv1beta4.Alert { + return &apiv1beta4.Alert{ ObjectMeta: metav1.ObjectMeta{ Finalizers: finalizers, }, diff --git a/internal/controller/provider_controller.go b/internal/controller/provider_controller.go index fee2e0db8..9fccd6e28 100644 --- a/internal/controller/provider_controller.go +++ b/internal/controller/provider_controller.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" "github.com/fluxcd/pkg/runtime/patch" ) @@ -46,14 +46,14 @@ type ProviderReconciler struct { func (r *ProviderReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&apiv1beta3.Provider{}, builder.WithPredicates(finalizerPredicate{})). + For(&apiv1beta4.Provider{}, builder.WithPredicates(finalizerPredicate{})). Complete(r) } func (r *ProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) { log := ctrl.LoggerFrom(ctx) - obj := &apiv1beta3.Provider{} + obj := &apiv1beta4.Provider{} if err := r.Get(ctx, req.NamespacedName, obj); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) } diff --git a/internal/controller/provider_controller_test.go b/internal/controller/provider_controller_test.go index 3a25e9246..3fae27886 100644 --- a/internal/controller/provider_controller_test.go +++ b/internal/controller/provider_controller_test.go @@ -29,7 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" ) func TestProviderReconciler(t *testing.T) { @@ -44,7 +44,7 @@ func TestProviderReconciler(t *testing.T) { g.Expect(testEnv.Cleanup(ctx, testns)).ToNot(HaveOccurred()) }) - provider := &apiv1beta3.Provider{ + provider := &apiv1beta4.Provider{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("provider-%s", randStringRunes(5)), Namespace: testns.Name, @@ -55,7 +55,7 @@ func TestProviderReconciler(t *testing.T) { // Remove finalizer at create. provider.ObjectMeta.Finalizers = append(provider.ObjectMeta.Finalizers, "foo.bar", apiv1.NotificationFinalizer) - provider.Spec = apiv1beta3.ProviderSpec{ + provider.Spec = apiv1beta4.ProviderSpec{ Type: "slack", } g.Expect(testEnv.Create(ctx, provider)).ToNot(HaveOccurred()) diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 83d16ec59..dcd2bc6c4 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -44,7 +44,7 @@ import ( apiv1 "github.com/fluxcd/notification-controller/api/v1" apiv1b2 "github.com/fluxcd/notification-controller/api/v1beta2" - apiv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1b3 "github.com/fluxcd/notification-controller/api/v1beta4" // +kubebuilder:scaffold:imports ) diff --git a/internal/notifier/factory.go b/internal/notifier/factory.go index 3280951ea..be58def8f 100644 --- a/internal/notifier/factory.go +++ b/internal/notifier/factory.go @@ -20,7 +20,7 @@ import ( "crypto/x509" "fmt" - apiv1 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1 "github.com/fluxcd/notification-controller/api/v1beta4" ) type Factory struct { diff --git a/internal/server/event_handlers.go b/internal/server/event_handlers.go index c3ff50f04..fa13375dd 100644 --- a/internal/server/event_handlers.go +++ b/internal/server/event_handlers.go @@ -38,7 +38,7 @@ import ( "github.com/fluxcd/pkg/masktoken" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" "github.com/fluxcd/notification-controller/internal/notifier" ) @@ -90,8 +90,8 @@ func (s *EventServer) handleEvent() func(w http.ResponseWriter, r *http.Request) } } -func (s *EventServer) getAllAlertsForEvent(ctx context.Context, event *eventv1.Event) ([]apiv1beta3.Alert, error) { - var allAlerts apiv1beta3.AlertList +func (s *EventServer) getAllAlertsForEvent(ctx context.Context, event *eventv1.Event) ([]apiv1beta4.Alert, error) { + var allAlerts apiv1beta4.AlertList err := s.kubeClient.List(ctx, &allAlerts) if err != nil { return nil, fmt.Errorf("failed listing alerts: %w", err) @@ -103,10 +103,10 @@ func (s *EventServer) getAllAlertsForEvent(ctx context.Context, event *eventv1.E // filterAlertsForEvent filters a given set of alerts against a given event, // checking if the event matches with any of the alert event sources and is // allowed by the exclusion list. -func (s *EventServer) filterAlertsForEvent(ctx context.Context, alerts []apiv1beta3.Alert, event *eventv1.Event) []apiv1beta3.Alert { +func (s *EventServer) filterAlertsForEvent(ctx context.Context, alerts []apiv1beta4.Alert, event *eventv1.Event) []apiv1beta4.Alert { logger := log.FromContext(ctx) - results := make([]apiv1beta3.Alert, 0) + results := make([]apiv1beta4.Alert, 0) for i := range alerts { alert := &alerts[i] // Skip suspended alert. @@ -138,7 +138,7 @@ func (s *EventServer) filterAlertsForEvent(ctx context.Context, alerts []apiv1be // eventMatchesAlertSources returns if a given event matches with any of the // alert sources. -func (s *EventServer) eventMatchesAlertSources(ctx context.Context, event *eventv1.Event, alert *apiv1beta3.Alert) bool { +func (s *EventServer) eventMatchesAlertSources(ctx context.Context, event *eventv1.Event, alert *apiv1beta4.Alert) bool { for _, source := range alert.Spec.EventSources { if source.Namespace == "" { source.Namespace = alert.Namespace @@ -152,7 +152,7 @@ func (s *EventServer) eventMatchesAlertSources(ctx context.Context, event *event // messageIsIncluded returns if the given message matches with the given alert's // inclusion rules. -func (s *EventServer) messageIsIncluded(ctx context.Context, msg string, alert *apiv1beta3.Alert) bool { +func (s *EventServer) messageIsIncluded(ctx context.Context, msg string, alert *apiv1beta4.Alert) bool { if len(alert.Spec.InclusionList) == 0 { return true } @@ -173,7 +173,7 @@ func (s *EventServer) messageIsIncluded(ctx context.Context, msg string, alert * // messageIsExcluded returns if the given message matches with the given alert's // exclusion rules. -func (s *EventServer) messageIsExcluded(ctx context.Context, msg string, alert *apiv1beta3.Alert) bool { +func (s *EventServer) messageIsExcluded(ctx context.Context, msg string, alert *apiv1beta4.Alert) bool { if len(alert.Spec.ExclusionList) == 0 { return false } @@ -194,7 +194,7 @@ func (s *EventServer) messageIsExcluded(ctx context.Context, msg string, alert * // dispatchNotification constructs and sends notification from the given event // and alert data. -func (s *EventServer) dispatchNotification(ctx context.Context, event *eventv1.Event, alert *apiv1beta3.Alert) error { +func (s *EventServer) dispatchNotification(ctx context.Context, event *eventv1.Event, alert *apiv1beta4.Alert) error { sender, notification, token, timeout, err := s.getNotificationParams(ctx, event, alert) if err != nil { return err @@ -227,7 +227,7 @@ func (s *EventServer) dispatchNotification(ctx context.Context, event *eventv1.E // event and alert, and returns a notifier, event, token and timeout for sending // the notification. The returned event is a mutated form of the input event // based on the alert configuration. -func (s *EventServer) getNotificationParams(ctx context.Context, event *eventv1.Event, alert *apiv1beta3.Alert) (notifier.Interface, *eventv1.Event, string, time.Duration, error) { +func (s *EventServer) getNotificationParams(ctx context.Context, event *eventv1.Event, alert *apiv1beta4.Alert) (notifier.Interface, *eventv1.Event, string, time.Duration, error) { // Check if event comes from a different namespace. if s.noCrossNamespaceRefs && event.InvolvedObject.Namespace != alert.Namespace { accessDenied := fmt.Errorf( @@ -236,8 +236,16 @@ func (s *EventServer) getNotificationParams(ctx context.Context, event *eventv1. return nil, nil, "", 0, fmt.Errorf("discarding event, access denied to cross-namespace sources: %w", accessDenied) } - var provider apiv1beta3.Provider - providerName := types.NamespacedName{Namespace: alert.Namespace, Name: alert.Spec.ProviderRef.Name} + var provider apiv1beta4.Provider + var providerNamespace string + + // If there's a namespace reference, use the provider's namespace, otherwise use the alert's namespace + if len(alert.Spec.ProviderRef.Namespace) > 0 { + providerNamespace = alert.Spec.ProviderRef.Namespace + } else { + providerNamespace = alert.Namespace + } + providerName := types.NamespacedName{Namespace: providerNamespace, Name: alert.Spec.ProviderRef.Name} err := s.kubeClient.Get(ctx, providerName, &provider) if err != nil { @@ -249,6 +257,17 @@ func (s *EventServer) getNotificationParams(ctx context.Context, event *eventv1. return nil, nil, "", 0, nil } + // Skip if accessing a provider across namespaces, but the provider doesn't allow it + if providerNamespace != alert.Namespace && !provider.Spec.CrossNamespace { + return nil, nil, "", 0, nil + } + + // If the alert provides an override for the Channel, use it, otherwise use the provider's default channel + if len(alert.Spec.Channel) > 0 { + s.logger.Info("overriding provider's channel", "defaultChannel", provider.Spec.Channel, "alertChannel", alert.Spec.Channel) + provider.Spec.Channel = alert.Spec.Channel + } + sender, token, err := createNotifier(ctx, s.kubeClient, provider) if err != nil { return nil, nil, "", 0, fmt.Errorf("failed to initialize notifier for provider '%s': %w", provider.Name, err) @@ -261,7 +280,7 @@ func (s *EventServer) getNotificationParams(ctx context.Context, event *eventv1. } // createNotifier returns a notifier.Interface for the given Provider. -func createNotifier(ctx context.Context, kubeClient client.Client, provider apiv1beta3.Provider) (notifier.Interface, string, error) { +func createNotifier(ctx context.Context, kubeClient client.Client, provider apiv1beta4.Provider) (notifier.Interface, string, error) { logger := log.FromContext(ctx) webhook := provider.Spec.Address @@ -361,7 +380,7 @@ func createNotifier(ctx context.Context, kubeClient client.Client, provider apiv // eventMatchesAlertSource returns if a given event matches with the given alert // source configuration and severity. -func (s *EventServer) eventMatchesAlertSource(ctx context.Context, event *eventv1.Event, alert *apiv1beta3.Alert, source apiv1.CrossNamespaceObjectReference) bool { +func (s *EventServer) eventMatchesAlertSource(ctx context.Context, event *eventv1.Event, alert *apiv1beta4.Alert, source apiv1.CrossNamespaceObjectReference) bool { logger := log.FromContext(ctx) // No match if the event and source don't have the same namespace and kind. @@ -418,7 +437,7 @@ func (s *EventServer) eventMatchesAlertSource(ctx context.Context, event *eventv } // enhanceEventWithAlertMetadata enhances the event with Alert metadata. -func (s *EventServer) enhanceEventWithAlertMetadata(ctx context.Context, event *eventv1.Event, alert *apiv1beta3.Alert) { +func (s *EventServer) enhanceEventWithAlertMetadata(ctx context.Context, event *eventv1.Event, alert *apiv1beta4.Alert) { meta := event.Metadata if meta == nil { meta = make(map[string]string) diff --git a/internal/server/event_handlers_test.go b/internal/server/event_handlers_test.go index 0b9f7aef6..21fa38b50 100644 --- a/internal/server/event_handlers_test.go +++ b/internal/server/event_handlers_test.go @@ -37,16 +37,16 @@ import ( "github.com/fluxcd/pkg/apis/meta" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" ) func TestFilterAlertsForEvent(t *testing.T) { testNamespace := "foo-ns" - testProvider := &apiv1beta3.Provider{} + testProvider := &apiv1beta4.Provider{} testProvider.Name = "provider-foo" testProvider.Namespace = testNamespace - testProvider.Spec = apiv1beta3.ProviderSpec{ + testProvider.Spec = apiv1beta4.ProviderSpec{ Type: "generic", Address: "https://example.com", } @@ -65,12 +65,12 @@ func TestFilterAlertsForEvent(t *testing.T) { tests := []struct { name string - alertSpecs []apiv1beta3.AlertSpec + alertSpecs []apiv1beta4.AlertSpec resultAlertCount int }{ { name: "all match", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -92,7 +92,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "some suspended alerts", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -115,7 +115,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with inclusion list unmatch", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -130,7 +130,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with inclusion list match", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -154,7 +154,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with invalid inclusion rule", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -169,7 +169,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with exclusion list match", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -192,7 +192,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with invalid exclusion rule", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -215,7 +215,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "alerts with inclusion and exclusion list match", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -239,7 +239,7 @@ func TestFilterAlertsForEvent(t *testing.T) { }, { name: "event source NS is not overwritten by alert NS", - alertSpecs: []apiv1beta3.AlertSpec{ + alertSpecs: []apiv1beta4.AlertSpec{ { EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -258,12 +258,12 @@ func TestFilterAlertsForEvent(t *testing.T) { t.Run(tt.name, func(t *testing.T) { g := NewWithT(t) - alerts := []apiv1beta3.Alert{} + alerts := []apiv1beta4.Alert{} for i, alertSpec := range tt.alertSpecs { // Add the default provider ref for this test. - alertSpec.ProviderRef = meta.LocalObjectReference{Name: testProvider.Name} + alertSpec.ProviderRef = meta.NamespacedObjectReference{Name: testProvider.Name} // Create new Alert with the spec. - alert := apiv1beta3.Alert{} + alert := apiv1beta4.Alert{} alert.Name = "test-alert-" + strconv.Itoa(i) alert.Namespace = testNamespace alert.Spec = alertSpec @@ -272,7 +272,7 @@ func TestFilterAlertsForEvent(t *testing.T) { // Create fake objects and event server. scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) builder := fakeclient.NewClientBuilder().WithScheme(scheme) builder.WithObjects(testProvider) eventServer := EventServer{ @@ -296,19 +296,19 @@ func TestDispatchNotification(t *testing.T) { })) defer rcvServer.Close() - testProvider := &apiv1beta3.Provider{} + testProvider := &apiv1beta4.Provider{} testProvider.Name = "provider-foo" testProvider.Namespace = testNamespace - testProvider.Spec = apiv1beta3.ProviderSpec{ + testProvider.Spec = apiv1beta4.ProviderSpec{ Type: "generic", Address: rcvServer.URL, } - testAlert := &apiv1beta3.Alert{} + testAlert := &apiv1beta4.Alert{} testAlert.Name = "alert-foo" testAlert.Namespace = testNamespace - testAlert.Spec = apiv1beta3.AlertSpec{ - ProviderRef: meta.LocalObjectReference{Name: testProvider.Name}, + testAlert.Spec = apiv1beta4.AlertSpec{ + ProviderRef: meta.NamespacedObjectReference{Name: testProvider.Name}, } // Event involved object. @@ -355,7 +355,7 @@ func TestDispatchNotification(t *testing.T) { // Create fake objects and event server. scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) g.Expect(corev1.AddToScheme(scheme)).ToNot(HaveOccurred()) builder := fakeclient.NewClientBuilder().WithScheme(scheme) builder.WithObjects(provider) @@ -379,20 +379,20 @@ func TestGetNotificationParams(t *testing.T) { testSecret.Name = "secret-foo" testSecret.Namespace = testNamespace - testProvider := &apiv1beta3.Provider{} + testProvider := &apiv1beta4.Provider{} testProvider.Name = "provider-foo" testProvider.Namespace = testNamespace - testProvider.Spec = apiv1beta3.ProviderSpec{ + testProvider.Spec = apiv1beta4.ProviderSpec{ Type: "generic", Address: "https://example.com", SecretRef: &meta.LocalObjectReference{Name: testSecret.Name}, } - testAlert := &apiv1beta3.Alert{} + testAlert := &apiv1beta4.Alert{} testAlert.Name = "alert-foo" testAlert.Namespace = testNamespace - testAlert.Spec = apiv1beta3.AlertSpec{ - ProviderRef: meta.LocalObjectReference{Name: testProvider.Name}, + testAlert.Spec = apiv1beta4.AlertSpec{ + ProviderRef: meta.NamespacedObjectReference{Name: testProvider.Name}, } // Event involved object. @@ -498,7 +498,7 @@ func TestGetNotificationParams(t *testing.T) { // Create fake objects and event server. scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) g.Expect(corev1.AddToScheme(scheme)).ToNot(HaveOccurred()) builder := fakeclient.NewClientBuilder().WithScheme(scheme) builder.WithObjects(provider, secret) @@ -530,7 +530,7 @@ func TestCreateNotifier(t *testing.T) { certSecretName := "cert-secret" tests := []struct { name string - providerSpec *apiv1beta3.ProviderSpec + providerSpec *apiv1beta4.ProviderSpec secretType corev1.SecretType secretData map[string][]byte certSecretData map[string][]byte @@ -538,21 +538,21 @@ func TestCreateNotifier(t *testing.T) { }{ { name: "no address, no secret ref", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", }, wantErr: true, }, { name: "valid address, no secret ref", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", }, }, { name: "reference to non-existing secret ref", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: "foo"}, }, @@ -560,7 +560,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "reference to secret with valid address, proxy, headers", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: secretName}, }, @@ -572,7 +572,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "reference to secret with invalid proxy", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: secretName}, }, @@ -584,7 +584,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "invalid headers in secret reference", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: secretName}, }, @@ -596,7 +596,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "invalid spec address overridden by valid secret ref address", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: secretName}, Address: "https://example.com|", @@ -607,7 +607,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "invalid spec proxy overridden by valid secret ref proxy", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", SecretRef: &meta.LocalObjectReference{Name: secretName}, Proxy: "https://example.com|", @@ -619,7 +619,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "reference to unsupported cert secret type", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -632,7 +632,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "reference to non-existing cert secret", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: "some-secret"}, @@ -641,7 +641,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "reference to cert secret without cert data", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -653,7 +653,7 @@ func TestCreateNotifier(t *testing.T) { }, { name: "cert secret reference in ca.crt with valid CA", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -675,7 +675,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "cert secret reference in caFile with valid CA", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -697,7 +697,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "cert secret reference in both ca.crt and caFile", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -720,7 +720,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "cert secret reference with invalid CA", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "slack", Address: "https://example.com", CertSecretRef: &meta.LocalObjectReference{Name: certSecretName}, @@ -732,7 +732,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "unsupported provider", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "foo", Address: "https://example.com", }, @@ -740,7 +740,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "address in secret too long", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "msteams", SecretRef: &meta.LocalObjectReference{Name: secretName}, }, @@ -751,7 +751,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc }, { name: "address in secret exactly as long as possible", - providerSpec: &apiv1beta3.ProviderSpec{ + providerSpec: &apiv1beta4.ProviderSpec{ Type: "msteams", SecretRef: &meta.LocalObjectReference{Name: secretName}, }, @@ -768,7 +768,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc // Create fake objects and event server. scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) g.Expect(corev1.AddToScheme(scheme)).ToNot(HaveOccurred()) builder := fakeclient.NewClientBuilder().WithScheme(scheme) if tt.secretData != nil { @@ -786,7 +786,7 @@ Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc } builder.WithObjects(secret) } - provider := apiv1beta3.Provider{Spec: *tt.providerSpec} + provider := apiv1beta4.Provider{Spec: *tt.providerSpec} _, _, err := createNotifier(context.TODO(), builder.Build(), provider) g.Expect(err != nil).To(Equal(tt.wantErr)) @@ -945,7 +945,7 @@ func TestEventMatchesAlert(t *testing.T) { g := NewWithT(t) scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) builder := fakeclient.NewClientBuilder().WithScheme(scheme) @@ -961,12 +961,12 @@ func TestEventMatchesAlert(t *testing.T) { logger: log.Log, EventRecorder: record.NewFakeRecorder(32), } - alert := &apiv1beta3.Alert{ + alert := &apiv1beta4.Alert{ ObjectMeta: metav1.ObjectMeta{ Name: "test-alert", Namespace: "test-ns", }, - Spec: apiv1beta3.AlertSpec{ + Spec: apiv1beta4.AlertSpec{ EventSeverity: tt.severity, }, } @@ -985,18 +985,18 @@ func TestEnhanceEventWithAlertMetadata(t *testing.T) { for name, tt := range map[string]struct { event eventv1.Event - alert apiv1beta3.Alert + alert apiv1beta4.Alert expectedMetadata map[string]string }{ "empty metadata": { event: eventv1.Event{}, - alert: apiv1beta3.Alert{}, + alert: apiv1beta4.Alert{}, expectedMetadata: nil, }, "enhanced with summary": { event: eventv1.Event{}, - alert: apiv1beta3.Alert{ - Spec: apiv1beta3.AlertSpec{ + alert: apiv1beta4.Alert{ + Spec: apiv1beta4.AlertSpec{ Summary: "summary", }, }, @@ -1010,8 +1010,8 @@ func TestEnhanceEventWithAlertMetadata(t *testing.T) { "summary": "original summary", }, }, - alert: apiv1beta3.Alert{ - Spec: apiv1beta3.AlertSpec{ + alert: apiv1beta4.Alert{ + Spec: apiv1beta4.AlertSpec{ Summary: "summary", }, }, @@ -1021,8 +1021,8 @@ func TestEnhanceEventWithAlertMetadata(t *testing.T) { }, "enhanced with metadata": { event: eventv1.Event{}, - alert: apiv1beta3.Alert{ - Spec: apiv1beta3.AlertSpec{ + alert: apiv1beta4.Alert{ + Spec: apiv1beta4.AlertSpec{ EventMetadata: map[string]string{ "foo": "bar", }, @@ -1038,8 +1038,8 @@ func TestEnhanceEventWithAlertMetadata(t *testing.T) { "foo": "baz", }, }, - alert: apiv1beta3.Alert{ - Spec: apiv1beta3.AlertSpec{ + alert: apiv1beta4.Alert{ + Spec: apiv1beta4.AlertSpec{ EventMetadata: map[string]string{ "foo": "bar", }, diff --git a/internal/server/event_server_test.go b/internal/server/event_server_test.go index 9aec6ace0..151cc5a97 100644 --- a/internal/server/event_server_test.go +++ b/internal/server/event_server_test.go @@ -48,7 +48,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" apiv1 "github.com/fluxcd/notification-controller/api/v1" - apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1beta4 "github.com/fluxcd/notification-controller/api/v1beta4" ) func TestEventServer(t *testing.T) { @@ -64,19 +64,19 @@ func TestEventServer(t *testing.T) { })) defer rcvServer.Close() - provider := &apiv1beta3.Provider{} + provider := &apiv1beta4.Provider{} provider.Name = "provider-foo" provider.Namespace = testNamespace - provider.Spec = apiv1beta3.ProviderSpec{ + provider.Spec = apiv1beta4.ProviderSpec{ Type: "generic", Address: rcvServer.URL, } - testAlert := &apiv1beta3.Alert{} + testAlert := &apiv1beta4.Alert{} testAlert.Name = "alert-foo" testAlert.Namespace = testNamespace - testAlert.Spec = apiv1beta3.AlertSpec{ - ProviderRef: meta.LocalObjectReference{Name: provider.Name}, + testAlert.Spec = apiv1beta4.AlertSpec{ + ProviderRef: meta.NamespacedObjectReference{Name: provider.Name}, EventSeverity: "info", EventSources: []apiv1.CrossNamespaceObjectReference{ { @@ -110,7 +110,7 @@ func TestEventServer(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) scheme := runtime.NewScheme() - g.Expect(apiv1beta3.AddToScheme(scheme)).ToNot(HaveOccurred()) + g.Expect(apiv1beta4.AddToScheme(scheme)).ToNot(HaveOccurred()) g.Expect(corev1.AddToScheme(scheme)).ToNot(HaveOccurred()) // Create a fake kube client with the above objects. diff --git a/main.go b/main.go index 5530ea7ba..1d30c27d7 100644 --- a/main.go +++ b/main.go @@ -50,6 +50,7 @@ import ( apiv1 "github.com/fluxcd/notification-controller/api/v1" apiv1b2 "github.com/fluxcd/notification-controller/api/v1beta2" apiv1b3 "github.com/fluxcd/notification-controller/api/v1beta3" + apiv1b4 "github.com/fluxcd/notification-controller/api/v1beta4" "github.com/fluxcd/notification-controller/internal/controller" "github.com/fluxcd/notification-controller/internal/features" "github.com/fluxcd/notification-controller/internal/server" @@ -69,6 +70,7 @@ func init() { _ = apiv1.AddToScheme(scheme) _ = apiv1b2.AddToScheme(scheme) _ = apiv1b3.AddToScheme(scheme) + _ = apiv1b4.AddToScheme(scheme) // +kubebuilder:scaffold:scheme }