diff --git a/api/v1beta1/grafanaalertrulegroup_types.go b/api/v1beta1/grafanaalertrulegroup_types.go index 69c5b60c1..2fc1ec71d 100644 --- a/api/v1beta1/grafanaalertrulegroup_types.go +++ b/api/v1beta1/grafanaalertrulegroup_types.go @@ -75,6 +75,8 @@ type AlertRule struct { IsPaused bool `json:"isPaused,omitempty"` + NotificationSettings *NotificationSettings `json:"notificationSettings,omitempty"` + Labels map[string]string `json:"labels,omitempty"` // +kubebuilder:validation:Enum=Alerting;NoData;OK;KeepLast @@ -89,6 +91,15 @@ type AlertRule struct { UID string `json:"uid"` } +type NotificationSettings struct { + GroupBy []string `json:"group_by,omitempty"` + GroupInterval string `json:"group_interval,omitempty"` + GroupWait string `json:"group_wait,omitempty"` + Receiver string `json:"receiver"` + MuteTimeIntervals []string `json:"mute_time_intervals,omitempty"` + RepeatInterval string `json:"repeat_interval,omitempty"` +} + type AlertQuery struct { // Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation. DatasourceUID string `json:"datasourceUid,omitempty"` diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 7782a3533..f8036cb5f 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -83,6 +83,11 @@ func (in *AlertRule) DeepCopyInto(out *AlertRule) { *out = new(metav1.Duration) **out = **in } + if in.NotificationSettings != nil { + in, out := &in.NotificationSettings, &out.NotificationSettings + *out = new(NotificationSettings) + (*in).DeepCopyInto(*out) + } if in.Labels != nil { in, out := &in.Labels, &out.Labels *out = make(map[string]string, len(*in)) @@ -1447,6 +1452,31 @@ func (in NamespacedResourceList) DeepCopy() NamespacedResourceList { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NotificationSettings) DeepCopyInto(out *NotificationSettings) { + *out = *in + if in.GroupBy != nil { + in, out := &in.GroupBy, &out.GroupBy + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.MuteTimeIntervals != nil { + in, out := &in.MuteTimeIntervals, &out.MuteTimeIntervals + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationSettings. +func (in *NotificationSettings) DeepCopy() *NotificationSettings { + if in == nil { + return nil + } + out := new(NotificationSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) { *out = *in diff --git a/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml b/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml index 270fee076..515bd1696 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml @@ -125,6 +125,27 @@ spec: - OK - KeepLast type: string + notificationSettings: + properties: + group_by: + items: + type: string + type: array + group_interval: + type: string + group_wait: + type: string + mute_time_intervals: + items: + type: string + type: array + receiver: + type: string + repeat_interval: + type: string + required: + - receiver + type: object title: example: Always firing maxLength: 190 diff --git a/config/grafana.integreatly.org_grafanaalertrulegroups.yaml b/config/grafana.integreatly.org_grafanaalertrulegroups.yaml index 70551ce04..e4b679529 100644 --- a/config/grafana.integreatly.org_grafanaalertrulegroups.yaml +++ b/config/grafana.integreatly.org_grafanaalertrulegroups.yaml @@ -178,6 +178,27 @@ spec: - OK - KeepLast type: string + notificationSettings: + properties: + group_by: + items: + type: string + type: array + group_interval: + type: string + group_wait: + type: string + mute_time_intervals: + items: + type: string + type: array + receiver: + type: string + repeat_interval: + type: string + required: + - receiver + type: object title: example: Always firing maxLength: 190 diff --git a/controllers/dashboard_controller.go b/controllers/dashboard_controller.go index 0d20ac1e8..1bd4b4669 100644 --- a/controllers/dashboard_controller.go +++ b/controllers/dashboard_controller.go @@ -490,9 +490,6 @@ func (r *GrafanaDashboardReconciler) fetchDashboardJson(ctx context.Context, das func (r *GrafanaDashboardReconciler) getDashboardEnvs(ctx context.Context, dashboard *v1beta1.GrafanaDashboard) (map[string]string, error) { envs := make(map[string]string) - if dashboard.Spec.EnvsFrom == nil && dashboard.Spec.Envs == nil { - return nil, fmt.Errorf("dashboard.Spec.Envs or dashboard.Spec.EnvFrom nil, can't get envs for dashboard: %s", dashboard.Name) - } if dashboard.Spec.EnvsFrom != nil { for _, ref := range dashboard.Spec.EnvsFrom { key, val, err := r.getReferencedValue(ctx, dashboard, ref) diff --git a/controllers/grafanaalertrulegroup_controller.go b/controllers/grafanaalertrulegroup_controller.go index ad401b1d2..9db2c0b08 100644 --- a/controllers/grafanaalertrulegroup_controller.go +++ b/controllers/grafanaalertrulegroup_controller.go @@ -225,6 +225,15 @@ func (r *GrafanaAlertRuleGroupReconciler) reconcileWithInstance(ctx context.Cont Title: &rule.Title, UID: rule.UID, } + if rule.NotificationSettings != nil { + apiRule.NotificationSettings = &models.AlertRuleNotificationSettings{ + Receiver: &rule.NotificationSettings.Receiver, + GroupBy: rule.NotificationSettings.GroupBy, + GroupWait: rule.NotificationSettings.GroupWait, + GroupInterval: rule.NotificationSettings.GroupInterval, + RepeatInterval: rule.NotificationSettings.RepeatInterval, + } + } for idx, q := range rule.Data { apiRule.Data[idx] = &models.AlertQuery{ DatasourceUID: q.DatasourceUID, diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml index 270fee076..515bd1696 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml @@ -125,6 +125,27 @@ spec: - OK - KeepLast type: string + notificationSettings: + properties: + group_by: + items: + type: string + type: array + group_interval: + type: string + group_wait: + type: string + mute_time_intervals: + items: + type: string + type: array + receiver: + type: string + repeat_interval: + type: string + required: + - receiver + type: object title: example: Always firing maxLength: 190 diff --git a/deploy/kustomize/base/crds.yaml b/deploy/kustomize/base/crds.yaml index 03d9dff91..37543db3d 100644 --- a/deploy/kustomize/base/crds.yaml +++ b/deploy/kustomize/base/crds.yaml @@ -124,6 +124,27 @@ spec: - OK - KeepLast type: string + notificationSettings: + properties: + group_by: + items: + type: string + type: array + group_interval: + type: string + group_wait: + type: string + mute_time_intervals: + items: + type: string + type: array + receiver: + type: string + repeat_interval: + type: string + required: + - receiver + type: object title: example: Always firing maxLength: 190 diff --git a/docs/docs/api.md b/docs/docs/api.md index 90a478dd0..fd36fe0c8 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -333,6 +333,13 @@ AlertRule defines a specific rule to be evaluated. It is based on the upstream m
false + + notificationSettings + object + +
+ + false @@ -431,6 +438,68 @@ relative time range +### GrafanaAlertRuleGroup.spec.rules[index].notificationSettings +[↩ Parent](#grafanaalertrulegroupspecrulesindex) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
receiverstring +
+
true
group_by[]string +
+
false
group_intervalstring +
+
false
group_waitstring +
+
false
mute_time_intervals[]string +
+
false
repeat_intervalstring +
+
false
+ + ### GrafanaAlertRuleGroup.status [↩ Parent](#grafanaalertrulegroup) diff --git a/go.mod b/go.mod index d4dd7d49e..d1e403d5c 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-logr/logr v1.4.1 github.com/go-openapi/strfmt v0.23.0 github.com/google/go-jsonnet v0.20.0 - github.com/grafana/grafana-openapi-client-go v0.0.0-20240215164046-eb0e60d27cb7 + github.com/grafana/grafana-openapi-client-go v0.0.0-20240430202104-3ad0f7e4ee52 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.33.1 github.com/openshift/api v3.9.0+incompatible @@ -26,20 +26,20 @@ require ( require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.22.2 // indirect + github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect - github.com/go-openapi/loads v0.21.5 // indirect - github.com/go-openapi/runtime v0.27.1 // indirect - github.com/go-openapi/spec v0.20.14 // indirect - github.com/go-openapi/validate v0.23.0 // indirect + github.com/go-openapi/loads v0.22.0 // indirect + github.com/go-openapi/runtime v0.28.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/validate v0.24.0 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/sync v0.6.0 // indirect ) @@ -52,9 +52,9 @@ require ( github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect; indirectn github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.9 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect diff --git a/go.sum b/go.sum index 812c4af06..cba38cb64 100644 --- a/go.sum +++ b/go.sum @@ -28,26 +28,26 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= -github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= +github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= +github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0= -github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8= -github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqvJYto= -github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU= -github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= -github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= +github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= +github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= +github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= -github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= -github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= -github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw= -github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSaEpHTJHtN5cbE= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= +github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -83,8 +83,8 @@ github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQN github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/grafana-openapi-client-go v0.0.0-20240215164046-eb0e60d27cb7 h1:3ckIV9HQ+g7ZF0EuFktYNxQP7h0p8ATwxOus0CfINGA= -github.com/grafana/grafana-openapi-client-go v0.0.0-20240215164046-eb0e60d27cb7/go.mod h1:J+/va7PHxPwcbwvoXlK6ZpocYuolEb0kht3IfALng9s= +github.com/grafana/grafana-openapi-client-go v0.0.0-20240430202104-3ad0f7e4ee52 h1:EBrKHk2URMJoT/xs+By+S+s92xsKNyyH7j8nrZFSCBY= +github.com/grafana/grafana-openapi-client-go v0.0.0-20240430202104-3ad0f7e4ee52/go.mod h1:hiZnMmXc9KXNUlvkV2BKFsiWuIFF/fF4wGgYWEjBitI= 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= @@ -155,14 +155,14 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=