From c0ca1e2ed6fc8f71b7edd1593af5596e28584eeb Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Fri, 17 Nov 2023 17:46:00 +0100 Subject: [PATCH 01/21] feat(pingdom): add post data field (#1) --- api/v1alpha1/endpointmonitor_types.go | 6 ++++ ...monitor.stakater.com_endpointmonitors.yaml | 7 +++++ docs/pingdom-configuration.md | 29 +++++++++++++++++++ pkg/monitors/pingdom/pingdom-monitor.go | 13 ++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/endpointmonitor_types.go b/api/v1alpha1/endpointmonitor_types.go index 48f241f3..80b65d9e 100644 --- a/api/v1alpha1/endpointmonitor_types.go +++ b/api/v1alpha1/endpointmonitor_types.go @@ -280,6 +280,12 @@ type PingdomConfig struct { // At this day your check will be considered down and if applicable a down alert will be sent. // +optional SSLDownDaysBefore int `json:"sslDownDaysBefore,omitempty"` + + // Data that should be posted to the web page, for example submission data for a sign-up or login form. + // The data needs to be formatted in the same way as a web browser would send it to the web server. + // Because post data contains sensitive secret this field is only reference to a environment variable. + // +optional + PostDataEnvVar string `json:"postDataEnvVar,omitempty"` } // AppInsightsConfig defines the configuration for AppInsights Monitor Provider diff --git a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml index 42d9e73c..50ccd782 100644 --- a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -88,6 +88,13 @@ spec: paused: description: Set to "true" to pause checks type: boolean + postDataEnvVar: + description: Data that should be posted to the web page, for example + submission data for a sign-up or login form. The data needs + to be formatted in the same way as a web browser would send + it to the web server. Because post data contains sensitive secret + this field is only reference to a environment variable. + type: string requestHeaders: description: Custom pingdom request headers type: string diff --git a/docs/pingdom-configuration.md b/docs/pingdom-configuration.md index 3f2d7f10..37059af0 100644 --- a/docs/pingdom-configuration.md +++ b/docs/pingdom-configuration.md @@ -44,6 +44,34 @@ Pingdom supports checks completing basic auth requirements. In `EndpointMonitor` For example; setting the field like `basicAuthUser: health-service` will set the username field to 'health-service' and will retrieve the password via `os.Getenv('health-service')` and set this appropriately. +### Post Data checks + +In case you need add post data to your request, you can use the field `postDataEnvVar`. +The value must match a environment variable that contains the post data to be sent. + +For example; setting the field like `postDataEnvVar: monitor-user` will set the post data field to the value of the environment variable `monitor-user`. + +To add the environment variable in helm context, first create a secret e.g. + +```yaml +kind: Secret +apiVersion: v1 +metadata: + name: stakater-post-data +stringData: + monitor-user: "username=stakater&password=stakater" +type: Opaque +``` + +Then we reference secret in the env context of helm chart + +```yaml +envFrom: + - secretRef: + name: stakater-post-data +``` + +If you set postData the request method will be automatically POST. ## Example: @@ -67,4 +95,5 @@ spec: alertIntegrations: "91166-12168" alertContacts: "1234567_8_9-9876543_2_1,1234567_8_9-9876543_2_2" teamAlertContacts: "1234567_8_9-9876543_2_1,1234567_8_9-9876543_2_2" + postDataEnvVar: "monitor-user" ``` diff --git a/pkg/monitors/pingdom/pingdom-monitor.go b/pkg/monitors/pingdom/pingdom-monitor.go index c8b54184..e4312cf0 100644 --- a/pkg/monitors/pingdom/pingdom-monitor.go +++ b/pkg/monitors/pingdom/pingdom-monitor.go @@ -2,6 +2,7 @@ package pingdom import ( "encoding/json" + "errors" "fmt" "net/url" "os" @@ -258,9 +259,19 @@ func (service *PingdomMonitorService) addConfigToHttpCheck(httpCheck *pingdom.Ht } } - // Enable SSL validation if providerConfig != nil { + // Enable SSL validation httpCheck.VerifyCertificate = &providerConfig.VerifyCertificate + // Add post data if exists + if len(providerConfig.PostDataEnvVar) > 0 { + postDataValue := os.Getenv(providerConfig.PostDataEnvVar) + if postDataValue != "" { + httpCheck.PostData = postDataValue + log.Info("Post data detected. Setting post data for httpCheck to value of environment variable: " + providerConfig.PostDataEnvVar) + } else { + log.Error(errors.New("Error reading post data from environment variable"), "Environment Variable %s does not exist", providerConfig.PostDataEnvVar) + } + } } // Set certificate not valid before, default to 28 days to accommodate Let's Encrypt 30 day renewals + 2 days grace period. From 6efde90258d299b958d4bbb495ab6fbc35d15ee6 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Thu, 18 Jan 2024 00:33:11 +0100 Subject: [PATCH 02/21] feat: add pingdom transaction checks --- api/v1alpha1/endpointmonitor_types.go | 43 +++++++++++++++++++++++++++ go.mod | 5 ++-- go.sum | 9 ++++-- pkg/monitors/monitor-proxy.go | 4 +++ pkg/util/util.go | 14 +++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/api/v1alpha1/endpointmonitor_types.go b/api/v1alpha1/endpointmonitor_types.go index 80b65d9e..e0aa06c9 100644 --- a/api/v1alpha1/endpointmonitor_types.go +++ b/api/v1alpha1/endpointmonitor_types.go @@ -18,6 +18,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" ) // EndpointMonitorSpec defines the desired state of EndpointMonitor @@ -60,6 +61,10 @@ type EndpointMonitorSpec struct { // +optional PingdomConfig *PingdomConfig `json:"pingdomConfig,omitempty"` + // Configuration for Pingdom Monitor Provider + // +optional + PingdomTransactionConfig *PingdomConfig `json:"pingdomTransactionConfig,omitempty"` + // Configuration for AppInsights Monitor Provider // +optional AppInsightsConfig *AppInsightsConfig `json:"appInsightsConfig,omitempty"` @@ -288,6 +293,44 @@ type PingdomConfig struct { PostDataEnvVar string `json:"postDataEnvVar,omitempty"` } +type PingdomTransactionConfig struct { + // Check status: active or inactive + // +optional + Paused bool `json:"paused,omitempty"` + // Custom message that is part of the email and webhook alerts + // +optional + CustomMessage string `json:"custom_message,omitempty"` + // TMS test intervals in minutes. Allowed intervals: 5,10,20,60,720,1440. The interval you're allowed to set may vary depending on your current plan. + // +optional + Interval int `json:"interval,omitempty"` + // Name of the region where the check is executed. Supported regions: us-east, us-west, eu, au + // +optional + Region string `json:"region,omitempty"` + // Send notification when down X times + SendNotificationWhenDown int64 `json:"send_notification_when_down,omitempty"` + // Check importance- how important are the alerts when the check fails. Allowed values: low, high + // +optional + SeverityLevel string `json:"severity_level,omitempty"` + // steps to be executed as part of the check + // +required + Steps []pingdomNew.Step `json:"steps"` + // Integration identifiers. + // +optional + Metadata pingdomNew.Metadata `json:"metadata,omitempty"` + // List of tags for a check. The tag name may contain the characters 'A-Z', 'a-z', '0-9', '_' and '-'. The maximum length of a tag is 64 characters. + Tags []string `json:"tags,omitempty"` + + // `-` separated set list of integrations ids (e.g. "91166-12168") + // +optional + AlertIntegrations string `json:"alertIntegrations,omitempty"` + // `-` separated contact id's (e.g. "1234567_8_9-9876543_2_1") + // +optional + AlertContacts string `json:"alertContacts,omitempty"` + // `-` separated team id's (e.g. "1234567_8_9-9876543_2_1") + // +optional + TeamAlertContacts string `json:"teamAlertContacts,omitempty"` +} + // AppInsightsConfig defines the configuration for AppInsights Monitor Provider type AppInsightsConfig struct { // Returned status code that is counted as a success diff --git a/go.mod b/go.mod index 1da81442..024a0e8c 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-logr/logr v1.2.0 github.com/grafana/synthetic-monitoring-agent v0.18.2 github.com/grafana/synthetic-monitoring-api-go-client v0.7.0 + github.com/karlderkaefer/pingdom-golang-client v1.0.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/openshift/api v0.0.0-20200526144822-34f54f12813a github.com/patrickmn/go-cache v2.1.0+incompatible @@ -62,13 +63,13 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/s2a-go v0.1.4 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/go.sum b/go.sum index 818700f7..fe88f962 100644 --- a/go.sum +++ b/go.sum @@ -316,8 +316,8 @@ github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkj github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -391,6 +391,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/karlderkaefer/pingdom-golang-client v1.0.0 h1:7RGD7gj8dJrXXjE9JgzHvGC424lXCbHXCGPBmtGKfkE= +github.com/karlderkaefer/pingdom-golang-client v1.0.0/go.mod h1:iHOA8APTy8wxam3QxKp/nGw9823gDIlMEpYiKp9+nrU= 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -415,8 +417,9 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN 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.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= diff --git a/pkg/monitors/monitor-proxy.go b/pkg/monitors/monitor-proxy.go index 1c70369b..9ad77974 100644 --- a/pkg/monitors/monitor-proxy.go +++ b/pkg/monitors/monitor-proxy.go @@ -33,6 +33,8 @@ func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy { mp.monitor = &uptimerobot.UpTimeMonitorService{} case "Pingdom": mp.monitor = &pingdom.PingdomMonitorService{} + case "PindomTransaction": + mp.monitor = &pingdom.PingdomTransactionMonitorService{} case "StatusCake": mp.monitor = &statuscake.StatusCakeMonitorService{} case "Uptime": @@ -59,6 +61,8 @@ func (mp *MonitorServiceProxy) ExtractConfig(spec endpointmonitorv1alpha1.Endpoi config = spec.UptimeRobotConfig case "Pingdom": config = spec.PingdomConfig + case "PingdomTransaction": + config = spec.PingdomTransactionConfig case "StatusCake": config = spec.StatusCakeConfig case "Uptime": diff --git a/pkg/util/util.go b/pkg/util/util.go index ba6e122d..1497b236 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -20,6 +20,20 @@ func SliceAtoi(stringSlice []string) ([]int, error) { return intSlice, nil } +func SliceAtoi64(stringSlice []string) ([]int64, error) { + var intSlice = []int64{} + + for _, stringValue := range stringSlice { + intValue, err := strconv.ParseInt(stringValue, 10, 64) + if err != nil { + return intSlice, err + } + intSlice = append(intSlice, intValue) + } + + return intSlice, nil +} + func SliceItoa(intSlice []int) []string { var stringSlice = []string{} From 2c0ed347ad3f27d01d912781ee400d9d620dd995 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Thu, 18 Jan 2024 00:33:37 +0100 Subject: [PATCH 03/21] feat: add pingdom transaction checks --- .../pingdom/pingdom-transaction-monitor.go | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 pkg/monitors/pingdom/pingdom-transaction-monitor.go diff --git a/pkg/monitors/pingdom/pingdom-transaction-monitor.go b/pkg/monitors/pingdom/pingdom-transaction-monitor.go new file mode 100644 index 00000000..bd6f448c --- /dev/null +++ b/pkg/monitors/pingdom/pingdom-transaction-monitor.go @@ -0,0 +1,203 @@ +package pingdom + +import ( + "context" + "fmt" + "os" + "strconv" + "strings" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + + "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/client/ptr" + pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" + endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" + "github.com/stakater/IngressMonitorController/v2/pkg/config" + "github.com/stakater/IngressMonitorController/v2/pkg/models" + "github.com/stakater/IngressMonitorController/v2/pkg/util" +) + +var logT = logf.Log.WithName("pingdom-transcation") + +// PingdomTransactionMonitorService interfaces with MonitorService +type PingdomTransactionMonitorService struct { + apiToken string + url string + alertContacts string + alertIntegrations string + teamAlertContacts string + client *pingdomNew.APIClient + context context.Context +} + +func (monitor *PingdomTransactionMonitorService) Equal(oldMonitor models.Monitor, newMonitor models.Monitor) bool { + // TODO: Retrieve oldMonitor config and compare it here + return false +} + +func (service *PingdomTransactionMonitorService) Setup(p config.Provider) { + service.apiToken = p.ApiToken + service.url = p.ApiURL + service.alertContacts = p.AlertContacts + service.alertIntegrations = p.AlertIntegrations + service.teamAlertContacts = p.TeamAlertContacts + + cfg := pingdomNew.NewConfiguration() + if service.apiToken == "" { + service.apiToken = os.Getenv("PINGDOM_API_TOKEN") + } + cfg.SetApiToken(service.apiToken) + service.client = pingdomNew.NewAPIClient(cfg) + service.context = context.Background() +} + +func (service *PingdomTransactionMonitorService) GetByName(name string) (*models.Monitor, error) { + var match *models.Monitor + + monitors := service.GetAll() + for _, mon := range monitors { + if mon.Name == name { + return &mon, nil + } + } + + return match, fmt.Errorf("Unable to locate monitor with name %v", name) +} + +func (service *PingdomTransactionMonitorService) GetAll() []models.Monitor { + var monitors []models.Monitor + checks, _, err := service.client.TMSChecksAPI.GetAllChecks(service.context).Type_("script").Execute() + if err != nil { + logT.Error(err, "Error getting all transaction checks") + return monitors + } + if checks == nil { + return monitors + } + for _, mon := range checks.GetChecks() { + newMon := models.Monitor{ + ID: fmt.Sprintf("%d", mon.Id), + Name: *mon.Name, + } + monitors = append(monitors, newMon) + } + + return monitors +} + +func (service *PingdomTransactionMonitorService) Add(m models.Monitor) { + transactionCheck := service.createTransactionCheck(m) + _, _, err := service.client.TMSChecksAPI.AddCheck(service.context).CheckWithoutID(transactionCheck).Execute() + if err != nil { + logT.Info("Error Adding Pingdom Transaction Monitor: " + err.Error()) + } else { + logT.Info("Added monitor for: " + m.Name) + } +} + +func (service *PingdomTransactionMonitorService) Update(m models.Monitor) { + transactionCheck := service.createTransactionCheck(m) + monitorID := strToInt64(m.ID) + _, _, err := service.client.TMSChecksAPI.ModifyCheck(context.Background(), monitorID).CheckWithoutIDPUT(*transactionCheck.AsPut()).Execute() + if err != nil { + logT.Info("Error updating Monitor: " + err.Error()) + return + } + logT.Info(fmt.Sprintf("Updated Pingdom Transaction Monitor: %s", m.Name)) +} + +func (service *PingdomTransactionMonitorService) Remove(m models.Monitor) { + _, resp, err := service.client.TMSChecksAPI.DeleteCheck(context.Background(), strToInt64(m.ID)).Execute() + if err != nil { + logT.Info("Error deleting Monitor: " + err.Error()) + } else { + logT.Info(fmt.Sprintf("Delete Monitor: %v", resp)) + } +} + +func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor models.Monitor) pingdomNew.CheckWithoutID { + transactionCheck := pingdomNew.CheckWithoutID{} + transactionCheck.Name = monitor.Name + + userIds := parseIDs(service.alertContacts) + if userIds != nil { + transactionCheck.ContactIds = userIds + } + integrationIds := parseIDs(service.alertIntegrations) + if integrationIds != nil { + transactionCheck.IntegrationIds = integrationIds + } + teamAlertContacts := parseIDs(service.teamAlertContacts) + if teamAlertContacts != nil { + transactionCheck.TeamIds = teamAlertContacts + } + service.addConfigToHttpCheck(&transactionCheck, monitor.Config) + + return transactionCheck +} + +func (service *PingdomTransactionMonitorService) addConfigToHttpCheck(transactionCheck *pingdomNew.CheckWithoutID, config interface{}) { + + // Retrieve provider configuration + providerConfig, _ := config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) + + if providerConfig == nil { + logT.Info("Error retrieving provider configuration for Pingdom Transaction Monitor") + return + } + + // Set contact ids + userIds := parseIDs(providerConfig.AlertContacts) + if userIds != nil { + transactionCheck.ContactIds = userIds + } + teamAlertContacts := parseIDs(providerConfig.TeamAlertContacts) + if teamAlertContacts != nil { + transactionCheck.TeamIds = teamAlertContacts + } + integrationIds := parseIDs(providerConfig.AlertIntegrations) + if integrationIds != nil { + transactionCheck.IntegrationIds = integrationIds + } + + // Set transaction check configuration + if providerConfig.CustomMessage != "" { + transactionCheck.CustomMessage = ptr.String(providerConfig.CustomMessage) + } + if providerConfig.Region != "" { + transactionCheck.Region = ptr.String(providerConfig.Region) + } + if providerConfig.SendNotificationWhenDown > 0 { + transactionCheck.SendNotificationWhenDown = ptr.Int64(providerConfig.SendNotificationWhenDown) + } + if providerConfig.Paused { + transactionCheck.Active = ptr.Bool(!providerConfig.Paused) + } + if len(providerConfig.Tags) > 0 { + transactionCheck.Tags = providerConfig.Tags + } +} + +// parseIDs splits a string of IDs into an array of integers +func parseIDs(field string) []int64 { + if len(field) > 0 { + stringArray := strings.Split(field, "-") + ids, err := util.SliceAtoi64(stringArray) + if err != nil { + logT.Info("Error decoding ids into integers" + err.Error()) + return nil + } + return ids + } + return nil +} + +func strToInt64(str string) int64 { + // Parse the string as a base-10 integer with a bit size of 64. + value, err := strconv.ParseInt(str, 10, 64) + if err != nil { + logT.Error(err, "Error converting string to int64") + return 0 + } + return value +} From 295032acc0ca0cd736fe51da98bdc1895d7a5c83 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Thu, 18 Jan 2024 12:47:17 +0100 Subject: [PATCH 04/21] feat: generate crds --- api/v1alpha1/endpointmonitor_types.go | 35 +++++++-- api/v1alpha1/zz_generated.deepcopy.go | 54 ++++++++++++++ ...monitor.stakater.com_endpointmonitors.yaml | 74 +++++++++++++++++++ pkg/monitors/monitor-proxy.go | 3 +- .../pingdom-transaction-monitor.go | 4 +- pkg/util/util.go | 18 ++--- 6 files changed, 170 insertions(+), 18 deletions(-) rename pkg/monitors/{pingdom => pingdomtransaction}/pingdom-transaction-monitor.go (98%) diff --git a/api/v1alpha1/endpointmonitor_types.go b/api/v1alpha1/endpointmonitor_types.go index d360f42c..dfb8eb35 100644 --- a/api/v1alpha1/endpointmonitor_types.go +++ b/api/v1alpha1/endpointmonitor_types.go @@ -18,7 +18,6 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" ) // EndpointMonitorSpec defines the desired state of EndpointMonitor @@ -63,7 +62,7 @@ type EndpointMonitorSpec struct { // Configuration for Pingdom Monitor Provider // +optional - PingdomTransactionConfig *PingdomConfig `json:"pingdomTransactionConfig,omitempty"` + PingdomTransactionConfig *PingdomTransactionConfig `json:"pingdomTransactionConfig,omitempty"` // Configuration for AppInsights Monitor Provider // +optional @@ -286,50 +285,74 @@ type PingdomConfig struct { // +optional SSLDownDaysBefore int `json:"sslDownDaysBefore,omitempty"` + // Data that should be posted to the web page, for example submission data for a sign-up or login form. // The data needs to be formatted in the same way as a web browser would send it to the web server. // Because post data contains sensitive secret this field is only reference to a environment variable. // +optional PostDataEnvVar string `json:"postDataEnvVar,omitempty"` } +// PingdomTransactionConfig defines the configuration for Pingdom Transaction Monitor Provider type PingdomTransactionConfig struct { + // Check status: active or inactive // +optional Paused bool `json:"paused,omitempty"` + // Custom message that is part of the email and webhook alerts // +optional CustomMessage string `json:"custom_message,omitempty"` + // TMS test intervals in minutes. Allowed intervals: 5,10,20,60,720,1440. The interval you're allowed to set may vary depending on your current plan. // +optional Interval int `json:"interval,omitempty"` + // Name of the region where the check is executed. Supported regions: us-east, us-west, eu, au // +optional Region string `json:"region,omitempty"` + // Send notification when down X times SendNotificationWhenDown int64 `json:"send_notification_when_down,omitempty"` + // Check importance- how important are the alerts when the check fails. Allowed values: low, high // +optional SeverityLevel string `json:"severity_level,omitempty"` + // steps to be executed as part of the check // +required - Steps []pingdomNew.Step `json:"steps"` - // Integration identifiers. - // +optional - Metadata pingdomNew.Metadata `json:"metadata,omitempty"` + Steps []PingdomStep `json:"steps"` + // List of tags for a check. The tag name may contain the characters 'A-Z', 'a-z', '0-9', '_' and '-'. The maximum length of a tag is 64 characters. Tags []string `json:"tags,omitempty"` // `-` separated set list of integrations ids (e.g. "91166-12168") // +optional AlertIntegrations string `json:"alertIntegrations,omitempty"` + // `-` separated contact id's (e.g. "1234567_8_9-9876543_2_1") // +optional AlertContacts string `json:"alertContacts,omitempty"` + // `-` separated team id's (e.g. "1234567_8_9-9876543_2_1") // +optional TeamAlertContacts string `json:"teamAlertContacts,omitempty"` } +// PingdomStep respresents a step of the script to run a transcaction check +type PingdomStep struct { + // contains the html element with assigned value + // the key element is always lowercase for example {"url": "https://www.pingdom.com"} + // see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg + // +required + Args map[string]string `json:"args"` + // contains the function that is executed as part of the step + // commands: go_to, click, fill, check, uncheck, sleep, select_radio, basic_auth, submit, wait_for_element, wait_for_contains + // validations: url, exists, not_exists, contains, not_contains, field_contains, field_not_contains, is_checked, is_not_checked, radio_selected, dropdown_selected, dropdown_not_selected + // see updated list https://docs.pingdom.com/api/#section/TMS-Steps-Vocabulary/Script-transaction-checks + // +required + Function string `json:"function"` +} + // AppInsightsConfig defines the configuration for AppInsights Monitor Provider type AppInsightsConfig struct { // Returned status code that is counted as a success diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 7306291c..6ca91e75 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -132,6 +132,11 @@ func (in *EndpointMonitorSpec) DeepCopyInto(out *EndpointMonitorSpec) { *out = new(PingdomConfig) **out = **in } + if in.PingdomTransactionConfig != nil { + in, out := &in.PingdomTransactionConfig, &out.PingdomTransactionConfig + *out = new(PingdomTransactionConfig) + (*in).DeepCopyInto(*out) + } if in.AppInsightsConfig != nil { in, out := &in.AppInsightsConfig, &out.AppInsightsConfig *out = new(AppInsightsConfig) @@ -234,6 +239,55 @@ func (in *PingdomConfig) DeepCopy() *PingdomConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PingdomStep) DeepCopyInto(out *PingdomStep) { + *out = *in + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingdomStep. +func (in *PingdomStep) DeepCopy() *PingdomStep { + if in == nil { + return nil + } + out := new(PingdomStep) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PingdomTransactionConfig) DeepCopyInto(out *PingdomTransactionConfig) { + *out = *in + if in.Steps != nil { + in, out := &in.Steps, &out.Steps + *out = make([]PingdomStep, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingdomTransactionConfig. +func (in *PingdomTransactionConfig) DeepCopy() *PingdomTransactionConfig { + if in == nil { + return nil + } + out := new(PingdomTransactionConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RouteURLSource) DeepCopyInto(out *RouteURLSource) { *out = *in diff --git a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml index 5367c583..2d547594 100644 --- a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -130,6 +130,80 @@ spec: HTTP checks. type: boolean type: object + pingdomTransactionConfig: + description: Configuration for Pingdom Monitor Provider + properties: + alertContacts: + description: '`-` separated contact id''s (e.g. "1234567_8_9-9876543_2_1")' + type: string + alertIntegrations: + description: '`-` separated set list of integrations ids (e.g. + "91166-12168")' + type: string + custom_message: + description: Custom message that is part of the email and webhook + alerts + type: string + interval: + description: 'TMS test intervals in minutes. Allowed intervals: + 5,10,20,60,720,1440. The interval you''re allowed to set may + vary depending on your current plan.' + type: integer + paused: + description: 'Check status: active or inactive' + type: boolean + region: + description: 'Name of the region where the check is executed. + Supported regions: us-east, us-west, eu, au' + type: string + send_notification_when_down: + description: Send notification when down X times + format: int64 + type: integer + severity_level: + description: 'Check importance- how important are the alerts when + the check fails. Allowed values: low, high' + type: string + steps: + description: steps to be executed as part of the check + items: + description: PingdomStep respresents a step of the script to + run a transcaction check + properties: + args: + additionalProperties: + type: string + description: 'contains the html element with assigned value + the key element is always lowercase for example {"url": + "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg' + type: object + function: + description: 'contains the function that is executed as + part of the step commands: go_to, click, fill, check, + uncheck, sleep, select_radio, basic_auth, submit, wait_for_element, + wait_for_contains validations: url, exists, not_exists, + contains, not_contains, field_contains, field_not_contains, + is_checked, is_not_checked, radio_selected, dropdown_selected, + dropdown_not_selected see updated list https://docs.pingdom.com/api/#section/TMS-Steps-Vocabulary/Script-transaction-checks' + type: string + required: + - args + - function + type: object + type: array + tags: + description: List of tags for a check. The tag name may contain + the characters 'A-Z', 'a-z', '0-9', '_' and '-'. The maximum + length of a tag is 64 characters. + items: + type: string + type: array + teamAlertContacts: + description: '`-` separated team id''s (e.g. "1234567_8_9-9876543_2_1")' + type: string + required: + - steps + type: object providers: description: Comma separated list of providers type: string diff --git a/pkg/monitors/monitor-proxy.go b/pkg/monitors/monitor-proxy.go index 9ad77974..cf4e6fa9 100644 --- a/pkg/monitors/monitor-proxy.go +++ b/pkg/monitors/monitor-proxy.go @@ -8,6 +8,7 @@ import ( "github.com/stakater/IngressMonitorController/v2/pkg/monitors/gcloud" "github.com/stakater/IngressMonitorController/v2/pkg/monitors/grafana" "github.com/stakater/IngressMonitorController/v2/pkg/monitors/pingdom" + "github.com/stakater/IngressMonitorController/v2/pkg/monitors/pingdomtransaction" "github.com/stakater/IngressMonitorController/v2/pkg/monitors/statuscake" "github.com/stakater/IngressMonitorController/v2/pkg/monitors/updown" "github.com/stakater/IngressMonitorController/v2/pkg/monitors/uptime" @@ -34,7 +35,7 @@ func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy { case "Pingdom": mp.monitor = &pingdom.PingdomMonitorService{} case "PindomTransaction": - mp.monitor = &pingdom.PingdomTransactionMonitorService{} + mp.monitor = &pingdomtransaction.PingdomTransactionMonitorService{} case "StatusCake": mp.monitor = &statuscake.StatusCakeMonitorService{} case "Uptime": diff --git a/pkg/monitors/pingdom/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go similarity index 98% rename from pkg/monitors/pingdom/pingdom-transaction-monitor.go rename to pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index bd6f448c..af7707e1 100644 --- a/pkg/monitors/pingdom/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -1,4 +1,4 @@ -package pingdom +package pingdomtransaction import ( "context" @@ -61,7 +61,7 @@ func (service *PingdomTransactionMonitorService) GetByName(name string) (*models } } - return match, fmt.Errorf("Unable to locate monitor with name %v", name) + return match, fmt.Errorf("unable to locate monitor with name %v", name) } func (service *PingdomTransactionMonitorService) GetAll() []models.Monitor { diff --git a/pkg/util/util.go b/pkg/util/util.go index 1497b236..769db2c4 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -21,17 +21,17 @@ func SliceAtoi(stringSlice []string) ([]int, error) { } func SliceAtoi64(stringSlice []string) ([]int64, error) { - var intSlice = []int64{} + var intSlice = []int64{} - for _, stringValue := range stringSlice { - intValue, err := strconv.ParseInt(stringValue, 10, 64) - if err != nil { - return intSlice, err - } - intSlice = append(intSlice, intValue) - } + for _, stringValue := range stringSlice { + intValue, err := strconv.ParseInt(stringValue, 10, 64) + if err != nil { + return intSlice, err + } + intSlice = append(intSlice, intValue) + } - return intSlice, nil + return intSlice, nil } func SliceItoa(intSlice []int) []string { From eaf216e3119fd4524f7800b712e12829c060b9d0 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Thu, 18 Jan 2024 13:10:50 +0100 Subject: [PATCH 05/21] feat: add mapping for step args --- .../pingdom-transaction-monitor.go | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index af7707e1..eda78b3b 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -2,6 +2,7 @@ package pingdomtransaction import ( "context" + "encoding/json" "fmt" "os" "strconv" @@ -131,12 +132,12 @@ func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor if teamAlertContacts != nil { transactionCheck.TeamIds = teamAlertContacts } - service.addConfigToHttpCheck(&transactionCheck, monitor.Config) + service.addConfigToTranscationCheck(&transactionCheck, monitor.Config) return transactionCheck } -func (service *PingdomTransactionMonitorService) addConfigToHttpCheck(transactionCheck *pingdomNew.CheckWithoutID, config interface{}) { +func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(transactionCheck *pingdomNew.CheckWithoutID, config interface{}) { // Retrieve provider configuration providerConfig, _ := config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) @@ -176,6 +177,37 @@ func (service *PingdomTransactionMonitorService) addConfigToHttpCheck(transactio if len(providerConfig.Tags) > 0 { transactionCheck.Tags = providerConfig.Tags } + if providerConfig.SeverityLevel != "" { + transactionCheck.SeverityLevel = ptr.String(providerConfig.SeverityLevel) + } + for _, step := range providerConfig.Steps { + args := NewStepArgsByMap(step.Args) + if args != nil { + transactionCheck.Steps = append(transactionCheck.Steps, pingdomNew.Step{ + Args: args, + Fn: ptr.String(step.Function), + }) + } else { + logT.Info("Invalid Pingdom Step Args Provided") + } + } +} + +// NewStepArgsByMap creates a new StepArgs object from a map +func NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { + // First, marshal the map to JSON + jsonData, err := json.Marshal(input) + if err != nil { + logT.Info("Error marshalling map to JSON" + err.Error()) + return nil + } + var stepArgs pingdomNew.StepArgs + err = json.Unmarshal(jsonData, &stepArgs) + if err != nil { + logT.Info("Error unmarshalling JSON to StepArgs" + err.Error()) + return nil + } + return &stepArgs } // parseIDs splits a string of IDs into an array of integers From 1e26926436d50c5cbf112417bbffe23dc285c98e Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 14:46:49 +0100 Subject: [PATCH 06/21] feat: support multiple providers --- api/v1alpha1/endpointmonitor_types.go | 5 +- ...monitor.stakater.com_endpointmonitors.yaml | 17 ++- docs/pingdom-configuration.md | 16 +++ .../test-config-pingdom-transaction.yaml | 5 + go.mod | 9 +- go.sum | 32 +++-- pkg/controllers/endpointmonitor_controller.go | 83 ++++++++++--- pkg/controllers/endpointmonitor_created.go | 5 +- pkg/controllers/endpointmonitor_deleted.go | 19 +-- pkg/controllers/endpointmonitor_updated.go | 2 +- pkg/controllers/endpointmonitor_util.go | 14 ++- pkg/monitors/monitor-proxy.go | 111 ++++++++++-------- pkg/monitors/monitor-service.go | 14 ++- .../pingdom-transaction-monitor.go | 108 +++++++++++++---- .../pingdom-transaction-monitor_test.go | 92 +++++++++++++++ 15 files changed, 414 insertions(+), 118 deletions(-) create mode 100644 examples/configs/test-config-pingdom-transaction.yaml create mode 100644 pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go diff --git a/api/v1alpha1/endpointmonitor_types.go b/api/v1alpha1/endpointmonitor_types.go index dfb8eb35..27ceb5a2 100644 --- a/api/v1alpha1/endpointmonitor_types.go +++ b/api/v1alpha1/endpointmonitor_types.go @@ -60,7 +60,7 @@ type EndpointMonitorSpec struct { // +optional PingdomConfig *PingdomConfig `json:"pingdomConfig,omitempty"` - // Configuration for Pingdom Monitor Provider + // Configuration for Pingdom Transaction Monitor Provider // +optional PingdomTransactionConfig *PingdomTransactionConfig `json:"pingdomTransactionConfig,omitempty"` @@ -305,10 +305,12 @@ type PingdomTransactionConfig struct { // TMS test intervals in minutes. Allowed intervals: 5,10,20,60,720,1440. The interval you're allowed to set may vary depending on your current plan. // +optional + // +kubebuilder:validation:Enum=5;10;20;60;720;1440 Interval int `json:"interval,omitempty"` // Name of the region where the check is executed. Supported regions: us-east, us-west, eu, au // +optional + // +kubebuilder:validation:Enum=us-east;us-west;eu;au Region string `json:"region,omitempty"` // Send notification when down X times @@ -316,6 +318,7 @@ type PingdomTransactionConfig struct { // Check importance- how important are the alerts when the check fails. Allowed values: low, high // +optional + // +kubebuilder:validation:Enum=low;high SeverityLevel string `json:"severity_level,omitempty"` // steps to be executed as part of the check diff --git a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml index 2d547594..4b226131 100644 --- a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -131,7 +131,7 @@ spec: type: boolean type: object pingdomTransactionConfig: - description: Configuration for Pingdom Monitor Provider + description: Configuration for Pingdom Transaction Monitor Provider properties: alertContacts: description: '`-` separated contact id''s (e.g. "1234567_8_9-9876543_2_1")' @@ -148,6 +148,13 @@ spec: description: 'TMS test intervals in minutes. Allowed intervals: 5,10,20,60,720,1440. The interval you''re allowed to set may vary depending on your current plan.' + enum: + - 5 + - 10 + - 20 + - 60 + - 720 + - 1440 type: integer paused: description: 'Check status: active or inactive' @@ -155,6 +162,11 @@ spec: region: description: 'Name of the region where the check is executed. Supported regions: us-east, us-west, eu, au' + enum: + - us-east + - us-west + - eu + - au type: string send_notification_when_down: description: Send notification when down X times @@ -163,6 +175,9 @@ spec: severity_level: description: 'Check importance- how important are the alerts when the check fails. Allowed values: low, high' + enum: + - low + - high type: string steps: description: steps to be executed as part of the check diff --git a/docs/pingdom-configuration.md b/docs/pingdom-configuration.md index 37059af0..af3d619b 100644 --- a/docs/pingdom-configuration.md +++ b/docs/pingdom-configuration.md @@ -97,3 +97,19 @@ spec: teamAlertContacts: "1234567_8_9-9876543_2_1,1234567_8_9-9876543_2_2" postDataEnvVar: "monitor-user" ``` + +## Transaction Check + +**Example:** + +```yaml +apiVersion: endpointmonitor.stakater.com/v1alpha1 +kind: EndpointMonitor +metadata: + name: pingdom-transaction-check +spec: + pingdomTransactionConfig: + tags: + - "testing" + - "manual" +`````` diff --git a/examples/configs/test-config-pingdom-transaction.yaml b/examples/configs/test-config-pingdom-transaction.yaml new file mode 100644 index 00000000..9a16d6a3 --- /dev/null +++ b/examples/configs/test-config-pingdom-transaction.yaml @@ -0,0 +1,5 @@ +providers: + - name: PingdomTransaction + apiURL: https://api.pingdom.com/api/3.1 + apiToken: +enableMonitorDeletion: true diff --git a/go.mod b/go.mod index 392ebed5..c690c2d7 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-logr/logr v1.2.0 github.com/grafana/synthetic-monitoring-agent v0.18.2 github.com/grafana/synthetic-monitoring-api-go-client v0.7.0 - github.com/karlderkaefer/pingdom-golang-client v1.0.0 + github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11 github.com/kelseyhightower/envconfig v1.4.0 github.com/openshift/api v0.0.0-20200526144822-34f54f12813a github.com/patrickmn/go-cache v2.1.0+incompatible @@ -47,11 +47,13 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deepmap/oapi-codegen/v2 v2.0.0 // indirect github.com/dimchansky/utfbom v1.1.0 // indirect github.com/emicklei/go-restful v2.16.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/getkin/kin-openapi v0.118.0 // indirect github.com/go-logr/zapr v1.2.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect @@ -67,6 +69,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/imdario/mergo v0.3.12 // indirect + github.com/invopop/yaml v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -74,7 +77,9 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/perimeterx/marshmallow v1.1.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect @@ -87,6 +92,7 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect golang.org/x/crypto v0.17.0 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.16.0 // indirect golang.org/x/oauth2 v0.10.0 // indirect golang.org/x/sync v0.4.0 // indirect @@ -94,6 +100,7 @@ require ( golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + golang.org/x/tools v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/go.sum b/go.sum index 36bbc0c8..a911fd8b 100644 --- a/go.sum +++ b/go.sum @@ -155,6 +155,9 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ 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/deepmap/oapi-codegen v1.16.2 h1:xGHx0dNqYfy9gE8a7AVgVM8Sd5oF9SEgePzP+UPAUXI= +github.com/deepmap/oapi-codegen/v2 v2.0.0 h1:3TS7w3r+XnjKFXcbFbc16pTWzfTy0OLPkCsutEHjWDA= +github.com/deepmap/oapi-codegen/v2 v2.0.0/go.mod h1:7zR+ZL3WzLeCkr2k8oWTxEa0v8y/F25ane0l6A5UjLA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= @@ -165,7 +168,6 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb 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 v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -194,6 +196,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= +github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -232,6 +236,7 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -375,6 +380,8 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= +github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -395,6 +402,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/karlderkaefer/pingdom-golang-client v1.0.0 h1:7RGD7gj8dJrXXjE9JgzHvGC424lXCbHXCGPBmtGKfkE= github.com/karlderkaefer/pingdom-golang-client v1.0.0/go.mod h1:iHOA8APTy8wxam3QxKp/nGw9823gDIlMEpYiKp9+nrU= +github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11 h1:amVFXIUzG7BiGXDa6IVdEdroRF7PL2NrPVrqE21iZXs= +github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11/go.mod h1:iHOA8APTy8wxam3QxKp/nGw9823gDIlMEpYiKp9+nrU= 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -451,6 +460,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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= @@ -486,6 +497,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= +github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -588,6 +601,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -668,8 +683,6 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -709,6 +722,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -864,14 +879,10 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -885,8 +896,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -963,6 +972,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1077,8 +1088,6 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= -google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1127,6 +1136,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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 v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= diff --git a/pkg/controllers/endpointmonitor_controller.go b/pkg/controllers/endpointmonitor_controller.go index 3a560eb4..5587eb7d 100644 --- a/pkg/controllers/endpointmonitor_controller.go +++ b/pkg/controllers/endpointmonitor_controller.go @@ -30,16 +30,19 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/log" endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" ) +var log = logf.Log.WithName("endpointmonitor-controller") + // EndpointMonitorReconciler reconciles a EndpointMonitor object type EndpointMonitorReconciler struct { client.Client Log logr.Logger Scheme *runtime.Scheme - MonitorServices []monitors.MonitorServiceProxy + MonitorServices []*monitors.MonitorServiceProxy } //+kubebuilder:rbac:groups=endpointmonitor.stakater.com,resources=endpointmonitors,verbs=get;list;watch @@ -83,23 +86,25 @@ func (r *EndpointMonitorReconciler) Reconcile(ctx context.Context, req ctrl.Requ // Handle CreationDelay createTime := instance.CreationTimestamp delay := time.Until(createTime.Add(config.GetControllerConfig().CreationDelay)) - - for index := 0; index < len(r.MonitorServices); index++ { - monitor := findMonitorByName(r.MonitorServices[index], monitorName) - if monitor != nil { - // Monitor already exists, update if required - err = r.handleUpdate(req, instance, *monitor, r.MonitorServices[index]) - } else { - // Monitor doesn't exist, create monitor - if delay.Nanoseconds() > 0 { - // Requeue request to add creation delay - log.Info("Requeuing request to add monitor " + monitorName + " for " + fmt.Sprintf("%+v", config.GetControllerConfig().CreationDelay) + " seconds") - return reconcile.Result{RequeueAfter: delay}, nil - } - err = r.handleCreate(req, instance, monitorName, r.MonitorServices[index]) + log.Info("Debug all monitors", "monitors", r.MonitorServices) + + monitorService := r.GetMonitorOfType(instance.Spec) + monitor := findMonitorByName(monitorService, monitorName) + log.Info("Debug trying to find "+monitorName, "monitors", monitorService, "type", monitorService.GetType()) + log.Info("Debug got service", "spec", monitorService.ExtractConfig(instance.Spec)) + if monitor != nil { + // Monitor already exists, update if required + err = r.handleUpdate(req, instance, *monitor, monitorService) + } else { + // Monitor doesn't exist, create monitor + if delay.Nanoseconds() > 0 { + // Requeue request to add creation delay + log.Info("Requeuing request to add monitor " + monitorName + " for " + fmt.Sprintf("%+v", config.GetControllerConfig().CreationDelay) + " seconds") + return reconcile.Result{RequeueAfter: delay}, nil } + log.Info("Debug forced to add "+monitorName, "monitors", monitorService, "instance", instance) + err = r.handleCreate(req, instance, monitorName, monitorService) } - return reconcile.Result{RequeueAfter: config.ReconciliationRequeueTime}, err } @@ -109,3 +114,49 @@ func (r *EndpointMonitorReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&endpointmonitorv1alpha1.EndpointMonitor{}). Complete(r) } + +func (r *EndpointMonitorReconciler) GetMonitorOfType(spec endpointmonitorv1alpha1.EndpointMonitorSpec) *monitors.MonitorServiceProxy { + if len(r.MonitorServices) == 0 { + panic("No monitor services found") + } + if spec.PingdomTransactionConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypePingdomTransaction) + } + if spec.PingdomConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypePingdom) + } + if spec.UptimeRobotConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUptimeRobot) + } + if spec.StatusCakeConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeStatusCake) + } + if spec.UptimeConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUptime) + } + if spec.UpdownConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUpdown) + } + if spec.AppInsightsConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeAppInsights) + } + if spec.GCloudConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeGCloud) + } + if spec.GrafanaConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeGrafana) + } + // If none of the above, return the first monitor service + return r.MonitorServices[0] +} + + +func (r *EndpointMonitorReconciler) GetMonitorServiceOfType(monitorType string) *monitors.MonitorServiceProxy { + for _, monitorService := range r.MonitorServices { + if monitorService.GetType() == monitorType { + return monitorService + } + } + log.Info("Error could not find monitor service " + monitorType + " in list of monitor services") + return nil +} diff --git a/pkg/controllers/endpointmonitor_created.go b/pkg/controllers/endpointmonitor_created.go index 905e2508..5ebcff01 100644 --- a/pkg/controllers/endpointmonitor_created.go +++ b/pkg/controllers/endpointmonitor_created.go @@ -9,10 +9,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string, monitorService monitors.MonitorServiceProxy) error { +func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string, monitorService *monitors.MonitorServiceProxy) error { log := r.Log.WithValues("endpointMonitor", instance.ObjectMeta.Namespace) - log.Info("Creating Monitor: " + monitorName) + log.Info("Debug Creating Monitor: " + monitorName, "MonitorType", monitorService.GetType()) url, err := util.GetMonitorURL(r.Client, instance) if err != nil { @@ -24,6 +24,7 @@ func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, inst // Create monitor Model monitor := models.Monitor{Name: monitorName, URL: url, Config: providerConfig} + log.Info("Debug got Request to create monitor", "monitor", monitor) // Add monitor for provider monitorService.Add(monitor) diff --git a/pkg/controllers/endpointmonitor_deleted.go b/pkg/controllers/endpointmonitor_deleted.go index eb01a596..132f30d4 100644 --- a/pkg/controllers/endpointmonitor_deleted.go +++ b/pkg/controllers/endpointmonitor_deleted.go @@ -10,7 +10,6 @@ import ( func (r *EndpointMonitorReconciler) handleDelete(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string) (reconcile.Result, error) { log := r.Log.WithValues("endpointMonitor", request.Namespace) - if instance == nil { // Instance not found, nothing to do return reconcile.Result{}, nil @@ -21,23 +20,27 @@ func (r *EndpointMonitorReconciler) handleDelete(request reconcile.Request, inst return reconcile.Result{}, nil } - log.Info("Removing Monitor: " + monitorName) - - // Remove monitor if it exists - for index := 0; index < len(r.MonitorServices); index++ { - r.removeMonitorIfExists(r.MonitorServices[index], monitorName) + log.Info("Debug deleting monitor spec", "spec", instance.Spec) + // in case of multiple providers we need to iterate over all of them + monitorServices := findMonitorServicesThatContainsMonitor(r.MonitorServices, monitorName) + for _, monitorService := range monitorServices { + r.removeMonitorIfExists(monitorService, monitorName) + } + if len(monitorServices) < 1 { + log.Info("Cannot find monitor service that contains monitor: " + monitorName) + return reconcile.Result{}, nil } return reconcile.Result{}, nil } -func (r *EndpointMonitorReconciler) removeMonitorIfExists(monitorService monitors.MonitorServiceProxy, monitorName string) { +func (r *EndpointMonitorReconciler) removeMonitorIfExists(monitorService *monitors.MonitorServiceProxy, monitorName string) { log := r.Log.WithValues("monitor", monitorName) monitor, _ := monitorService.GetByName(monitorName) // Monitor Exists if monitor != nil { // Monitor Exists, remove the monitor - log.Info("Removing monitor with name: " + monitorName + " for provider: " + monitorService.GetType()) + log.Info("Removing monitor: " + monitorName + " from provider provider: " + monitorService.GetType()) monitorService.Remove(*monitor) } else { log.Info("Cannot find monitor with name: " + monitorName + " for provider: " + monitorService.GetType()) diff --git a/pkg/controllers/endpointmonitor_updated.go b/pkg/controllers/endpointmonitor_updated.go index 7f27e001..0d66d1c9 100644 --- a/pkg/controllers/endpointmonitor_updated.go +++ b/pkg/controllers/endpointmonitor_updated.go @@ -9,7 +9,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func (r *EndpointMonitorReconciler) handleUpdate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitor models.Monitor, monitorService monitors.MonitorServiceProxy) error { +func (r *EndpointMonitorReconciler) handleUpdate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitor models.Monitor, monitorService *monitors.MonitorServiceProxy) error { url, err := util.GetMonitorURL(r.Client, instance) if err != nil { return err diff --git a/pkg/controllers/endpointmonitor_util.go b/pkg/controllers/endpointmonitor_util.go index ebcbd3a0..ecbfceec 100644 --- a/pkg/controllers/endpointmonitor_util.go +++ b/pkg/controllers/endpointmonitor_util.go @@ -5,7 +5,7 @@ import ( "github.com/stakater/IngressMonitorController/v2/pkg/monitors" ) -func findMonitorByName(monitorService monitors.MonitorServiceProxy, monitorName string) *models.Monitor { +func findMonitorByName(monitorService *monitors.MonitorServiceProxy, monitorName string) *models.Monitor { monitor, _ := monitorService.GetByName(monitorName) // Monitor Exists @@ -14,3 +14,15 @@ func findMonitorByName(monitorService monitors.MonitorServiceProxy, monitorName } return nil } + +// findMonitorServiceThatContainsMonitor iterates over all monitor services and returns the one that contains the monitor +func findMonitorServicesThatContainsMonitor(monitorServices []*monitors.MonitorServiceProxy, monitorName string) []*monitors.MonitorServiceProxy { + var targetMonitorServices []*monitors.MonitorServiceProxy + for _, monitorService := range monitorServices { + monitor, _ := monitorService.GetByName(monitorName) + if monitor != nil { + targetMonitorServices = append(targetMonitorServices, monitorService) + } + } + return targetMonitorServices +} diff --git a/pkg/monitors/monitor-proxy.go b/pkg/monitors/monitor-proxy.go index cf4e6fa9..ca77b6ff 100644 --- a/pkg/monitors/monitor-proxy.go +++ b/pkg/monitors/monitor-proxy.go @@ -18,6 +18,18 @@ import ( var log = logf.Log.WithName("monitors") +const ( + TypeUptimeRobot = "UptimeRobot" + TypePingdom = "Pingdom" + TypePingdomTransaction = "PingdomTransaction" + TypeStatusCake = "StatusCake" + TypeUptime = "Uptime" + TypeUpdown = "Updown" + TypeAppInsights = "AppInsights" + TypeGCloud = "gcloud" + TypeGrafana = "Grafana" +) + type MonitorServiceProxy struct { monitorType string monitor MonitorService @@ -28,58 +40,59 @@ func (mp *MonitorServiceProxy) GetType() string { } func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy { - mp.monitorType = mType - switch mType { - case "UptimeRobot": - mp.monitor = &uptimerobot.UpTimeMonitorService{} - case "Pingdom": - mp.monitor = &pingdom.PingdomMonitorService{} - case "PindomTransaction": - mp.monitor = &pingdomtransaction.PingdomTransactionMonitorService{} - case "StatusCake": - mp.monitor = &statuscake.StatusCakeMonitorService{} - case "Uptime": - mp.monitor = &uptime.UpTimeMonitorService{} - case "Updown": - mp.monitor = &updown.UpdownMonitorService{} - case "AppInsights": - mp.monitor = &appinsights.AppinsightsMonitorService{} - case "gcloud": - mp.monitor = &gcloud.MonitorService{} - case "Grafana": - mp.monitor = &grafana.GrafanaMonitorService{} - default: - panic("No such provider found: " + mType) - } - return *mp + mp.monitorType = mType + switch mType { + case TypeUptimeRobot: + mp.monitor = &uptimerobot.UpTimeMonitorService{} + case TypePingdom: + mp.monitor = &pingdom.PingdomMonitorService{} + case TypePingdomTransaction: + mp.monitor = &pingdomtransaction.PingdomTransactionMonitorService{} + case TypeStatusCake: + mp.monitor = &statuscake.StatusCakeMonitorService{} + case TypeUptime: + mp.monitor = &uptime.UpTimeMonitorService{} + case TypeUpdown: + mp.monitor = &updown.UpdownMonitorService{} + case TypeAppInsights: + mp.monitor = &appinsights.AppinsightsMonitorService{} + case TypeGCloud: + mp.monitor = &gcloud.MonitorService{} + case TypeGrafana: + mp.monitor = &grafana.GrafanaMonitorService{} + default: + panic("No such provider found: " + mType) + } + return *mp } func (mp *MonitorServiceProxy) ExtractConfig(spec endpointmonitorv1alpha1.EndpointMonitorSpec) interface{} { - var config interface{} - - switch mp.monitorType { - case "UptimeRobot": - config = spec.UptimeRobotConfig - case "Pingdom": - config = spec.PingdomConfig - case "PingdomTransaction": - config = spec.PingdomTransactionConfig - case "StatusCake": - config = spec.StatusCakeConfig - case "Uptime": - config = spec.UptimeConfig - case "Updown": - config = spec.UpdownConfig - case "AppInsights": - config = spec.AppInsightsConfig - case "gcloud": - config = spec.GCloudConfig - case "Grafana": - config = spec.GrafanaConfig - default: - return config - } - return config + var config interface{} + log.Info("Debug Extracting config for monitor type: "+mp.monitorType, "MonitorSpec", spec) + switch mp.monitorType { + case TypeUptimeRobot: + config = spec.UptimeRobotConfig + case TypePingdom: + config = spec.PingdomConfig + case TypePingdomTransaction: + config = spec.PingdomTransactionConfig + case TypeStatusCake: + config = spec.StatusCakeConfig + case TypeUptime: + config = spec.UptimeConfig + case TypeUpdown: + config = spec.UpdownConfig + case TypeAppInsights: + config = spec.AppInsightsConfig + case TypeGCloud: + config = spec.GCloudConfig + case TypeGrafana: + config = spec.GrafanaConfig + default: + log.Info("Debug not specific Provider config found for monitor type: " + mp.monitorType, "MonitorSpec", spec) + return config + } + return config } func (mp *MonitorServiceProxy) Setup(p config.Provider) { diff --git a/pkg/monitors/monitor-service.go b/pkg/monitors/monitor-service.go index b1ff90d9..63496f7c 100644 --- a/pkg/monitors/monitor-service.go +++ b/pkg/monitors/monitor-service.go @@ -17,18 +17,20 @@ type MonitorService interface { Equal(oldMonitor models.Monitor, newMonitor models.Monitor) bool } -func CreateMonitorService(p *config.Provider) MonitorServiceProxy { +func CreateMonitorService(p *config.Provider) *MonitorServiceProxy { monitorService := (&MonitorServiceProxy{}).OfType(p.Name) + monitorService.monitorType = p.Name monitorService.Setup(*p) - return monitorService + log.Info("Debug Created Monitor Service for provider: " + p.Name) + return &monitorService } -func SetupMonitorServicesForProviders(providers []config.Provider) []MonitorServiceProxy { +func SetupMonitorServicesForProviders(providers []config.Provider) []*MonitorServiceProxy { if len(providers) < 1 { panic("Cannot Instantiate controller with no providers") } - monitorServices := []MonitorServiceProxy{} + monitorServices := []*MonitorServiceProxy{} for index := 0; index < len(providers); index++ { monitorServices = append(monitorServices, CreateMonitorService(&providers[index])) @@ -38,7 +40,7 @@ func SetupMonitorServicesForProviders(providers []config.Provider) []MonitorServ return monitorServices } -func SetupMonitorServicesForProvidersTest(providers []config.Provider) []MonitorServiceProxy { +func SetupMonitorServicesForProvidersTest(providers []config.Provider) []*MonitorServiceProxy { if len(providers) < 1 { panic("Cannot Instantiate controller with no providers") } @@ -46,7 +48,7 @@ func SetupMonitorServicesForProvidersTest(providers []config.Provider) []Monitor allowedProviders := []string{"UptimeRobot", "StatusCake"} log.Info("Setting up monitor services for tests(CRDs) for supported providers: " + strings.Join(allowedProviders[:], ",")) - monitorServices := []MonitorServiceProxy{} + monitorServices := []*MonitorServiceProxy{} for index := 0; index < len(providers); index++ { if contains(allowedProviders, providers[index].Name) { diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index eda78b3b..e7427e8b 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + "io" + "net/http" "os" "strconv" "strings" @@ -18,7 +20,7 @@ import ( "github.com/stakater/IngressMonitorController/v2/pkg/util" ) -var logT = logf.Log.WithName("pingdom-transcation") +var logT = logf.Log.WithName("pingdom-transaction") // PingdomTransactionMonitorService interfaces with MonitorService type PingdomTransactionMonitorService struct { @@ -72,52 +74,82 @@ func (service *PingdomTransactionMonitorService) GetAll() []models.Monitor { logT.Error(err, "Error getting all transaction checks") return monitors } + if checks == nil { return monitors } for _, mon := range checks.GetChecks() { newMon := models.Monitor{ - ID: fmt.Sprintf("%d", mon.Id), + URL: service.GetUrlFromSteps(*mon.Id), + ID: fmt.Sprintf("%v", *mon.Id), Name: *mon.Name, } monitors = append(monitors, newMon) } - return monitors } +func (service *PingdomTransactionMonitorService) GetUrlFromSteps(id int64) string { + check, _, err := service.client.TMSChecksAPI.GetCheck(service.context, id).Execute() + if err != nil { + logT.Error(err, "Error getting transaction check") + return "" + } + if check == nil { + return "" + } + for _, step := range check.GetSteps() { + if step.GetFn() == "go_to" { + return *step.GetArgs().Url + } + } + return "" +} + func (service *PingdomTransactionMonitorService) Add(m models.Monitor) { transactionCheck := service.createTransactionCheck(m) - _, _, err := service.client.TMSChecksAPI.AddCheck(service.context).CheckWithoutID(transactionCheck).Execute() + if transactionCheck == nil { + return + } + _, resp, err := service.client.TMSChecksAPI.AddCheck(service.context).CheckWithoutID(*transactionCheck).Execute() if err != nil { - logT.Info("Error Adding Pingdom Transaction Monitor: " + err.Error()) + logT.Error(err, "Error Adding Pingdom Transaction Monitor " + m.Name, "Response", parseResponseBody(resp)) } else { - logT.Info("Added monitor for: " + m.Name) + logT.Info("Added Pingdom Transaction Monitor Monitor " + m.Name) } } func (service *PingdomTransactionMonitorService) Update(m models.Monitor) { transactionCheck := service.createTransactionCheck(m) + if transactionCheck == nil { + return + } monitorID := strToInt64(m.ID) - _, _, err := service.client.TMSChecksAPI.ModifyCheck(context.Background(), monitorID).CheckWithoutIDPUT(*transactionCheck.AsPut()).Execute() + _, resp, err := service.client.TMSChecksAPI.ModifyCheck(service.context, monitorID).CheckWithoutIDPUT(*transactionCheck.AsPut()).Execute() if err != nil { - logT.Info("Error updating Monitor: " + err.Error()) + logT.Error(err, "Error Updating Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) return } - logT.Info(fmt.Sprintf("Updated Pingdom Transaction Monitor: %s", m.Name)) + logT.Info("Updated Pingdom Transaction Monitor Monitor " + m.Name) } func (service *PingdomTransactionMonitorService) Remove(m models.Monitor) { - _, resp, err := service.client.TMSChecksAPI.DeleteCheck(context.Background(), strToInt64(m.ID)).Execute() + _, resp, err := service.client.TMSChecksAPI.DeleteCheck(service.context, strToInt64(m.ID)).Execute() if err != nil { - logT.Info("Error deleting Monitor: " + err.Error()) + logT.Error(err, "Error Deleting Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) } else { - logT.Info(fmt.Sprintf("Delete Monitor: %v", resp)) + logT.Info("Deleted Pingdom Transaction Monitor Monitor " + m.Name) } } -func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor models.Monitor) pingdomNew.CheckWithoutID { - transactionCheck := pingdomNew.CheckWithoutID{} +func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor models.Monitor) *pingdomNew.CheckWithoutID { + transactionCheck := &pingdomNew.CheckWithoutID{} + providerConfig, _ := monitor.Config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) + if providerConfig == nil { + // ignore monitor if type is not PingdomTransaction + logT.Info("Monitor is not PingdomTransaction type", "Monitor", monitor) + return nil + } transactionCheck.Name = monitor.Name userIds := parseIDs(service.alertContacts) @@ -132,18 +164,25 @@ func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor if teamAlertContacts != nil { transactionCheck.TeamIds = teamAlertContacts } - service.addConfigToTranscationCheck(&transactionCheck, monitor.Config) + service.addConfigToTranscationCheck(transactionCheck, monitor) return transactionCheck } -func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(transactionCheck *pingdomNew.CheckWithoutID, config interface{}) { +func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(transactionCheck *pingdomNew.CheckWithoutID, monitor models.Monitor) { // Retrieve provider configuration + config := monitor.Config providerConfig, _ := config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) if providerConfig == nil { - logT.Info("Error retrieving provider configuration for Pingdom Transaction Monitor") + // providerConfig is not set, we create a go_to transaction by default from url because its required by API + transactionCheck.Steps = append(transactionCheck.Steps, pingdomNew.Step{ + Args: &pingdomNew.StepArgs{ + Url: ptr.String(monitor.URL), + }, + Fn: ptr.String("go_to"), + }) return } @@ -198,13 +237,13 @@ func NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { // First, marshal the map to JSON jsonData, err := json.Marshal(input) if err != nil { - logT.Info("Error marshalling map to JSON" + err.Error()) + logT.Error(err, "Error marshalling map to JSON") return nil } var stepArgs pingdomNew.StepArgs err = json.Unmarshal(jsonData, &stepArgs) if err != nil { - logT.Info("Error unmarshalling JSON to StepArgs" + err.Error()) + logT.Error(err, "Error marshalling map to StepArgs") return nil } return &stepArgs @@ -216,7 +255,7 @@ func parseIDs(field string) []int64 { stringArray := strings.Split(field, "-") ids, err := util.SliceAtoi64(stringArray) if err != nil { - logT.Info("Error decoding ids into integers" + err.Error()) + logT.Error(err, "Error decoding ids into integers") return nil } return ids @@ -228,8 +267,35 @@ func strToInt64(str string) int64 { // Parse the string as a base-10 integer with a bit size of 64. value, err := strconv.ParseInt(str, 10, 64) if err != nil { - logT.Error(err, "Error converting string to int64") return 0 } return value } + +// parseResponseBody checks if the response body is JSON and contains "errormessage". +// If so, it returns the value of "errormessage". Otherwise, it returns the entire body. +func parseResponseBody(resp *http.Response) string { + defer resp.Body.Close() + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + logT.Error(err, "Error reading response body") + return "" + } + // Attempt to unmarshal the response body into a map + var responseBodyMap map[string]map[string]interface{} + if err := json.Unmarshal(bodyBytes, &responseBodyMap); err != nil { + // If unmarshaling fails, return the whole body as a string. + return string(bodyBytes) + } + // Check if "error" key exists in the map + if errorObj, ok := responseBodyMap["error"]; ok { + // Check if "errormessage" key exists in the "error" object + if errorMessage, ok := errorObj["errormessage"]; ok { + if errMsgStr, ok := errorMessage.(string); ok { + return errMsgStr + } + } + } + // If "errormessage" key doesn't exist or isn't a string, return the whole JSON body + return string(bodyBytes) +} diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go new file mode 100644 index 00000000..2fa228a5 --- /dev/null +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go @@ -0,0 +1,92 @@ +package pingdomtransaction + +import ( + "testing" + + "github.com/stakater/IngressMonitorController/v2/pkg/config" + "github.com/stakater/IngressMonitorController/v2/pkg/models" + "github.com/stakater/IngressMonitorController/v2/pkg/util" + "gotest.tools/assert" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +func init() { + // To allow normal logging to be printed if tests fails + // Dev mode is an extra feature to make output more readable + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) +} + +func TestAddMonitorWithCorrectValues(t *testing.T) { + config := config.GetControllerConfigTest() + + service := PingdomTransactionMonitorService{} + provider := util.GetProviderWithName(config, "PingdomTransaction") + if provider == nil { + // TODO: Currently forcing to pass the test as we dont have Pingdom account to test + // Fail this case in future when have a valid Pingdom account + logT.Error(nil, "Failed to find provider") + return + } + + service.Setup(*provider) + m := models.Monitor{Name: "google-test", URL: "https://google1.com"} + + service.Add(m) + + mRes, err := service.GetByName("google-test") + assert.NilError(t, err) + + defer func() { + // Cleanup + service.Remove(*mRes) + }() + + if err != nil { + t.Error("Error: " + err.Error()) + } + + assert.Equal(t, mRes.Name, m.Name) + assert.Equal(t, mRes.URL, "https://google1.com") +} + +func TestUpdateMonitorWithCorrectValues(t *testing.T) { + config := config.GetControllerConfigTest() + + service := PingdomTransactionMonitorService{} + + provider := util.GetProviderWithName(config, "Pingdom") + if provider == nil { + // TODO: Currently forcing to pass the test as we dont have Pingdom account to test + // Fail this case in future when have a valid Pingdom account + logT.Error(nil, "Failed to find provider") + return + } + service.Setup(*provider) + + // Create initial record + m := models.Monitor{Name: "google-update-test", URL: "https://google.com"} + service.Add(m) + + mRes, err := service.GetByName("google-update-test") + assert.NilError(t, err) + + defer func() { + // Cleanup + service.Remove(*mRes) + }() + + // Update the record + mRes.URL = "https://facebook.com" + + service.Update(*mRes) + + mRes, err = service.GetByName("google-update-test") + if err != nil { + t.Error("Error: " + err.Error()) + } + + assert.Equal(t, mRes.Name, m.Name) + assert.Equal(t, mRes.URL, "https://facebook.com") + +} From 43aac905db5c01aa279bd9cee3286db2a61bbf8f Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 15:54:25 +0100 Subject: [PATCH 07/21] fix: optimize log outputs --- pkg/controllers/endpointmonitor_controller.go | 4 --- pkg/controllers/endpointmonitor_created.go | 5 ++-- pkg/controllers/endpointmonitor_deleted.go | 1 - pkg/monitors/gcloud/gcloud-monitor.go | 2 +- pkg/monitors/monitor-proxy.go | 2 -- pkg/monitors/monitor-service.go | 1 - pkg/monitors/pingdom/pingdom-monitor.go | 16 ++++------ .../pingdom-transaction-monitor.go | 30 +++++++++---------- .../pingdom-transaction-monitor_test.go | 4 +-- 9 files changed, 26 insertions(+), 39 deletions(-) diff --git a/pkg/controllers/endpointmonitor_controller.go b/pkg/controllers/endpointmonitor_controller.go index 5587eb7d..28fc5572 100644 --- a/pkg/controllers/endpointmonitor_controller.go +++ b/pkg/controllers/endpointmonitor_controller.go @@ -86,12 +86,9 @@ func (r *EndpointMonitorReconciler) Reconcile(ctx context.Context, req ctrl.Requ // Handle CreationDelay createTime := instance.CreationTimestamp delay := time.Until(createTime.Add(config.GetControllerConfig().CreationDelay)) - log.Info("Debug all monitors", "monitors", r.MonitorServices) monitorService := r.GetMonitorOfType(instance.Spec) monitor := findMonitorByName(monitorService, monitorName) - log.Info("Debug trying to find "+monitorName, "monitors", monitorService, "type", monitorService.GetType()) - log.Info("Debug got service", "spec", monitorService.ExtractConfig(instance.Spec)) if monitor != nil { // Monitor already exists, update if required err = r.handleUpdate(req, instance, *monitor, monitorService) @@ -102,7 +99,6 @@ func (r *EndpointMonitorReconciler) Reconcile(ctx context.Context, req ctrl.Requ log.Info("Requeuing request to add monitor " + monitorName + " for " + fmt.Sprintf("%+v", config.GetControllerConfig().CreationDelay) + " seconds") return reconcile.Result{RequeueAfter: delay}, nil } - log.Info("Debug forced to add "+monitorName, "monitors", monitorService, "instance", instance) err = r.handleCreate(req, instance, monitorName, monitorService) } return reconcile.Result{RequeueAfter: config.ReconciliationRequeueTime}, err diff --git a/pkg/controllers/endpointmonitor_created.go b/pkg/controllers/endpointmonitor_created.go index 5ebcff01..272ea949 100644 --- a/pkg/controllers/endpointmonitor_created.go +++ b/pkg/controllers/endpointmonitor_created.go @@ -10,9 +10,9 @@ import ( ) func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string, monitorService *monitors.MonitorServiceProxy) error { - log := r.Log.WithValues("endpointMonitor", instance.ObjectMeta.Namespace) + log := r.Log.WithValues("endpointMonitor") - log.Info("Debug Creating Monitor: " + monitorName, "MonitorType", monitorService.GetType()) + log.Info("Creating Monitor: " + monitorName, "Namespace", instance.ObjectMeta.Namespace, "MonitorType", monitorService.GetType()) url, err := util.GetMonitorURL(r.Client, instance) if err != nil { @@ -24,7 +24,6 @@ func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, inst // Create monitor Model monitor := models.Monitor{Name: monitorName, URL: url, Config: providerConfig} - log.Info("Debug got Request to create monitor", "monitor", monitor) // Add monitor for provider monitorService.Add(monitor) diff --git a/pkg/controllers/endpointmonitor_deleted.go b/pkg/controllers/endpointmonitor_deleted.go index 132f30d4..f6210f6f 100644 --- a/pkg/controllers/endpointmonitor_deleted.go +++ b/pkg/controllers/endpointmonitor_deleted.go @@ -20,7 +20,6 @@ func (r *EndpointMonitorReconciler) handleDelete(request reconcile.Request, inst return reconcile.Result{}, nil } - log.Info("Debug deleting monitor spec", "spec", instance.Spec) // in case of multiple providers we need to iterate over all of them monitorServices := findMonitorServicesThatContainsMonitor(r.MonitorServices, monitorName) for _, monitorService := range monitorServices { diff --git a/pkg/monitors/gcloud/gcloud-monitor.go b/pkg/monitors/gcloud/gcloud-monitor.go index 280dcd2c..1e237fed 100644 --- a/pkg/monitors/gcloud/gcloud-monitor.go +++ b/pkg/monitors/gcloud/gcloud-monitor.go @@ -197,7 +197,7 @@ func (service *MonitorService) Update(monitor models.Monitor) { return } - log.Info(fmt.Sprintf("Updated Monitor: %v", uptimeCheckConfig)) + log.Info("Successfully updated monitor " + monitor.Name, "Response", uptimeCheckConfig) } func (service *MonitorService) Remove(monitor models.Monitor) { diff --git a/pkg/monitors/monitor-proxy.go b/pkg/monitors/monitor-proxy.go index ca77b6ff..cee931a4 100644 --- a/pkg/monitors/monitor-proxy.go +++ b/pkg/monitors/monitor-proxy.go @@ -68,7 +68,6 @@ func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy { func (mp *MonitorServiceProxy) ExtractConfig(spec endpointmonitorv1alpha1.EndpointMonitorSpec) interface{} { var config interface{} - log.Info("Debug Extracting config for monitor type: "+mp.monitorType, "MonitorSpec", spec) switch mp.monitorType { case TypeUptimeRobot: config = spec.UptimeRobotConfig @@ -89,7 +88,6 @@ func (mp *MonitorServiceProxy) ExtractConfig(spec endpointmonitorv1alpha1.Endpoi case TypeGrafana: config = spec.GrafanaConfig default: - log.Info("Debug not specific Provider config found for monitor type: " + mp.monitorType, "MonitorSpec", spec) return config } return config diff --git a/pkg/monitors/monitor-service.go b/pkg/monitors/monitor-service.go index 63496f7c..14be3862 100644 --- a/pkg/monitors/monitor-service.go +++ b/pkg/monitors/monitor-service.go @@ -21,7 +21,6 @@ func CreateMonitorService(p *config.Provider) *MonitorServiceProxy { monitorService := (&MonitorServiceProxy{}).OfType(p.Name) monitorService.monitorType = p.Name monitorService.Setup(*p) - log.Info("Debug Created Monitor Service for provider: " + p.Name) return &monitorService } diff --git a/pkg/monitors/pingdom/pingdom-monitor.go b/pkg/monitors/pingdom/pingdom-monitor.go index e4312cf0..ab13727d 100644 --- a/pkg/monitors/pingdom/pingdom-monitor.go +++ b/pkg/monitors/pingdom/pingdom-monitor.go @@ -102,9 +102,9 @@ func (service *PingdomMonitorService) Update(m models.Monitor) { resp, err := service.client.Checks.Update(monitorID, &httpCheck) if err != nil { - log.Info("Error updating Monitor: " + err.Error()) + log.Info(fmt.Sprintf("Error updating Monitor %s %v", m.Name, err.Error())) } else { - log.Info(fmt.Sprintf("Updated Monitor: %v", resp)) + log.Info("Sucessfully updated Monitor " + m.Name, "Response", resp.Message) } } @@ -113,9 +113,9 @@ func (service *PingdomMonitorService) Remove(m models.Monitor) { resp, err := service.client.Checks.Delete(monitorID) if err != nil { - log.Info("Error deleting Monitor: " + err.Error()) + log.Info(fmt.Sprintf("Error deleting Monitor %s %v", m.Name, err.Error())) } else { - log.Info(fmt.Sprintf("Delete Monitor: %v", resp)) + log.Info("Sucessfully deleted Monitor " + m.Name, "Response", resp.Message) } } @@ -238,7 +238,6 @@ func (service *PingdomMonitorService) addConfigToHttpCheck(httpCheck *pingdom.Ht // Env variable set, pass user/pass to httpCheck httpCheck.Username = providerConfig.BasicAuthUser httpCheck.Password = passwordValue - log.Info("Basic auth requirement detected. Setting username and password for httpCheck") } else { log.Info("Error reading basic auth password from environment variable") } @@ -246,16 +245,14 @@ func (service *PingdomMonitorService) addConfigToHttpCheck(httpCheck *pingdom.Ht if providerConfig != nil && len(providerConfig.ShouldContain) > 0 { httpCheck.ShouldContain = providerConfig.ShouldContain - log.Info("Should contain detected. Setting Should Contain string: " + providerConfig.ShouldContain) } // Tags should be a single word or multiple comma-separated words if providerConfig != nil && len(providerConfig.Tags) > 0 { if !strings.Contains(providerConfig.Tags, " ") { httpCheck.Tags = providerConfig.Tags - log.Info("Tags detected. Setting Tags as: " + providerConfig.Tags) } else { - log.Info("Tag string should not contain spaces. Not applying tags.") + log.Info("Tag string should not contain spaces. Not applying tags for monitor: " + httpCheck.Name) } } @@ -267,9 +264,8 @@ func (service *PingdomMonitorService) addConfigToHttpCheck(httpCheck *pingdom.Ht postDataValue := os.Getenv(providerConfig.PostDataEnvVar) if postDataValue != "" { httpCheck.PostData = postDataValue - log.Info("Post data detected. Setting post data for httpCheck to value of environment variable: " + providerConfig.PostDataEnvVar) } else { - log.Error(errors.New("Error reading post data from environment variable"), "Environment Variable %s does not exist", providerConfig.PostDataEnvVar) + log.Error(errors.New("error reading post data from environment variable"), "Environment Variable %s does not exist", providerConfig.PostDataEnvVar) } } } diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index e7427e8b..d0f835ad 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -20,7 +20,7 @@ import ( "github.com/stakater/IngressMonitorController/v2/pkg/util" ) -var logT = logf.Log.WithName("pingdom-transaction") +var log = logf.Log.WithName("pingdom-transaction") // PingdomTransactionMonitorService interfaces with MonitorService type PingdomTransactionMonitorService struct { @@ -71,7 +71,7 @@ func (service *PingdomTransactionMonitorService) GetAll() []models.Monitor { var monitors []models.Monitor checks, _, err := service.client.TMSChecksAPI.GetAllChecks(service.context).Type_("script").Execute() if err != nil { - logT.Error(err, "Error getting all transaction checks") + log.Error(err, "Error getting all transaction checks") return monitors } @@ -92,7 +92,7 @@ func (service *PingdomTransactionMonitorService) GetAll() []models.Monitor { func (service *PingdomTransactionMonitorService) GetUrlFromSteps(id int64) string { check, _, err := service.client.TMSChecksAPI.GetCheck(service.context, id).Execute() if err != nil { - logT.Error(err, "Error getting transaction check") + log.Error(err, "Error getting transaction check") return "" } if check == nil { @@ -113,9 +113,9 @@ func (service *PingdomTransactionMonitorService) Add(m models.Monitor) { } _, resp, err := service.client.TMSChecksAPI.AddCheck(service.context).CheckWithoutID(*transactionCheck).Execute() if err != nil { - logT.Error(err, "Error Adding Pingdom Transaction Monitor " + m.Name, "Response", parseResponseBody(resp)) + log.Error(err, "Error Adding Pingdom Transaction Monitor "+m.Name, "Response", parseResponseBody(resp)) } else { - logT.Info("Added Pingdom Transaction Monitor Monitor " + m.Name) + log.Info("Successfully added Pingdom Transaction Monitor " + m.Name) } } @@ -127,18 +127,18 @@ func (service *PingdomTransactionMonitorService) Update(m models.Monitor) { monitorID := strToInt64(m.ID) _, resp, err := service.client.TMSChecksAPI.ModifyCheck(service.context, monitorID).CheckWithoutIDPUT(*transactionCheck.AsPut()).Execute() if err != nil { - logT.Error(err, "Error Updating Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) + log.Error(err, "Error Updating Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) return } - logT.Info("Updated Pingdom Transaction Monitor Monitor " + m.Name) + log.Info("Updated Pingdom Transaction Monitor Monitor " + m.Name) } func (service *PingdomTransactionMonitorService) Remove(m models.Monitor) { _, resp, err := service.client.TMSChecksAPI.DeleteCheck(service.context, strToInt64(m.ID)).Execute() if err != nil { - logT.Error(err, "Error Deleting Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) + log.Error(err, "Error Deleting Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) } else { - logT.Info("Deleted Pingdom Transaction Monitor Monitor " + m.Name) + log.Info("Deleted Pingdom Transaction Monitor Monitor " + m.Name) } } @@ -147,7 +147,7 @@ func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor providerConfig, _ := monitor.Config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) if providerConfig == nil { // ignore monitor if type is not PingdomTransaction - logT.Info("Monitor is not PingdomTransaction type", "Monitor", monitor) + log.Info("Monitor is not PingdomTransaction type" + monitor.Name) return nil } transactionCheck.Name = monitor.Name @@ -227,7 +227,7 @@ func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(tra Fn: ptr.String(step.Function), }) } else { - logT.Info("Invalid Pingdom Step Args Provided") + log.Info("Invalid Pingdom Step Args Provided") } } } @@ -237,13 +237,13 @@ func NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { // First, marshal the map to JSON jsonData, err := json.Marshal(input) if err != nil { - logT.Error(err, "Error marshalling map to JSON") + log.Error(err, "Error marshalling map to JSON") return nil } var stepArgs pingdomNew.StepArgs err = json.Unmarshal(jsonData, &stepArgs) if err != nil { - logT.Error(err, "Error marshalling map to StepArgs") + log.Error(err, "Error marshalling map to StepArgs") return nil } return &stepArgs @@ -255,7 +255,7 @@ func parseIDs(field string) []int64 { stringArray := strings.Split(field, "-") ids, err := util.SliceAtoi64(stringArray) if err != nil { - logT.Error(err, "Error decoding ids into integers") + log.Error(err, "Error decoding ids into integers") return nil } return ids @@ -278,7 +278,7 @@ func parseResponseBody(resp *http.Response) string { defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) if err != nil { - logT.Error(err, "Error reading response body") + log.Error(err, "Error reading response body") return "" } // Attempt to unmarshal the response body into a map diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go index 2fa228a5..e01eda1a 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go @@ -25,7 +25,7 @@ func TestAddMonitorWithCorrectValues(t *testing.T) { if provider == nil { // TODO: Currently forcing to pass the test as we dont have Pingdom account to test // Fail this case in future when have a valid Pingdom account - logT.Error(nil, "Failed to find provider") + log.Error(nil, "Failed to find provider") return } @@ -59,7 +59,7 @@ func TestUpdateMonitorWithCorrectValues(t *testing.T) { if provider == nil { // TODO: Currently forcing to pass the test as we dont have Pingdom account to test // Fail this case in future when have a valid Pingdom account - logT.Error(nil, "Failed to find provider") + log.Error(nil, "Failed to find provider") return } service.Setup(*provider) From 3f1f5660bffac94b08e84554eab1ee78803c2f99 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 15:55:20 +0100 Subject: [PATCH 08/21] fix: make test compability with macos arm64 --- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 6dc7cd87..612c0ad8 100644 --- a/Makefile +++ b/Makefile @@ -101,10 +101,9 @@ vet: ## Run go vet against code. ENVTEST_ASSETS_DIR = $(shell pwd)/testbin .PHONY: test -test: generate fmt vet manifests - mkdir -p $(ENVTEST_ASSETS_DIR) - test -f $(ENVTEST_ASSETS_DIR)/setup-envtest.sh || curl -sSLo $(ENVTEST_ASSETS_DIR)/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.6.3/hack/setup-envtest.sh - source $(ENVTEST_ASSETS_DIR)/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -count=1 -coverprofile cover.out +test: generate fmt vet manifests envtest + $(ENVTEST) use -p path 1.28.x! + go test ./... -count=1 -coverprofile cover.out ##@ Build From 2d24ee560e87168b8f08be133e04df81a83d6ec6 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 16:26:26 +0100 Subject: [PATCH 09/21] fix: update pingdom client to latest tag --- go.mod | 9 +------ go.sum | 25 ++----------------- .../pingdom-transaction-monitor.go | 2 +- 3 files changed, 4 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index c690c2d7..a3c8f2a7 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-logr/logr v1.2.0 github.com/grafana/synthetic-monitoring-agent v0.18.2 github.com/grafana/synthetic-monitoring-api-go-client v0.7.0 - github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11 + github.com/karlderkaefer/pingdom-golang-client v1.0.3 github.com/kelseyhightower/envconfig v1.4.0 github.com/openshift/api v0.0.0-20200526144822-34f54f12813a github.com/patrickmn/go-cache v2.1.0+incompatible @@ -47,13 +47,11 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deepmap/oapi-codegen/v2 v2.0.0 // indirect github.com/dimchansky/utfbom v1.1.0 // indirect github.com/emicklei/go-restful v2.16.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/getkin/kin-openapi v0.118.0 // indirect github.com/go-logr/zapr v1.2.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect @@ -69,7 +67,6 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/imdario/mergo v0.3.12 // indirect - github.com/invopop/yaml v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -77,9 +74,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/perimeterx/marshmallow v1.1.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect @@ -92,7 +87,6 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect golang.org/x/crypto v0.17.0 // indirect - golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.16.0 // indirect golang.org/x/oauth2 v0.10.0 // indirect golang.org/x/sync v0.4.0 // indirect @@ -100,7 +94,6 @@ require ( golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/tools v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/go.sum b/go.sum index a911fd8b..59e15fcb 100644 --- a/go.sum +++ b/go.sum @@ -155,9 +155,6 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ 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/deepmap/oapi-codegen v1.16.2 h1:xGHx0dNqYfy9gE8a7AVgVM8Sd5oF9SEgePzP+UPAUXI= -github.com/deepmap/oapi-codegen/v2 v2.0.0 h1:3TS7w3r+XnjKFXcbFbc16pTWzfTy0OLPkCsutEHjWDA= -github.com/deepmap/oapi-codegen/v2 v2.0.0/go.mod h1:7zR+ZL3WzLeCkr2k8oWTxEa0v8y/F25ane0l6A5UjLA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= @@ -196,8 +193,6 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= -github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -236,7 +231,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -380,8 +374,6 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= -github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= @@ -400,10 +392,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karlderkaefer/pingdom-golang-client v1.0.0 h1:7RGD7gj8dJrXXjE9JgzHvGC424lXCbHXCGPBmtGKfkE= -github.com/karlderkaefer/pingdom-golang-client v1.0.0/go.mod h1:iHOA8APTy8wxam3QxKp/nGw9823gDIlMEpYiKp9+nrU= -github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11 h1:amVFXIUzG7BiGXDa6IVdEdroRF7PL2NrPVrqE21iZXs= -github.com/karlderkaefer/pingdom-golang-client v1.0.1-0.20240119151402-5a612ee09e11/go.mod h1:iHOA8APTy8wxam3QxKp/nGw9823gDIlMEpYiKp9+nrU= +github.com/karlderkaefer/pingdom-golang-client v1.0.3 h1:QaPE4VjHBi5n2eH/2u90VUYm5/a73iy+9dukQ+QUQjg= +github.com/karlderkaefer/pingdom-golang-client v1.0.3/go.mod h1:Q01dHklWfM8O8V8ln80ix4nqlxburepAsdmoIHJt7hg= 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -460,8 +450,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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= @@ -497,8 +485,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= -github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -601,8 +587,6 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -722,8 +706,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -972,8 +954,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1136,7 +1116,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -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 v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index d0f835ad..ab8f5f6d 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -12,7 +12,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/client/ptr" + "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" "github.com/stakater/IngressMonitorController/v2/pkg/config" From 0ef7381c7b149222380760b9fc076b1cd0486fae Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 16:30:28 +0100 Subject: [PATCH 10/21] fix: move util function to utils --- charts/ingressmonitorcontroller/Chart.yaml | 6 +++--- .../pingdom-transaction-monitor.go | 16 +++------------- pkg/util/util.go | 9 +++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/charts/ingressmonitorcontroller/Chart.yaml b/charts/ingressmonitorcontroller/Chart.yaml index 4cbdc23f..b919980f 100644 --- a/charts/ingressmonitorcontroller/Chart.yaml +++ b/charts/ingressmonitorcontroller/Chart.yaml @@ -1,12 +1,12 @@ apiVersion: v2 -name: ingressmonitorcontroller +name: stakater-ingressmonitorcontroller description: IngressMonitorController Operator chart that runs on kubernetes # Helm chart Version -version: 2.1.49 +version: 2.3.0 # Application version to be deployed -appVersion: 2.1.49 +appVersion: 2.3.0 keywords: - IngressMonitorController diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index ab8f5f6d..2a3d033d 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -7,13 +7,12 @@ import ( "io" "net/http" "os" - "strconv" "strings" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" + "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" "github.com/stakater/IngressMonitorController/v2/pkg/config" "github.com/stakater/IngressMonitorController/v2/pkg/models" @@ -124,7 +123,7 @@ func (service *PingdomTransactionMonitorService) Update(m models.Monitor) { if transactionCheck == nil { return } - monitorID := strToInt64(m.ID) + monitorID := util.StrToInt64(m.ID) _, resp, err := service.client.TMSChecksAPI.ModifyCheck(service.context, monitorID).CheckWithoutIDPUT(*transactionCheck.AsPut()).Execute() if err != nil { log.Error(err, "Error Updating Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) @@ -134,7 +133,7 @@ func (service *PingdomTransactionMonitorService) Update(m models.Monitor) { } func (service *PingdomTransactionMonitorService) Remove(m models.Monitor) { - _, resp, err := service.client.TMSChecksAPI.DeleteCheck(service.context, strToInt64(m.ID)).Execute() + _, resp, err := service.client.TMSChecksAPI.DeleteCheck(service.context, util.StrToInt64(m.ID)).Execute() if err != nil { log.Error(err, "Error Deleting Pingdom Transaction Monitor", "Response", parseResponseBody(resp)) } else { @@ -263,15 +262,6 @@ func parseIDs(field string) []int64 { return nil } -func strToInt64(str string) int64 { - // Parse the string as a base-10 integer with a bit size of 64. - value, err := strconv.ParseInt(str, 10, 64) - if err != nil { - return 0 - } - return value -} - // parseResponseBody checks if the response body is JSON and contains "errormessage". // If so, it returns the value of "errormessage". Otherwise, it returns the entire body. func parseResponseBody(resp *http.Response) string { diff --git a/pkg/util/util.go b/pkg/util/util.go index 769db2c4..2304096a 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -69,3 +69,12 @@ func SplitAndSort(s string, sep string) []string { sort.Strings(slice) return slice } + +func StrToInt64(str string) int64 { + // Parse the string as a base-10 integer with a bit size of 64. + value, err := strconv.ParseInt(str, 10, 64) + if err != nil { + return 0 + } + return value +} \ No newline at end of file From 38289cdd2fcfd7c4b25ca27531744dba6086b946 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 16:42:16 +0100 Subject: [PATCH 11/21] chore: go vet and go fmt --- pkg/controllers/endpointmonitor_controller.go | 61 +++++----- pkg/controllers/endpointmonitor_created.go | 2 +- pkg/controllers/endpointmonitor_deleted.go | 2 +- pkg/monitors/gcloud/gcloud-monitor.go | 2 +- pkg/monitors/monitor-proxy.go | 114 +++++++++--------- pkg/monitors/pingdom/pingdom-monitor.go | 4 +- pkg/util/util.go | 2 +- 7 files changed, 93 insertions(+), 94 deletions(-) diff --git a/pkg/controllers/endpointmonitor_controller.go b/pkg/controllers/endpointmonitor_controller.go index 28fc5572..b81f5838 100644 --- a/pkg/controllers/endpointmonitor_controller.go +++ b/pkg/controllers/endpointmonitor_controller.go @@ -29,8 +29,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" ) @@ -112,41 +112,40 @@ func (r *EndpointMonitorReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *EndpointMonitorReconciler) GetMonitorOfType(spec endpointmonitorv1alpha1.EndpointMonitorSpec) *monitors.MonitorServiceProxy { - if len(r.MonitorServices) == 0 { + if len(r.MonitorServices) == 0 { panic("No monitor services found") } if spec.PingdomTransactionConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypePingdomTransaction) - } - if spec.PingdomConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypePingdom) - } - if spec.UptimeRobotConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeUptimeRobot) - } - if spec.StatusCakeConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeStatusCake) - } - if spec.UptimeConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeUptime) - } - if spec.UpdownConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeUpdown) - } - if spec.AppInsightsConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeAppInsights) - } - if spec.GCloudConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeGCloud) - } - if spec.GrafanaConfig != nil { - return r.GetMonitorServiceOfType(monitors.TypeGrafana) - } - // If none of the above, return the first monitor service - return r.MonitorServices[0] + return r.GetMonitorServiceOfType(monitors.TypePingdomTransaction) + } + if spec.PingdomConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypePingdom) + } + if spec.UptimeRobotConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUptimeRobot) + } + if spec.StatusCakeConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeStatusCake) + } + if spec.UptimeConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUptime) + } + if spec.UpdownConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeUpdown) + } + if spec.AppInsightsConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeAppInsights) + } + if spec.GCloudConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeGCloud) + } + if spec.GrafanaConfig != nil { + return r.GetMonitorServiceOfType(monitors.TypeGrafana) + } + // If none of the above, return the first monitor service + return r.MonitorServices[0] } - func (r *EndpointMonitorReconciler) GetMonitorServiceOfType(monitorType string) *monitors.MonitorServiceProxy { for _, monitorService := range r.MonitorServices { if monitorService.GetType() == monitorType { diff --git a/pkg/controllers/endpointmonitor_created.go b/pkg/controllers/endpointmonitor_created.go index 272ea949..53f34f8a 100644 --- a/pkg/controllers/endpointmonitor_created.go +++ b/pkg/controllers/endpointmonitor_created.go @@ -12,7 +12,7 @@ import ( func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string, monitorService *monitors.MonitorServiceProxy) error { log := r.Log.WithValues("endpointMonitor") - log.Info("Creating Monitor: " + monitorName, "Namespace", instance.ObjectMeta.Namespace, "MonitorType", monitorService.GetType()) + log.Info("Creating Monitor: "+monitorName, "Namespace", instance.ObjectMeta.Namespace, "MonitorType", monitorService.GetType()) url, err := util.GetMonitorURL(r.Client, instance) if err != nil { diff --git a/pkg/controllers/endpointmonitor_deleted.go b/pkg/controllers/endpointmonitor_deleted.go index f6210f6f..4ae7cbaa 100644 --- a/pkg/controllers/endpointmonitor_deleted.go +++ b/pkg/controllers/endpointmonitor_deleted.go @@ -20,7 +20,7 @@ func (r *EndpointMonitorReconciler) handleDelete(request reconcile.Request, inst return reconcile.Result{}, nil } - // in case of multiple providers we need to iterate over all of them + // in case of multiple providers we need to iterate over all of them monitorServices := findMonitorServicesThatContainsMonitor(r.MonitorServices, monitorName) for _, monitorService := range monitorServices { r.removeMonitorIfExists(monitorService, monitorName) diff --git a/pkg/monitors/gcloud/gcloud-monitor.go b/pkg/monitors/gcloud/gcloud-monitor.go index 1e237fed..3cc7c421 100644 --- a/pkg/monitors/gcloud/gcloud-monitor.go +++ b/pkg/monitors/gcloud/gcloud-monitor.go @@ -197,7 +197,7 @@ func (service *MonitorService) Update(monitor models.Monitor) { return } - log.Info("Successfully updated monitor " + monitor.Name, "Response", uptimeCheckConfig) + log.Info("Successfully updated monitor "+monitor.Name, "Response", uptimeCheckConfig) } func (service *MonitorService) Remove(monitor models.Monitor) { diff --git a/pkg/monitors/monitor-proxy.go b/pkg/monitors/monitor-proxy.go index cee931a4..6875846a 100644 --- a/pkg/monitors/monitor-proxy.go +++ b/pkg/monitors/monitor-proxy.go @@ -19,15 +19,15 @@ import ( var log = logf.Log.WithName("monitors") const ( - TypeUptimeRobot = "UptimeRobot" - TypePingdom = "Pingdom" - TypePingdomTransaction = "PingdomTransaction" - TypeStatusCake = "StatusCake" - TypeUptime = "Uptime" - TypeUpdown = "Updown" - TypeAppInsights = "AppInsights" - TypeGCloud = "gcloud" - TypeGrafana = "Grafana" + TypeUptimeRobot = "UptimeRobot" + TypePingdom = "Pingdom" + TypePingdomTransaction = "PingdomTransaction" + TypeStatusCake = "StatusCake" + TypeUptime = "Uptime" + TypeUpdown = "Updown" + TypeAppInsights = "AppInsights" + TypeGCloud = "gcloud" + TypeGrafana = "Grafana" ) type MonitorServiceProxy struct { @@ -40,57 +40,57 @@ func (mp *MonitorServiceProxy) GetType() string { } func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy { - mp.monitorType = mType - switch mType { - case TypeUptimeRobot: - mp.monitor = &uptimerobot.UpTimeMonitorService{} - case TypePingdom: - mp.monitor = &pingdom.PingdomMonitorService{} - case TypePingdomTransaction: - mp.monitor = &pingdomtransaction.PingdomTransactionMonitorService{} - case TypeStatusCake: - mp.monitor = &statuscake.StatusCakeMonitorService{} - case TypeUptime: - mp.monitor = &uptime.UpTimeMonitorService{} - case TypeUpdown: - mp.monitor = &updown.UpdownMonitorService{} - case TypeAppInsights: - mp.monitor = &appinsights.AppinsightsMonitorService{} - case TypeGCloud: - mp.monitor = &gcloud.MonitorService{} - case TypeGrafana: - mp.monitor = &grafana.GrafanaMonitorService{} - default: - panic("No such provider found: " + mType) - } - return *mp + mp.monitorType = mType + switch mType { + case TypeUptimeRobot: + mp.monitor = &uptimerobot.UpTimeMonitorService{} + case TypePingdom: + mp.monitor = &pingdom.PingdomMonitorService{} + case TypePingdomTransaction: + mp.monitor = &pingdomtransaction.PingdomTransactionMonitorService{} + case TypeStatusCake: + mp.monitor = &statuscake.StatusCakeMonitorService{} + case TypeUptime: + mp.monitor = &uptime.UpTimeMonitorService{} + case TypeUpdown: + mp.monitor = &updown.UpdownMonitorService{} + case TypeAppInsights: + mp.monitor = &appinsights.AppinsightsMonitorService{} + case TypeGCloud: + mp.monitor = &gcloud.MonitorService{} + case TypeGrafana: + mp.monitor = &grafana.GrafanaMonitorService{} + default: + panic("No such provider found: " + mType) + } + return *mp } func (mp *MonitorServiceProxy) ExtractConfig(spec endpointmonitorv1alpha1.EndpointMonitorSpec) interface{} { - var config interface{} - switch mp.monitorType { - case TypeUptimeRobot: - config = spec.UptimeRobotConfig - case TypePingdom: - config = spec.PingdomConfig - case TypePingdomTransaction: - config = spec.PingdomTransactionConfig - case TypeStatusCake: - config = spec.StatusCakeConfig - case TypeUptime: - config = spec.UptimeConfig - case TypeUpdown: - config = spec.UpdownConfig - case TypeAppInsights: - config = spec.AppInsightsConfig - case TypeGCloud: - config = spec.GCloudConfig - case TypeGrafana: - config = spec.GrafanaConfig - default: - return config - } - return config + var config interface{} + switch mp.monitorType { + case TypeUptimeRobot: + config = spec.UptimeRobotConfig + case TypePingdom: + config = spec.PingdomConfig + case TypePingdomTransaction: + config = spec.PingdomTransactionConfig + case TypeStatusCake: + config = spec.StatusCakeConfig + case TypeUptime: + config = spec.UptimeConfig + case TypeUpdown: + config = spec.UpdownConfig + case TypeAppInsights: + config = spec.AppInsightsConfig + case TypeGCloud: + config = spec.GCloudConfig + case TypeGrafana: + config = spec.GrafanaConfig + default: + return config + } + return config } func (mp *MonitorServiceProxy) Setup(p config.Provider) { diff --git a/pkg/monitors/pingdom/pingdom-monitor.go b/pkg/monitors/pingdom/pingdom-monitor.go index ab13727d..f68785c4 100644 --- a/pkg/monitors/pingdom/pingdom-monitor.go +++ b/pkg/monitors/pingdom/pingdom-monitor.go @@ -104,7 +104,7 @@ func (service *PingdomMonitorService) Update(m models.Monitor) { if err != nil { log.Info(fmt.Sprintf("Error updating Monitor %s %v", m.Name, err.Error())) } else { - log.Info("Sucessfully updated Monitor " + m.Name, "Response", resp.Message) + log.Info("Sucessfully updated Monitor "+m.Name, "Response", resp.Message) } } @@ -115,7 +115,7 @@ func (service *PingdomMonitorService) Remove(m models.Monitor) { if err != nil { log.Info(fmt.Sprintf("Error deleting Monitor %s %v", m.Name, err.Error())) } else { - log.Info("Sucessfully deleted Monitor " + m.Name, "Response", resp.Message) + log.Info("Sucessfully deleted Monitor "+m.Name, "Response", resp.Message) } } diff --git a/pkg/util/util.go b/pkg/util/util.go index 2304096a..8d573eb5 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -77,4 +77,4 @@ func StrToInt64(str string) int64 { return 0 } return value -} \ No newline at end of file +} From b48165f9360b9353828ea4494173d6f323bd6e14 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 16:42:26 +0100 Subject: [PATCH 12/21] feat: update CRD for helm chart --- ...monitor.stakater.com_endpointmonitors.yaml | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml index 5367c583..4b226131 100644 --- a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -130,6 +130,95 @@ spec: HTTP checks. type: boolean type: object + pingdomTransactionConfig: + description: Configuration for Pingdom Transaction Monitor Provider + properties: + alertContacts: + description: '`-` separated contact id''s (e.g. "1234567_8_9-9876543_2_1")' + type: string + alertIntegrations: + description: '`-` separated set list of integrations ids (e.g. + "91166-12168")' + type: string + custom_message: + description: Custom message that is part of the email and webhook + alerts + type: string + interval: + description: 'TMS test intervals in minutes. Allowed intervals: + 5,10,20,60,720,1440. The interval you''re allowed to set may + vary depending on your current plan.' + enum: + - 5 + - 10 + - 20 + - 60 + - 720 + - 1440 + type: integer + paused: + description: 'Check status: active or inactive' + type: boolean + region: + description: 'Name of the region where the check is executed. + Supported regions: us-east, us-west, eu, au' + enum: + - us-east + - us-west + - eu + - au + type: string + send_notification_when_down: + description: Send notification when down X times + format: int64 + type: integer + severity_level: + description: 'Check importance- how important are the alerts when + the check fails. Allowed values: low, high' + enum: + - low + - high + type: string + steps: + description: steps to be executed as part of the check + items: + description: PingdomStep respresents a step of the script to + run a transcaction check + properties: + args: + additionalProperties: + type: string + description: 'contains the html element with assigned value + the key element is always lowercase for example {"url": + "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg' + type: object + function: + description: 'contains the function that is executed as + part of the step commands: go_to, click, fill, check, + uncheck, sleep, select_radio, basic_auth, submit, wait_for_element, + wait_for_contains validations: url, exists, not_exists, + contains, not_contains, field_contains, field_not_contains, + is_checked, is_not_checked, radio_selected, dropdown_selected, + dropdown_not_selected see updated list https://docs.pingdom.com/api/#section/TMS-Steps-Vocabulary/Script-transaction-checks' + type: string + required: + - args + - function + type: object + type: array + tags: + description: List of tags for a check. The tag name may contain + the characters 'A-Z', 'a-z', '0-9', '_' and '-'. The maximum + length of a tag is 64 characters. + items: + type: string + type: array + teamAlertContacts: + description: '`-` separated team id''s (e.g. "1234567_8_9-9876543_2_1")' + type: string + required: + - steps + type: object providers: description: Comma separated list of providers type: string From 6b72345dbc8e9296cd25a746a5fa25c73de29b82 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 16:43:18 +0100 Subject: [PATCH 13/21] chore: reset helm chart spec --- charts/ingressmonitorcontroller/Chart.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/ingressmonitorcontroller/Chart.yaml b/charts/ingressmonitorcontroller/Chart.yaml index b919980f..4cbdc23f 100644 --- a/charts/ingressmonitorcontroller/Chart.yaml +++ b/charts/ingressmonitorcontroller/Chart.yaml @@ -1,12 +1,12 @@ apiVersion: v2 -name: stakater-ingressmonitorcontroller +name: ingressmonitorcontroller description: IngressMonitorController Operator chart that runs on kubernetes # Helm chart Version -version: 2.3.0 +version: 2.1.49 # Application version to be deployed -appVersion: 2.3.0 +appVersion: 2.1.49 keywords: - IngressMonitorController From 24c605b4b2fc16c8fa7f6e4ee106ca618177b6dd Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 18:13:02 +0100 Subject: [PATCH 14/21] fix: update golang client --- go.mod | 2 +- go.sum | 4 ++-- .../pingdomtransaction/pingdom-transaction-monitor.go | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a3c8f2a7..5c891014 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-logr/logr v1.2.0 github.com/grafana/synthetic-monitoring-agent v0.18.2 github.com/grafana/synthetic-monitoring-api-go-client v0.7.0 - github.com/karlderkaefer/pingdom-golang-client v1.0.3 + github.com/karlderkaefer/pingdom-golang-client v1.0.4 github.com/kelseyhightower/envconfig v1.4.0 github.com/openshift/api v0.0.0-20200526144822-34f54f12813a github.com/patrickmn/go-cache v2.1.0+incompatible diff --git a/go.sum b/go.sum index 59e15fcb..59019039 100644 --- a/go.sum +++ b/go.sum @@ -392,8 +392,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karlderkaefer/pingdom-golang-client v1.0.3 h1:QaPE4VjHBi5n2eH/2u90VUYm5/a73iy+9dukQ+QUQjg= -github.com/karlderkaefer/pingdom-golang-client v1.0.3/go.mod h1:Q01dHklWfM8O8V8ln80ix4nqlxburepAsdmoIHJt7hg= +github.com/karlderkaefer/pingdom-golang-client v1.0.4 h1:tBLJ5Id3thyEor9D5zl7VZen5P8EI13/6izrjhvniH4= +github.com/karlderkaefer/pingdom-golang-client v1.0.4/go.mod h1:Q01dHklWfM8O8V8ln80ix4nqlxburepAsdmoIHJt7hg= 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index 2a3d033d..a34cd691 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -218,6 +218,9 @@ func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(tra if providerConfig.SeverityLevel != "" { transactionCheck.SeverityLevel = ptr.String(providerConfig.SeverityLevel) } + if providerConfig.Interval > 0 { + transactionCheck.Interval = ptr.Int64((int64(providerConfig.Interval))) + } for _, step := range providerConfig.Steps { args := NewStepArgsByMap(step.Args) if args != nil { From a834ceab37216519758a77fdeb411aaf154f16cf Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 18:16:40 +0100 Subject: [PATCH 15/21] docs: add readme for pingdom transaction --- api/v1alpha1/endpointmonitor_types.go | 2 +- docs/pingdom-configuration.md | 15 ----- docs/pingdom-transcation-configuration.md | 77 +++++++++++++++++++++++ 3 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 docs/pingdom-transcation-configuration.md diff --git a/api/v1alpha1/endpointmonitor_types.go b/api/v1alpha1/endpointmonitor_types.go index 27ceb5a2..ab2d322c 100644 --- a/api/v1alpha1/endpointmonitor_types.go +++ b/api/v1alpha1/endpointmonitor_types.go @@ -345,7 +345,7 @@ type PingdomTransactionConfig struct { type PingdomStep struct { // contains the html element with assigned value // the key element is always lowercase for example {"url": "https://www.pingdom.com"} - // see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg + // see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@latest/pkg/pingdom/client/tmschecks#StepArg // +required Args map[string]string `json:"args"` // contains the function that is executed as part of the step diff --git a/docs/pingdom-configuration.md b/docs/pingdom-configuration.md index af3d619b..1ff654bf 100644 --- a/docs/pingdom-configuration.md +++ b/docs/pingdom-configuration.md @@ -98,18 +98,3 @@ spec: postDataEnvVar: "monitor-user" ``` -## Transaction Check - -**Example:** - -```yaml -apiVersion: endpointmonitor.stakater.com/v1alpha1 -kind: EndpointMonitor -metadata: - name: pingdom-transaction-check -spec: - pingdomTransactionConfig: - tags: - - "testing" - - "manual" -`````` diff --git a/docs/pingdom-transcation-configuration.md b/docs/pingdom-transcation-configuration.md new file mode 100644 index 00000000..7493b92e --- /dev/null +++ b/docs/pingdom-transcation-configuration.md @@ -0,0 +1,77 @@ +# Pingdom Transaction Configuration + +This document describes how to configure a Pingdom Transaction monitor using the `PingdomTransactionConfig` struct in the EndpointMonitor custom resource. + +## `PingdomTransactionConfig` Structure + +The `PingdomTransactionConfig` struct is defined as follows: + +| Field | Type | Description | +|-------|------|-------------| +| Paused | bool | Check status: active or inactive | +| CustomMessage | string | Custom message that is part of the email and webhook alerts | +| Interval | int | TMS test intervals in minutes. Allowed intervals: 5,10,20,60,720,1440 | +| Region | string | Name of the region where the check is executed. Supported regions: us-east, us-west, eu, au | +| SendNotificationWhenDown | int64 | Send notification when down X times | +| SeverityLevel | string | Check importance- how important are the alerts when the check fails. Allowed values: low, high | +| Steps | []PingdomStep | Steps to be executed as part of the check | +| Tags | []string | List of tags for a check | +| AlertIntegrations | string | `-` separated set list of integrations ids | +| AlertContacts | string | `-` separated contact id's | +| TeamAlertContacts | string | `-` separated team id's | + +Each `PingdomStep` is defined as follows: + +| Field | Type | Description | +|-------|------|-------------| +| Args | map[string]string | Contains the HTML element with assigned value | +| Function | string | Contains the function that is executed as part of the step | + +## Configuration + +To configure a Pingdom Transaction monitor, you need to specify the fields in the `PingdomTransactionConfig` section of your EndpointMonitor custom resource. + +Here's an example: + +```yaml +apiVersion: endpointmonitor.stakater.com/v1alpha1 +kind: EndpointMonitor +metadata: + name: manual-pingdom-transaction-check-karl +spec: + # url is not used, but required for ingressmonitorcontroller to work + url: https://www.google.com + pingdomTransactionConfig: + steps: + - function: go_to + args: + url: https://www.google.com + - function: fill + args: + input: textarea[name=q] + value: kubernetes + - function: submit + args: + form: form + - function: exists + args: + element: '#rso' + alertContacts: "14901866" + alertIntegrations: "132625" + #teamAlertContacts: "14901866" + custom_message: "This is a custom message" + paused: false + region: us-east + interval: 60 + send_notification_when_down: 3 + severity_level: low + tags: + - testing + - manual +``` + +In this example, we run a transaction check against Google. The check will fail if the search results page does not contain the search term "kubernetes". + +For full details on the available functions and arguments, please refer to the [Pingdom Transaction Checks API documentation](https://docs.pingdom.com/api/#section/TMS-Steps-Vocabulary/Script-transaction-checks). + +Please refer to the [Pingdom Transaction Checks API documentation](https://docs.pingdom.com/api/#operation/getAllCheckss) for more information on how to configure transaction checks. \ No newline at end of file From 8dff89665f8173e1755ce623b4ee9e97937a711a Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Sun, 21 Jan 2024 18:17:35 +0100 Subject: [PATCH 16/21] chore: update crd --- .../crds/endpointmonitor.stakater.com_endpointmonitors.yaml | 2 +- .../bases/endpointmonitor.stakater.com_endpointmonitors.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml index 4b226131..a9b6e282 100644 --- a/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -190,7 +190,7 @@ spec: type: string description: 'contains the html element with assigned value the key element is always lowercase for example {"url": - "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg' + "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@latest/pkg/pingdom/client/tmschecks#StepArg' type: object function: description: 'contains the function that is executed as diff --git a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml index 4b226131..a9b6e282 100644 --- a/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml +++ b/config/crd/bases/endpointmonitor.stakater.com_endpointmonitors.yaml @@ -190,7 +190,7 @@ spec: type: string description: 'contains the html element with assigned value the key element is always lowercase for example {"url": - "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@v1.0.0/pkg/pingdom/client/tmschecks#StepArg' + "https://www.pingdom.com"} see available values at https://pkg.go.dev/github.com/karlderkaefer/pingdom-golang-client@latest/pkg/pingdom/client/tmschecks#StepArg' type: object function: description: 'contains the function that is executed as From d18cdc56e836804855742370e399c3d49f94cce9 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Mon, 22 Jan 2024 10:33:30 +0100 Subject: [PATCH 17/21] chore: update log output for pingdom --- pkg/monitors/pingdom/pingdom-monitor.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/monitors/pingdom/pingdom-monitor.go b/pkg/monitors/pingdom/pingdom-monitor.go index f68785c4..842b69d8 100644 --- a/pkg/monitors/pingdom/pingdom-monitor.go +++ b/pkg/monitors/pingdom/pingdom-monitor.go @@ -90,7 +90,7 @@ func (service *PingdomMonitorService) Add(m models.Monitor) { _, err := service.client.Checks.Create(&httpCheck) if err != nil { - log.Info("Error Adding Monitor: " + err.Error()) + log.Info(fmt.Sprintf("Error Adding Monitor %s %v", m.Name, err.Error())) } else { log.Info("Added monitor for: " + m.Name) } @@ -123,6 +123,7 @@ func (service *PingdomMonitorService) createHttpCheck(monitor models.Monitor) pi httpCheck := pingdom.HttpCheck{} url, err := url.Parse(monitor.URL) if err != nil { + log.Info(fmt.Sprintf("Error parsing url '%s' of monitor %s", monitor.Name, service.url)) log.Info("Unable to parse the URL: " + service.url) } From 2f49d663b1089a916b936a3c431488bf4ce1fe97 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Mon, 22 Jan 2024 12:51:17 +0100 Subject: [PATCH 18/21] fix: logs need key pair values as input --- pkg/controllers/endpointmonitor_created.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/controllers/endpointmonitor_created.go b/pkg/controllers/endpointmonitor_created.go index 53f34f8a..bc00427e 100644 --- a/pkg/controllers/endpointmonitor_created.go +++ b/pkg/controllers/endpointmonitor_created.go @@ -10,9 +10,9 @@ import ( ) func (r *EndpointMonitorReconciler) handleCreate(request reconcile.Request, instance *endpointmonitorv1alpha1.EndpointMonitor, monitorName string, monitorService *monitors.MonitorServiceProxy) error { - log := r.Log.WithValues("endpointMonitor") + log := r.Log.WithValues("Namespace", instance.ObjectMeta.Namespace) - log.Info("Creating Monitor: "+monitorName, "Namespace", instance.ObjectMeta.Namespace, "MonitorType", monitorService.GetType()) + log.Info("Creating Monitor: "+monitorName, "MonitorType", monitorService.GetType()) url, err := util.GetMonitorURL(r.Client, instance) if err != nil { From ff9d48e131b438e0e76279b7df605fd9f4b4f299 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Fri, 26 Jan 2024 17:42:39 +0100 Subject: [PATCH 19/21] feat: add secret template for sensitive data (#3) --- docs/pingdom-transcation-configuration.md | 49 +++++++- pkg/kube/kube.go | 10 ++ .../pingdom-transaction-monitor.go | 96 ++++++++++++++- .../pingdom-transaction-monitor_test.go | 114 ++++++++++++++++++ 4 files changed, 265 insertions(+), 4 deletions(-) diff --git a/docs/pingdom-transcation-configuration.md b/docs/pingdom-transcation-configuration.md index 7493b92e..59cb3c00 100644 --- a/docs/pingdom-transcation-configuration.md +++ b/docs/pingdom-transcation-configuration.md @@ -37,7 +37,7 @@ Here's an example: apiVersion: endpointmonitor.stakater.com/v1alpha1 kind: EndpointMonitor metadata: - name: manual-pingdom-transaction-check-karl + name: manual-pingdom-transaction-check spec: # url is not used, but required for ingressmonitorcontroller to work url: https://www.google.com @@ -74,4 +74,49 @@ In this example, we run a transaction check against Google. The check will fail For full details on the available functions and arguments, please refer to the [Pingdom Transaction Checks API documentation](https://docs.pingdom.com/api/#section/TMS-Steps-Vocabulary/Script-transaction-checks). -Please refer to the [Pingdom Transaction Checks API documentation](https://docs.pingdom.com/api/#operation/getAllCheckss) for more information on how to configure transaction checks. \ No newline at end of file +Please refer to the [Pingdom Transaction Checks API documentation](https://docs.pingdom.com/api/#operation/getAllCheckss) for more information on how to configure transaction checks. + +## Using Passwords and Secrets + +You may have fields that contain secret values, such as passwords. To avoid storing these values in plain text, you can use a template function to reference a secret value. This makes sure that the secret value is not stored in plain text in your EndpointMonitor custom resource. + +Example: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: my-secret-name +stringData: + my-secret-key: kubernetes operator + admin-password: adminPass +--- +apiVersion: endpointmonitor.stakater.com/v1alpha1 +kind: EndpointMonitor +metadata: + name: manual-pingdom-transaction-check-with-password +spec: + url: https://www.google.com + pingdomTransactionConfig: + steps: + - function: go_to + args: + url: https://www.google.com + - function: fill + args: + input: textarea[name=q] + # this will replaced with the value of the secret before sending the request to pingdom + value: '{{secret:my-secret-name:my-secret-key}}' + - function: basic_auth + args: + user: admin + password: '{{secret:my-secret-name:admin-password}}' + - function: submit + args: + form: form + - function: exists + args: + element: '#rso' +``` + +The secret must be located in the same namespace as the IngressMonitorController. The operator can only retrieve secrets from his own namespace. The template function is only activated for the `value` and `password` fields. diff --git a/pkg/kube/kube.go b/pkg/kube/kube.go index decacdc0..fc0bdc58 100644 --- a/pkg/kube/kube.go +++ b/pkg/kube/kube.go @@ -92,3 +92,13 @@ func isOpenshift() bool { log.Info("Environment is Vanilla Kubernetes") return false } + +func GetCurrentKubernetesNamespace() string { + // Read the namespace from the file + namespace, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + if err != nil || len(namespace) == 0 { + log.Error(err, "Failed to read namespace from file") + return "" + } + return string(namespace) +} diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index a34cd691..3b7d5969 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -7,16 +7,22 @@ import ( "io" "net/http" "os" + "regexp" "strings" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" logf "sigs.k8s.io/controller-runtime/pkg/log" pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" "github.com/stakater/IngressMonitorController/v2/pkg/config" + "github.com/stakater/IngressMonitorController/v2/pkg/kube" "github.com/stakater/IngressMonitorController/v2/pkg/models" "github.com/stakater/IngressMonitorController/v2/pkg/util" + "k8s.io/client-go/kubernetes/fake" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" ) var log = logf.Log.WithName("pingdom-transaction") @@ -30,6 +36,8 @@ type PingdomTransactionMonitorService struct { teamAlertContacts string client *pingdomNew.APIClient context context.Context + kubeClient *kubernetes.Clientset + namespace string } func (monitor *PingdomTransactionMonitorService) Equal(oldMonitor models.Monitor, newMonitor models.Monitor) bool { @@ -51,6 +59,12 @@ func (service *PingdomTransactionMonitorService) Setup(p config.Provider) { cfg.SetApiToken(service.apiToken) service.client = pingdomNew.NewAPIClient(cfg) service.context = context.Background() + kubeClient, err := kube.GetClient() + if err != nil { + log.Error(err, "Error creating kubernetes client") + } + service.kubeClient = kubeClient + service.namespace = kube.GetCurrentKubernetesNamespace() } func (service *PingdomTransactionMonitorService) GetByName(name string) (*models.Monitor, error) { @@ -222,7 +236,7 @@ func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(tra transactionCheck.Interval = ptr.Int64((int64(providerConfig.Interval))) } for _, step := range providerConfig.Steps { - args := NewStepArgsByMap(step.Args) + args := service.NewStepArgsByMap(step.Args) if args != nil { transactionCheck.Steps = append(transactionCheck.Steps, pingdomNew.Step{ Args: args, @@ -234,8 +248,19 @@ func (service *PingdomTransactionMonitorService) addConfigToTranscationCheck(tra } } +// KubernetesInterface abstracts the clientset methods used +type KubernetesInterface interface { + CoreV1() corev1.CoreV1Interface +} + +// Ensure the real clientset satisfies the interface +var _ KubernetesInterface = &kubernetes.Clientset{} + +// Ensure the fake clientset satisfies the interface +var _ KubernetesInterface = &fake.Clientset{} + // NewStepArgsByMap creates a new StepArgs object from a map -func NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { +func (service *PingdomTransactionMonitorService) NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { // First, marshal the map to JSON jsonData, err := json.Marshal(input) if err != nil { @@ -248,9 +273,76 @@ func NewStepArgsByMap(input map[string]string) *pingdomNew.StepArgs { log.Error(err, "Error marshalling map to StepArgs") return nil } + // Replace secrets in the password field + err = replaceSecretValuesInArgs(&stepArgs, service.kubeClient, service.namespace) + if err != nil { + log.Error(err, "Error replacing secrets in step args") + return nil + } return &stepArgs } +// ReplaceSecretValuesInArgs replaces secrets in StepArgs with actual secret values from Kubernetes. +// It expects secrets to be formatted as {{secret:secret-name:key}} in the args. +// Returns an error if the secret or defined secret key cannot be retrieved. +func replaceSecretValuesInArgs(args *pingdomNew.StepArgs, kubeClient KubernetesInterface, namespace string) error { + if args == nil { + return nil // No arguments provided + } + // Helper function to process a single string field + processField := func(field *string) error { + if field == nil { + return nil // Skip nil fields + } + secretName, secretKey := parseSecretTemplate(*field) + if secretName != "" && secretKey != "" { + secretValue, err := getSecretValue(kubeClient, namespace, secretName, secretKey) + + if err != nil { + return fmt.Errorf("failed to get secret: %v", err) + } + *field = secretValue + } + return nil + } + // Process the Password and Input fields + if err := processField(args.Password); err != nil { + return err + } + if err := processField(args.Value); err != nil { + return err + } + + return nil +} + +// parseSecretTemplate extracts secret name and key from a string template. +func parseSecretTemplate(content string) (secretName string, secretKey string) { + const secretPattern = `{{secret:(.*):(.*)}}` + re := regexp.MustCompile(secretPattern) + + matches := re.FindStringSubmatch(content) + if len(matches) == 3 { + return matches[1], matches[2] + } + return "", "" +} + +// getSecretValue retrieves a secret value from Kubernetes. +func getSecretValue(kubeClient KubernetesInterface, namespace, secretName, secretKey string) (string, error) { + secret, err := kubeClient.CoreV1().Secrets(namespace).Get(context.Background(), secretName, v1.GetOptions{}) + if err != nil { + return "", fmt.Errorf("failed to retrieve secret %s: %v", secretName, err) + } + + secretValue, ok := secret.Data[secretKey] + if !ok { + return "", fmt.Errorf("secret %s does not contain key %s", secretName, secretKey) + } + + return string(secretValue), nil +} + // parseIDs splits a string of IDs into an array of integers func parseIDs(field string) []int64 { if len(field) > 0 { diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go index e01eda1a..d3d39580 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go @@ -1,12 +1,18 @@ package pingdomtransaction import ( + "context" "testing" + pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" + "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" "github.com/stakater/IngressMonitorController/v2/pkg/config" "github.com/stakater/IngressMonitorController/v2/pkg/models" "github.com/stakater/IngressMonitorController/v2/pkg/util" "gotest.tools/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" ) @@ -88,5 +94,113 @@ func TestUpdateMonitorWithCorrectValues(t *testing.T) { assert.Equal(t, mRes.Name, m.Name) assert.Equal(t, mRes.URL, "https://facebook.com") +} + +func TestGetSecretFromTemplate(t *testing.T) { + var tests = []struct { + name string + content string + expectedSecretName string + expectedSecretKey string + }{ + { + name: "With Secret", + content: "This is a sample content with {{secret:my-secret:my-key}} embedded in it.", + expectedSecretName: "my-secret", + expectedSecretKey: "my-key", + }, + { + name: "No Secret", + content: "This is a sample content without any secret.", + expectedSecretName: "", + expectedSecretKey: "", + }, + { + name: "Invalid Format", + content: "This is a sample content with invalid secret format {{secret:my-secret}}", + expectedSecretName: "", + expectedSecretKey: "", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + secretName, secretKey := parseSecretTemplate(tc.content) + assert.Equal(t, secretName, tc.expectedSecretName) + assert.Equal(t, secretKey, tc.expectedSecretKey) + }) + } +} + +func TestReplaceSecrets(t *testing.T) { + // Create a fake clientset + clientset := fake.NewSimpleClientset() + + // Create and add a secret to the fake clientset + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + "username": []byte("admin"), + "password": []byte("simple-password"), + }, + } + _, err := clientset.CoreV1().Secrets("default").Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error injecting secret add: %v", err) + } + + // Define test cases + testCases := []struct { + name string + password string + value string + expectedPassword string + expectedValue string + expectError bool + }{ + { + name: "Password field with secret", + password: "{{secret:my-secret:password}}", + value: "{{secret:my-secret:username}}", + expectedPassword: "simple-password", + expectedValue: "admin", + expectError: false, + }, + { + name: "Password field without secret", + value: "no-secret", + password: "no-secret", + expectedPassword: "no-secret", + expectedValue: "no-secret", + expectError: false, + }, + { + name: "Password field with invalid secret", + password: "{{secret:my-secret:invalidkey}}", + value: "no-secret", + expectedPassword: "", + expectedValue: "no-secret", + expectError: true, + }, + } + + // Run test cases + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + args := &pingdomNew.StepArgs{ + Password: ptr.String(tc.password), + Value: ptr.String(tc.value), + } + err := replaceSecretValuesInArgs(args, clientset, secret.Namespace) + if tc.expectError { + assert.Error(t, err, "failed to get secret: secret my-secret does not contain key invalidkey") + return + } + assert.Equal(t, *args.Password, tc.expectedPassword) + assert.Equal(t, *args.Value, tc.expectedValue) + }) + } } From c06ff6e38c6e2b875d9b91ebac20e33ac2d3bdf8 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Tue, 30 Jan 2024 13:31:28 +0100 Subject: [PATCH 20/21] fix: use helm compatible template for secrets --- docs/pingdom-transcation-configuration.md | 4 +- .../pingdom-transaction-monitor.go | 6 +- .../pingdom-transaction-monitor_test.go | 69 ++++++------------- 3 files changed, 27 insertions(+), 52 deletions(-) diff --git a/docs/pingdom-transcation-configuration.md b/docs/pingdom-transcation-configuration.md index 59cb3c00..d33074d1 100644 --- a/docs/pingdom-transcation-configuration.md +++ b/docs/pingdom-transcation-configuration.md @@ -106,11 +106,11 @@ spec: args: input: textarea[name=q] # this will replaced with the value of the secret before sending the request to pingdom - value: '{{secret:my-secret-name:my-secret-key}}' + value: '{secret:my-secret-name:my-secret-key}' - function: basic_auth args: user: admin - password: '{{secret:my-secret-name:admin-password}}' + password: '{secret:my-secret-name:admin-password}' - function: submit args: form: form diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go index 3b7d5969..17c409d4 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor.go @@ -160,7 +160,7 @@ func (service *PingdomTransactionMonitorService) createTransactionCheck(monitor providerConfig, _ := monitor.Config.(*endpointmonitorv1alpha1.PingdomTransactionConfig) if providerConfig == nil { // ignore monitor if type is not PingdomTransaction - log.Info("Monitor is not PingdomTransaction type" + monitor.Name) + log.Info("Monitor is not PingdomTransaction type " + monitor.Name) return nil } transactionCheck.Name = monitor.Name @@ -283,7 +283,7 @@ func (service *PingdomTransactionMonitorService) NewStepArgsByMap(input map[stri } // ReplaceSecretValuesInArgs replaces secrets in StepArgs with actual secret values from Kubernetes. -// It expects secrets to be formatted as {{secret:secret-name:key}} in the args. +// It expects secrets to be formatted as {secret:secret-name:key} in the args. // Returns an error if the secret or defined secret key cannot be retrieved. func replaceSecretValuesInArgs(args *pingdomNew.StepArgs, kubeClient KubernetesInterface, namespace string) error { if args == nil { @@ -318,7 +318,7 @@ func replaceSecretValuesInArgs(args *pingdomNew.StepArgs, kubeClient KubernetesI // parseSecretTemplate extracts secret name and key from a string template. func parseSecretTemplate(content string) (secretName string, secretKey string) { - const secretPattern = `{{secret:(.*):(.*)}}` + const secretPattern = `{secret:(.*):(.*)}` re := regexp.MustCompile(secretPattern) matches := re.FindStringSubmatch(content) diff --git a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go index d3d39580..2a00a9a0 100644 --- a/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go +++ b/pkg/monitors/pingdomtransaction/pingdom-transaction-monitor_test.go @@ -6,6 +6,7 @@ import ( pingdomNew "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi" "github.com/karlderkaefer/pingdom-golang-client/pkg/pingdom/openapi/ptr" + endpointmonitorv1alpha1 "github.com/stakater/IngressMonitorController/v2/api/v1alpha1" "github.com/stakater/IngressMonitorController/v2/pkg/config" "github.com/stakater/IngressMonitorController/v2/pkg/models" "github.com/stakater/IngressMonitorController/v2/pkg/util" @@ -34,47 +35,27 @@ func TestAddMonitorWithCorrectValues(t *testing.T) { log.Error(nil, "Failed to find provider") return } - - service.Setup(*provider) - m := models.Monitor{Name: "google-test", URL: "https://google1.com"} - - service.Add(m) - - mRes, err := service.GetByName("google-test") - assert.NilError(t, err) - - defer func() { - // Cleanup - service.Remove(*mRes) - }() - - if err != nil { - t.Error("Error: " + err.Error()) + spec := &endpointmonitorv1alpha1.PingdomTransactionConfig{ + Steps: []endpointmonitorv1alpha1.PingdomStep{ + { + Function: "go_to", + Args: map[string]string{ + "url": "https://google.com", + }, + }, + }, } - assert.Equal(t, mRes.Name, m.Name) - assert.Equal(t, mRes.URL, "https://google1.com") -} - -func TestUpdateMonitorWithCorrectValues(t *testing.T) { - config := config.GetControllerConfigTest() - - service := PingdomTransactionMonitorService{} - - provider := util.GetProviderWithName(config, "Pingdom") - if provider == nil { - // TODO: Currently forcing to pass the test as we dont have Pingdom account to test - // Fail this case in future when have a valid Pingdom account - log.Error(nil, "Failed to find provider") - return - } service.Setup(*provider) + m := models.Monitor{ + Name: "google-test", + URL: "https://google.com", + Config: spec, + } - // Create initial record - m := models.Monitor{Name: "google-update-test", URL: "https://google.com"} service.Add(m) - mRes, err := service.GetByName("google-update-test") + mRes, err := service.GetByName("google-test") assert.NilError(t, err) defer func() { @@ -82,18 +63,12 @@ func TestUpdateMonitorWithCorrectValues(t *testing.T) { service.Remove(*mRes) }() - // Update the record - mRes.URL = "https://facebook.com" - - service.Update(*mRes) - - mRes, err = service.GetByName("google-update-test") if err != nil { t.Error("Error: " + err.Error()) } assert.Equal(t, mRes.Name, m.Name) - assert.Equal(t, mRes.URL, "https://facebook.com") + assert.Equal(t, mRes.URL, "https://google.com") } func TestGetSecretFromTemplate(t *testing.T) { @@ -105,7 +80,7 @@ func TestGetSecretFromTemplate(t *testing.T) { }{ { name: "With Secret", - content: "This is a sample content with {{secret:my-secret:my-key}} embedded in it.", + content: "This is a sample content with {secret:my-secret:my-key} embedded in it.", expectedSecretName: "my-secret", expectedSecretKey: "my-key", }, @@ -117,7 +92,7 @@ func TestGetSecretFromTemplate(t *testing.T) { }, { name: "Invalid Format", - content: "This is a sample content with invalid secret format {{secret:my-secret}}", + content: "This is a sample content with invalid secret format {secret:my-secret}", expectedSecretName: "", expectedSecretKey: "", }, @@ -163,8 +138,8 @@ func TestReplaceSecrets(t *testing.T) { }{ { name: "Password field with secret", - password: "{{secret:my-secret:password}}", - value: "{{secret:my-secret:username}}", + password: "{secret:my-secret:password}", + value: "{secret:my-secret:username}", expectedPassword: "simple-password", expectedValue: "admin", expectError: false, @@ -179,7 +154,7 @@ func TestReplaceSecrets(t *testing.T) { }, { name: "Password field with invalid secret", - password: "{{secret:my-secret:invalidkey}}", + password: "{secret:my-secret:invalidkey}", value: "no-secret", expectedPassword: "", expectedValue: "no-secret", From 08fa1fdc6e50679ffd5f964697aa56ea399d8163 Mon Sep 17 00:00:00 2001 From: karlderkaefer Date: Mon, 10 Jun 2024 09:24:41 +0200 Subject: [PATCH 21/21] chore: update go mod --- go.mod | 2 +- go.sum | 73 ++++------------------------------------------------------ 2 files changed, 5 insertions(+), 70 deletions(-) diff --git a/go.mod b/go.mod index 91b0c947..b4b408b1 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-logr/logr v1.4.1 github.com/grafana/synthetic-monitoring-agent v0.19.4 github.com/grafana/synthetic-monitoring-api-go-client v0.8.0 + github.com/karlderkaefer/pingdom-golang-client v1.0.4 github.com/kelseyhightower/envconfig v1.4.0 github.com/openshift/api v0.0.0-20200526144822-34f54f12813a github.com/patrickmn/go-cache v2.1.0+incompatible @@ -69,7 +70,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index d85a7d81..4e1ab388 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= @@ -33,8 +31,6 @@ cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2Aawl cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58= -cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= cloud.google.com/go/monitoring v1.16.3 h1:mf2SN9qSoBtIgiMA4R/y4VADPWZA7VCNJA079qLaZQ8= cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -132,11 +128,7 @@ 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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= @@ -157,7 +149,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -181,7 +172,6 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -214,7 +204,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -300,8 +289,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -322,25 +309,17 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -351,12 +330,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/synthetic-monitoring-agent v0.18.2 h1:YW92rw38q3QB2dY34UK+O0a/735PlHLk4zWcOzrTro0= -github.com/grafana/synthetic-monitoring-agent v0.18.2/go.mod h1:TZzTibceWuSz/vb8K8JpdfAucuMctDCAKN7R0EaDIO4= github.com/grafana/synthetic-monitoring-agent v0.19.4 h1:6L3Nb9Sw1XmIs7jPcbquTilWUc+H63MvFFpNXIYzymA= github.com/grafana/synthetic-monitoring-agent v0.19.4/go.mod h1:9S3Yx8EMaluA90aD4YCJnJH/Xpk+SMgMGd7NWdn41Lg= -github.com/grafana/synthetic-monitoring-api-go-client v0.7.0 h1:3ZfQzmXDBPcQTTgMAIIiTw5Dwxm/B4lzf34Sto0d0YY= -github.com/grafana/synthetic-monitoring-api-go-client v0.7.0/go.mod h1:ET64tbp14yq3U8X97/IO/KbG+FqU5Z8DigWrzGUHX40= github.com/grafana/synthetic-monitoring-api-go-client v0.8.0 h1:Tm4MtwwYmPNInGfnj66l6j6KOshMkNV4emIVKJdlXMg= github.com/grafana/synthetic-monitoring-api-go-client v0.8.0/go.mod h1:TGaywTdL2Z+PJhpWzJEmJFRF5K55vKz2f39mWY/GvV8= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -449,8 +424,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -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/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -513,7 +486,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -525,16 +497,12 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -543,8 +511,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -554,8 +520,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -668,14 +632,12 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -700,9 +662,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -715,6 +674,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -794,10 +755,6 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -813,8 +770,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -829,8 +784,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -905,14 +858,10 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1030,8 +979,6 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1040,7 +987,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= @@ -1091,16 +1037,10 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1125,9 +1065,6 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1143,8 +1080,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=