diff --git a/controllers/factory/vmalert.go b/controllers/factory/vmalert.go index 31313c87..e6cab3e2 100644 --- a/controllers/factory/vmalert.go +++ b/controllers/factory/vmalert.go @@ -12,6 +12,7 @@ import ( "github.com/VictoriaMetrics/operator/controllers/factory/k8stools" "github.com/VictoriaMetrics/operator/controllers/factory/psp" "github.com/VictoriaMetrics/operator/internal/config" + "golang.org/x/exp/slices" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -127,26 +128,15 @@ func createOrUpdateVMAlertSecret(ctx context.Context, rclient client.Client, cr func CreateOrUpdateVMAlert(ctx context.Context, cr *victoriametricsv1beta1.VMAlert, rclient client.Client, c *config.BaseOperatorConf, cmNames []string) error { l := log.WithValues("controller", "vmalert.crud", "vmalert", cr.Name) + // copy to avoid side effects. cr = cr.DeepCopy() - var additionalNotifiers []victoriametricsv1beta1.VMAlertNotifierSpec - if cr.Spec.Notifier != nil { - cr.Spec.Notifiers = append(cr.Spec.Notifiers, *cr.Spec.Notifier) - } - // trim notifiers with non-empty notifier Selector - var cnt int - for i := range cr.Spec.Notifiers { - n := cr.Spec.Notifiers[i] - // fast path - if n.Selector == nil { - cr.Spec.Notifiers[cnt] = n - cnt++ - continue - } + var additionalNotifiers []victoriametricsv1beta1.VMAlertNotifierSpec + for _, selector := range cr.GetNotifierSelectors() { // discover alertmanagers var ams victoriametricsv1beta1.VMAlertmanagerList - amListOpts, err := n.Selector.AsListOptions() + amListOpts, err := selector.AsListOptions() if err != nil { return fmt.Errorf("cannot convert notifier selector as ListOptions: %w", err) } @@ -154,14 +144,23 @@ func CreateOrUpdateVMAlert(ctx context.Context, cr *victoriametricsv1beta1.VMAle return fmt.Errorf("cannot list alertmanagers for vmalert notifier sd: %w", err) } for _, item := range ams.Items { - if !item.DeletionTimestamp.IsZero() || (n.Selector.Namespace != nil && !n.Selector.Namespace.IsMatch(&item)) { + if !item.DeletionTimestamp.IsZero() || (selector.Namespace != nil && !selector.Namespace.IsMatch(&item)) { continue } dsc := item.AsNotifiers() additionalNotifiers = append(additionalNotifiers, dsc...) } } - cr.Spec.Notifiers = cr.Spec.Notifiers[:cnt] + + // remove notifiers with a selector as they have been consumed and the + // results added to additionalNotifiers. + cr.Spec.Notifiers = slices.DeleteFunc(cr.Spec.Notifiers, func(n victoriametricsv1beta1.VMAlertNotifierSpec) bool { + return n.Selector != nil + }) + + if cr.Spec.Notifier != nil && cr.Spec.Notifier.Selector == nil { + cr.Spec.Notifiers = append(cr.Spec.Notifiers, *cr.Spec.Notifier) + } if len(additionalNotifiers) > 0 { sort.Slice(additionalNotifiers, func(i, j int) bool { diff --git a/controllers/factory/vmalert_test.go b/controllers/factory/vmalert_test.go index 82699436..782fe1ea 100644 --- a/controllers/factory/vmalert_test.go +++ b/controllers/factory/vmalert_test.go @@ -146,316 +146,465 @@ func TestCreateOrUpdateVMAlert(t *testing.T) { wantErr bool predefinedObjects []runtime.Object validator func(vma *v1.Deployment) error - }{ - { - name: "base-spec-gen", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", + }{{ + name: "base-spec-gen", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ + URL: "http://some-alertmanager", }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ - URL: "http://some-alertmanager", - }, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", - }, + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", }, }, - c: config.MustGetBaseConfig(), }, + c: config.MustGetBaseConfig(), }, - { - name: "base-spec-gen with externalLabels", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", - }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ - URL: "http://some-alertmanager", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }, + }, { + name: "base-spec-gen with externalLabels", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ + URL: "http://some-alertmanager", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + }}, + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + InsecureSkipVerify: true, }}, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }}, - }, - ExternalLabels: map[string]string{"label1": "value1", "label2": "value-2"}, }, + ExternalLabels: map[string]string{"label1": "value1", "label2": "value-2"}, }, - c: config.MustGetBaseConfig(), - }, - validator: func(vma *v1.Deployment) error { - var foundOk bool - for _, cnt := range vma.Spec.Template.Spec.Containers { - if cnt.Name == "vmalert" { - args := cnt.Args - for _, arg := range args { - if strings.HasPrefix(arg, "-external.label") { - foundOk = true - kv := strings.ReplaceAll(arg, "-external.label=", "") - if kv != "label1=value1" && kv != "label2=value-2" { - return fmt.Errorf("unexepcted value for external.label arg: %s", kv) - } + }, + c: config.MustGetBaseConfig(), + }, + validator: func(vma *v1.Deployment) error { + var foundOk bool + for _, cnt := range vma.Spec.Template.Spec.Containers { + if cnt.Name == "vmalert" { + args := cnt.Args + for _, arg := range args { + if strings.HasPrefix(arg, "-external.label") { + foundOk = true + kv := strings.ReplaceAll(arg, "-external.label=", "") + if kv != "label1=value1" && kv != "label2=value-2" { + return fmt.Errorf("unexepcted value for external.label arg: %s", kv) } } } } - if !foundOk { - return fmt.Errorf("expected to found arg: -external.label at vmalert container") - } - return nil - }, + } + if !foundOk { + return fmt.Errorf("expected to found arg: -external.label at vmalert container") + } + return nil }, - { - name: "with-remote-tls", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", + }, { + name: "with-remote-tls", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ + URL: "http://some-alertmanager", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + CAFile: "/tmp/ca", + CertFile: "/tmp/cert", + KeyFile: "/tmp/key", + }, + }}, + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ + { + URL: "http://another-alertmanager", + }, }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - Notifier: &victoriametricsv1beta1.VMAlertNotifierSpec{ - URL: "http://some-alertmanager", + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + CA: victoriametricsv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, + }, + Cert: victoriametricsv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, + }, + KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, + }, + }}, + RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ + URL: "http://vm-insert-url", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + CA: victoriametricsv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, + }, + Cert: victoriametricsv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, + }, + KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, + }, + }}, + }, + }, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", + }, + Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + }, + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", + }, + Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, + }, + }, + }, { + name: "with-notifiers-tls", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ + { + URL: "http://another-alertmanager", HTTPAuth: victoriametricsv1beta1.HTTPAuth{ TLSConfig: &victoriametricsv1beta1.TLSConfig{ CAFile: "/tmp/ca", CertFile: "/tmp/cert", KeyFile: "/tmp/key", + }}, + }, + }, + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + CA: victoriametricsv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, }, - }}, - Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ - { - URL: "http://another-alertmanager", + Cert: victoriametricsv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, + }, + KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, }, }, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - CA: victoriametricsv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - Cert: victoriametricsv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, + }, + RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ + URL: "http://vm-insert-url", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + CA: victoriametricsv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, }, - }}, - RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ - URL: "http://vm-insert-url", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - CA: victoriametricsv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - Cert: victoriametricsv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, + Cert: victoriametricsv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, }, - }}, - }, + KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, + }, + }}, }, - c: config.MustGetBaseConfig(), }, - predefinedObjects: []runtime.Object{ - &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, - &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, + Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + }, + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", }, + Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, }, }, - { - name: "with-notifiers-tls", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", - }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ - { - URL: "http://another-alertmanager", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - CAFile: "/tmp/ca", - CertFile: "/tmp/cert", - KeyFile: "/tmp/key", - }}, - }, - }, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", + }, { + name: "with tlsconfig insecure true", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ + { + URL: "http://another-alertmanager", HTTPAuth: victoriametricsv1beta1.HTTPAuth{ TLSConfig: &victoriametricsv1beta1.TLSConfig{ - CA: victoriametricsv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - Cert: victoriametricsv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, - }, - }, + InsecureSkipVerify: true, + }}, }, - RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ - URL: "http://vm-insert-url", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - CA: victoriametricsv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - Cert: victoriametricsv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "ca"}, - }, - KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "datasource-tls"}, Key: "key"}, - }, + }, + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + InsecureSkipVerify: true, }}, }, + RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ + URL: "http://vm-insert-url", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }}, + }, + RemoteRead: &victoriametricsv1beta1.VMAlertRemoteReadSpec{ + URL: "http://vm-insert-url", + HTTPAuth: victoriametricsv1beta1.HTTPAuth{ + TLSConfig: &victoriametricsv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + }, + }, }, - c: config.MustGetBaseConfig(), }, - predefinedObjects: []runtime.Object{ - &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, - &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, + Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + }, + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "datasource-tls", + Namespace: "default", }, + Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, }, }, - { - name: "with tlsconfig insecure true", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", + }, { + name: "with notifier config", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic-vmalert", + Namespace: "default", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + NotifierConfigRef: &corev1.SecretKeySelector{ + Key: "cfg.yaml", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "notifier-cfg", + }, }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{ - { - URL: "http://another-alertmanager", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }}, + Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ + URL: "http://some-vm-datasource", + }, + }, + }, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "notifier-cfg", + Namespace: "default", + }, + StringData: map[string]string{"cfg.yaml": "static: []"}, + }, + }, + }, { + name: "with selector", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{{ + Selector: &victoriametricsv1beta1.DiscoverySelector{ + Labels: &metav1.LabelSelector{ + MatchLabels: map[string]string{"some-label-key": "some-label-value"}, }, }, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }}, - }, - RemoteWrite: &victoriametricsv1beta1.VMAlertRemoteWriteSpec{ - URL: "http://vm-insert-url", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }}, - }, - RemoteRead: &victoriametricsv1beta1.VMAlertRemoteReadSpec{ - URL: "http://vm-insert-url", - HTTPAuth: victoriametricsv1beta1.HTTPAuth{ - TLSConfig: &victoriametricsv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }, + }}, + }, + }, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &victoriametricsv1beta1.VMAlertmanager{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + Labels: map[string]string{"some-label-key": "some-label-value"}, + }, + }, + }, + }, { + name: "with selector in namespace", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{{ + Selector: &victoriametricsv1beta1.DiscoverySelector{ + Namespace: &victoriametricsv1beta1.NamespaceSelector{ + MatchNames: []string{"some-other-namespace"}, + }, + Labels: &metav1.LabelSelector{ + MatchLabels: map[string]string{"some-label-key": "some-label-value"}, }, }, - }, + }}, }, - c: config.MustGetBaseConfig(), }, - predefinedObjects: []runtime.Object{ - &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}, - &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string][]byte{"ca": []byte(`sa`), "cert": []byte(`cert-data`), "key": []byte(`"key-data"`)}, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &victoriametricsv1beta1.VMAlertmanager{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + Labels: map[string]string{"some-label-key": "some-label-value"}, }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "datasource-tls", - Namespace: "default", - }, - Data: map[string]string{"ca": "ca-data", "cert": "cert-data"}, + }, + }, + }, { + name: "with selector in any namespace", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{{ + Selector: &victoriametricsv1beta1.DiscoverySelector{ + Namespace: &victoriametricsv1beta1.NamespaceSelector{ + Any: true, + }, + Labels: &metav1.LabelSelector{ + MatchLabels: map[string]string{"some-label-key": "some-label-value"}, + }, + }, + }}, }, }, + c: config.MustGetBaseConfig(), }, - { - name: "with notifier config", - args: args{ - cr: &victoriametricsv1beta1.VMAlert{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic-vmalert", - Namespace: "default", - }, - Spec: victoriametricsv1beta1.VMAlertSpec{ - NotifierConfigRef: &corev1.SecretKeySelector{ - Key: "cfg.yaml", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "notifier-cfg", + predefinedObjects: []runtime.Object{ + &victoriametricsv1beta1.VMAlertmanager{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + Labels: map[string]string{"some-label-key": "some-label-value"}, + }, + }, + }, + }, { + name: "with invalid selector", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{{ + Selector: &victoriametricsv1beta1.DiscoverySelector{ + Labels: &metav1.LabelSelector{ + MatchLabels: map[string]string{"some-label-key": "some-label-value"}, }, }, - Datasource: victoriametricsv1beta1.VMAlertDatasourceSpec{ - URL: "http://some-vm-datasource", + }}, + }, + }, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &victoriametricsv1beta1.VMAlertmanager{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + Labels: map[string]string{"some-label-key": "some-invalid-label-value"}, + }, + }, + }, + wantErr: true, + }, { + name: "with selector in invalid namespace", + args: args{ + cr: &victoriametricsv1beta1.VMAlert{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-name", + Namespace: "some-namespace", + }, + Spec: victoriametricsv1beta1.VMAlertSpec{ + Notifiers: []victoriametricsv1beta1.VMAlertNotifierSpec{{ + Selector: &victoriametricsv1beta1.DiscoverySelector{ + Namespace: &victoriametricsv1beta1.NamespaceSelector{ + MatchNames: []string{"some-namespace"}, + }, + Labels: &metav1.LabelSelector{ + MatchLabels: map[string]string{"some-label-key": "some-label-value"}, + }, }, - }, + }}, }, - c: config.MustGetBaseConfig(), }, - predefinedObjects: []runtime.Object{ - &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "notifier-cfg", - Namespace: "default", - }, - StringData: map[string]string{"cfg.yaml": "static: []"}, + c: config.MustGetBaseConfig(), + }, + predefinedObjects: []runtime.Object{ + &victoriametricsv1beta1.VMAlertmanager{ + ObjectMeta: metav1.ObjectMeta{ + Name: "some-other-name", + Namespace: "some-other-namespace", + Labels: map[string]string{"some-label-key": "some-label-value"}, }, }, }, - } + wantErr: true, + }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fclient := k8stools.GetTestClientWithObjects(tt.predefinedObjects) - err := CreateOrUpdateVMAlert(context.TODO(), tt.args.cr, fclient, tt.args.c, tt.args.cmNames) + err := CreateOrUpdateVMAlert(context.Background(), tt.args.cr, fclient, tt.args.c, tt.args.cmNames) if (err != nil) != tt.wantErr { t.Errorf("CreateOrUpdateVMAlert() error = %v, wantErr %v", err, tt.wantErr) return @@ -463,11 +612,11 @@ func TestCreateOrUpdateVMAlert(t *testing.T) { if tt.validator != nil { var generatedDeploment v1.Deployment - if err := fclient.Get(context.TODO(), types.NamespacedName{Namespace: tt.args.cr.Namespace, Name: tt.args.cr.PrefixedName()}, &generatedDeploment); err != nil { + if err := fclient.Get(context.Background(), types.NamespacedName{Namespace: tt.args.cr.Namespace, Name: tt.args.cr.PrefixedName()}, &generatedDeploment); err != nil { t.Fatalf("cannot find generated deployment: %v, err: %v", tt.args.cr.PrefixedName(), err) } if err := tt.validator(&generatedDeploment); err != nil { - t.Fatalf("unexpetected error at deployment validation: %v", err) + t.Fatalf("unexpected error during deployment validation: %v", err) } } }) diff --git a/go.mod b/go.mod index 7dc7e692..2b2841a0 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 go.uber.org/zap v1.21.0 + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/net v0.10.0 golang.org/x/sync v0.2.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index da9d48fa..3ca5bd86 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,18 @@ cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQ cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= +github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/VictoriaMetrics/VictoriaMetrics v1.90.1-0.20230427110221-29e059e49c7d h1:vKrE/KI2MISNYsTQsA5igEI4nXQM/WWeN1DUWKuckxk= github.com/VictoriaMetrics/VictoriaMetrics v1.90.1-0.20230427110221-29e059e49c7d/go.mod h1:2ox/nrMfi4iGrv7rb/5FkFD4dmWkN83wCmdIMNX8EqE= github.com/VictoriaMetrics/VictoriaMetrics v1.91.3 h1:mInejMsp7W3z4lrEzO4uQy59WnxIhMqwCeiogAId+jU= @@ -24,6 +34,7 @@ github.com/VictoriaMetrics/metricsql v0.56.2/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQI github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -39,10 +50,14 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful/v3 v3.10.0 h1:X4gma4HM7hFm6WMeAsTfqA0GOfdNoCzBIkHGoRLGXuM= github.com/emicklei/go-restful/v3 v3.10.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -57,6 +72,7 @@ github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -83,6 +99,7 @@ github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -105,6 +122,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -121,17 +139,25 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -148,12 +174,15 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -161,9 +190,13 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -173,6 +206,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -200,6 +234,8 @@ github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -215,6 +251,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= @@ -232,9 +269,17 @@ github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7Fw github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -255,6 +300,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -388,6 +437,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -403,6 +453,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.25.6 h1:LwDY2H6kD/3R8TekJYYaJWOdekNdXDO44eVpX6sNtJA=