diff --git a/agent/config/config.go b/agent/config/config.go index 4fbe3658..50209ccd 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -6,8 +6,15 @@ import ( ) type AgentConfigurations struct { - SANamespace string `envconfig:"SA_NAMESPACE" default:"default"` - SAName string `envconfig:"SA_NAME" default:"default"` + SANamespace string `envconfig:"SA_NAMESPACE" default:"default"` + SAName string `envconfig:"SA_NAME" default:"default"` + OutdatedInterval string `envconfig:"OUTDATED_INTERVAL" default:"*/20 * * * *"` + GetAllInterval string `envconfig:"GETALL_INTERVAL" default:"*/30 * * * *"` + KubeScoreInterval string `envconfig:"KUBESCORE_INTERVAL" default:"*/40 * * * *"` + RakkessInterval string `envconfig:"RAKKESS_INTERVAL" default:"*/50 * * * *"` + KubePreUpgradeInterval string `envconfig:"KUBEPREUPGRADE_INTERVAL" default:"*/60 * * * *"` + TrivyInterval string `envconfig:"TRIVY_INTERVAL" default:"*/10 * * * *"` + SchedulerEnable bool `envconfig:"SCHEDULER_ENABLE" default:"false"` } func GetAgentConfigurations() (serviceConf *AgentConfigurations, err error) { diff --git a/agent/kubviz/k8smetrics_agent.go b/agent/kubviz/k8smetrics_agent.go index f86d163f..a807bac2 100644 --- a/agent/kubviz/k8smetrics_agent.go +++ b/agent/kubviz/k8smetrics_agent.go @@ -4,10 +4,14 @@ import ( "encoding/json" "log" "os" + "os/signal" "strconv" "strings" + "syscall" "time" + "github.com/intelops/go-common/logging" + "github.com/go-co-op/gocron" "github.com/nats-io/nats.go" @@ -22,6 +26,7 @@ import ( "fmt" + "github.com/intelops/kubviz/agent/config" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/fields" _ "k8s.io/client-go/plugin/pkg/client/auth/azure" @@ -77,6 +82,10 @@ func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) env := Production clusterMetricsChan := make(chan error, 1) + cfg, err := config.GetAgentConfigurations() + if err != nil { + log.Fatal("Failed to retrieve agent configurations", err) + } var ( config *rest.Config clientset *kubernetes.Clientset @@ -126,15 +135,30 @@ func main() { if schedulingIntervalStr == "" { schedulingIntervalStr = "20m" } - schedulingInterval, err := time.ParseDuration(schedulingIntervalStr) - if err != nil { - log.Fatalf("Failed to parse SCHEDULING_INTERVAL: %v", err) + if cfg.SchedulerEnable { // Assuming "cfg.Schedule" is a boolean indicating whether to schedule or not. + scheduler := initScheduler(config, js, *cfg, clientset) + + // Start the scheduler + scheduler.Start() + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + <-signals + + scheduler.Stop() + } else { + if schedulingIntervalStr == "" { + schedulingIntervalStr = "20m" + } + schedulingInterval, err := time.ParseDuration(schedulingIntervalStr) + if err != nil { + log.Fatalf("Failed to parse SCHEDULING_INTERVAL: %v", err) + } + s := gocron.NewScheduler(time.UTC) + s.Every(schedulingInterval).Do(func() { + collectAndPublishMetrics() + }) + s.StartBlocking() } - s := gocron.NewScheduler(time.UTC) - s.Every(schedulingInterval).Do(func() { - collectAndPublishMetrics() - }) - s.StartBlocking() } // publishMetrics publishes stream of events @@ -272,3 +296,68 @@ func watchK8sEvents(clientset *kubernetes.Clientset, js nats.JetStreamContext) { time.Sleep(time.Second) } } +func initScheduler(config *rest.Config, js nats.JetStreamContext, cfg config.AgentConfigurations, clientset *kubernetes.Clientset) (s *Scheduler) { + log := logging.NewLogger() + s = NewScheduler(log) + if cfg.OutdatedInterval != "" { + sj, err := NewOutDatedImagesJob(config, js, cfg.OutdatedInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("Outdated", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + if cfg.GetAllInterval != "" { + sj, err := NewKetallJob(config, js, cfg.GetAllInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("GetALL", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + if cfg.KubeScoreInterval != "" { + sj, err := NewKubescoreJob(clientset, js, cfg.KubeScoreInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("KubeScore", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + if cfg.RakkessInterval != "" { + sj, err := NewRakkessJob(config, js, cfg.RakkessInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("Rakkess", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + if cfg.KubePreUpgradeInterval != "" { + sj, err := NewKubePreUpgradeJob(config, js, cfg.KubePreUpgradeInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("KubePreUpgrade", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + if cfg.TrivyInterval != "" { + sj, err := NewTrivyJob(config, js, cfg.TrivyInterval) + if err != nil { + log.Fatal("no time interval", err) + } + err = s.AddJob("Trivy", sj) + if err != nil { + log.Fatal("failed to do job", err) + } + } + return +} diff --git a/agent/kubviz/scheduler.go b/agent/kubviz/scheduler.go new file mode 100644 index 00000000..ce9b96d3 --- /dev/null +++ b/agent/kubviz/scheduler.go @@ -0,0 +1,88 @@ +package main + +import ( + "sync" + + "github.com/pkg/errors" + "github.com/robfig/cron/v3" + + "github.com/intelops/go-common/logging" +) + +type jobHandler interface { + CronSpec() string + Run() +} + +type Scheduler struct { + log logging.Logger + jobs map[string]jobHandler + cronIDs map[string]cron.EntryID + c *cron.Cron + cronMutex *sync.Mutex +} + +func NewScheduler(log logging.Logger) *Scheduler { + clog := cron.VerbosePrintfLogger(log.(logging.StdLogger)) + return &Scheduler{ + log: log, + c: cron.New(cron.WithChain(cron.SkipIfStillRunning(clog), cron.Recover(clog))), + jobs: map[string]jobHandler{}, + cronIDs: map[string]cron.EntryID{}, + cronMutex: &sync.Mutex{}, + } +} + +func (t *Scheduler) AddJob(jobName string, job jobHandler) error { + t.cronMutex.Lock() + defer t.cronMutex.Unlock() + _, ok := t.cronIDs[jobName] + if ok { + return errors.Errorf("%s job already exists", jobName) + } + spec := job.CronSpec() + if spec == "" { + return errors.Errorf("%s job has no cron spec", jobName) + } + entryID, err := t.c.AddJob(spec, job) + if err != nil { + return errors.WithMessagef(err, "%s job cron spec not valid", jobName) + } + + t.jobs[jobName] = job + t.cronIDs[jobName] = entryID + t.log.Infof("%s job added with cron '%s'", jobName, spec) + return nil +} + +// RemoveJob ... +func (t *Scheduler) RemoveJob(jobName string) error { + t.cronMutex.Lock() + defer t.cronMutex.Unlock() + entryID, ok := t.cronIDs[jobName] + if !ok { + return errors.Errorf("%s job not exist", jobName) + } + + t.c.Remove(entryID) + delete(t.jobs, jobName) + delete(t.cronIDs, jobName) + t.log.Infof("%s job removed", jobName) + return nil +} + +func (t *Scheduler) Start() { + t.c.Start() + t.log.Infof("Job scheduler started") +} + +func (t *Scheduler) Stop() { + t.c.Stop() + t.log.Infof("Job scheduler stopped") +} + +func (t *Scheduler) GetJobs() map[string]jobHandler { + t.cronMutex.Lock() + defer t.cronMutex.Unlock() + return t.jobs +} diff --git a/agent/kubviz/scheduler_watch.go b/agent/kubviz/scheduler_watch.go new file mode 100644 index 00000000..90de3d25 --- /dev/null +++ b/agent/kubviz/scheduler_watch.go @@ -0,0 +1,138 @@ +package main + +import ( + "github.com/nats-io/nats.go" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +type OutDatedImagesJob struct { + config *rest.Config + js nats.JetStreamContext + frequency string +} + +type KetallJob struct { + config *rest.Config + js nats.JetStreamContext + frequency string +} +type TrivyJob struct { + config *rest.Config + js nats.JetStreamContext + frequency string +} +type RakkessJob struct { + config *rest.Config + js nats.JetStreamContext + frequency string +} +type KubePreUpgradeJob struct { + config *rest.Config + js nats.JetStreamContext + frequency string +} +type KubescoreJob struct { + clientset *kubernetes.Clientset + js nats.JetStreamContext + frequency string +} + +func NewOutDatedImagesJob(config *rest.Config, js nats.JetStreamContext, frequency string) (*OutDatedImagesJob, error) { + return &OutDatedImagesJob{ + config: config, + js: js, + frequency: frequency, + }, nil +} +func (v *OutDatedImagesJob) CronSpec() string { + return v.frequency +} + +func (j *OutDatedImagesJob) Run() { + // Call the outDatedImages function with the provided config and js + err := outDatedImages(j.config, j.js) + LogErr(err) +} +func NewKetallJob(config *rest.Config, js nats.JetStreamContext, frequency string) (*KetallJob, error) { + return &KetallJob{ + config: config, + js: js, + frequency: frequency, + }, nil +} +func (v *KetallJob) CronSpec() string { + return v.frequency +} + +func (j *KetallJob) Run() { + // Call the Ketall function with the provided config and js + err := GetAllResources(j.config, j.js) + LogErr(err) +} + +func NewKubePreUpgradeJob(config *rest.Config, js nats.JetStreamContext, frequency string) (*KubePreUpgradeJob, error) { + return &KubePreUpgradeJob{ + config: config, + js: js, + frequency: frequency, + }, nil +} +func (v *KubePreUpgradeJob) CronSpec() string { + return v.frequency +} + +func (j *KubePreUpgradeJob) Run() { + // Call the Kubepreupgrade function with the provided config and js + err := GetAllResources(j.config, j.js) + LogErr(err) +} + +func NewKubescoreJob(clientset *kubernetes.Clientset, js nats.JetStreamContext, frequency string) (*KubescoreJob, error) { + return &KubescoreJob{ + clientset: clientset, + js: js, + frequency: frequency, + }, nil +} +func (v *KubescoreJob) CronSpec() string { + return v.frequency +} + +func (j *KubescoreJob) Run() { + // Call the Kubescore function with the provided config and js + err := RunKubeScore(j.clientset, j.js) + LogErr(err) +} +func NewRakkessJob(config *rest.Config, js nats.JetStreamContext, frequency string) (*RakkessJob, error) { + return &RakkessJob{ + config: config, + js: js, + frequency: frequency, + }, nil +} +func (v *RakkessJob) CronSpec() string { + return v.frequency +} + +func (j *RakkessJob) Run() { + // Call the Rakkes function with the provided config and js + err := RakeesOutput(j.config, j.js) + LogErr(err) +} +func NewTrivyJob(config *rest.Config, js nats.JetStreamContext, frequency string) (*TrivyJob, error) { + return &TrivyJob{ + config: config, + js: js, + frequency: frequency, + }, nil +} +func (v *TrivyJob) CronSpec() string { + return v.frequency +} + +func (j *TrivyJob) Run() { + // Call the Trivy function with the provided config and js + err := runTrivyScans(j.config, j.js) + LogErr(err) +} diff --git a/agent/kubviz/trivy.go b/agent/kubviz/trivy.go index adaf84ef..46248c8a 100644 --- a/agent/kubviz/trivy.go +++ b/agent/kubviz/trivy.go @@ -1,8 +1,10 @@ package main import ( + "bytes" "encoding/json" "log" + exec "os/exec" "strings" "github.com/aquasecurity/trivy/pkg/k8s/report" @@ -12,11 +14,38 @@ import ( "github.com/nats-io/nats.go" ) +func executeCommandTrivy(command string) ([]byte, error) { + cmd := exec.Command("/bin/sh", "-c", command) + var outc, errc bytes.Buffer + cmd.Stdout = &outc + cmd.Stderr = &errc + + err := cmd.Run() + + if err != nil { + log.Println("Execute Trivy Command Error", err.Error()) + } + + return outc.Bytes(), err +} func RunTrivyK8sClusterScan(js nats.JetStreamContext) error { var report report.ConsolidatedReport - out, err := executeCommand("trivy k8s --report summary cluster --timeout 60m -f json -q --cache-dir /tmp/.cache") - // log.Println("Commnd for k8s cluster scan: trivy k8s --report summary cluster --timeout 60m -f json -q --cache-dir /tmp/.cache") - parts := strings.SplitN(out, "{", 2) + cmdString := "trivy k8s --report summary cluster --exclude-nodes kubernetes.io/arch:amd64 --timeout 20m -f json --cache-dir /tmp/.cache --debug" + + // Log the command before execution + log.Printf("Executing command: %s\n", cmdString) + + // Execute the command + out, err := executeCommandTrivy(cmdString) + + // Handle errors and process the command output as needed + if err != nil { + log.Printf("Error executing command: %v\n", err) + } + // Log the command output for debugging purposes + log.Printf("Command output: %s\n", out) + outStr := string(out) + parts := strings.SplitN(outStr, "{", 2) if len(parts) <= 1 { log.Println("No output from k8s cluster scan command", err) return err diff --git a/go.mod b/go.mod index 414c54bb..df47ddff 100644 --- a/go.mod +++ b/go.mod @@ -17,12 +17,14 @@ require ( github.com/golang-migrate/migrate/v4 v4.16.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-version v1.6.0 + github.com/intelops/go-common v1.0.19 github.com/kelseyhightower/envconfig v1.4.0 github.com/nats-io/nats.go v1.27.1 github.com/pkg/errors v0.9.1 + github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 - golang.org/x/term v0.10.0 + golang.org/x/term v0.11.0 k8s.io/api v0.27.3 k8s.io/apimachinery v0.27.3 k8s.io/cli-runtime v0.27.3 @@ -31,6 +33,9 @@ require ( ) require ( + cloud.google.com/go v0.110.6 // indirect + cloud.google.com/go/iam v1.1.1 // indirect + cloud.google.com/go/storage v1.30.1 // indirect github.com/ClickHouse/ch-go v0.52.1 // indirect github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 // indirect github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect @@ -70,6 +75,7 @@ require ( github.com/google/go-containerregistry v0.15.2 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -108,10 +114,10 @@ require ( github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect github.com/samber/lo v1.38.1 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/showa-93/go-mask v0.6.0 // indirect github.com/spdx/tools-golang v0.5.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect @@ -128,15 +134,18 @@ require ( go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.12.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect - golang.org/x/net v0.11.0 // indirect - golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/oauth2 v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.126.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 1570851a..b8b6d6ff 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= -cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= +cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= @@ -11,6 +14,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/ClickHouse/ch-go v0.52.1 h1:nucdgfD1BDSHjbNaG3VNebonxJzD8fX8jbuBpfo5VY0= github.com/ClickHouse/ch-go v0.52.1/go.mod h1:B9htMJ0hii/zrC2hljUKdnagRBuLqtRG/GrU3jqCwRk= +github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= github.com/ClickHouse/clickhouse-go/v2 v2.10.1 h1:WCnusqEeCO/9sLFVIv57le/O1ydUb+x9+SYYhJ11fsY= github.com/ClickHouse/clickhouse-go/v2 v2.10.1/go.mod h1:teXfZNM90iQ99Jnuht+dxQXCuhDZ8nvvMoTJOFrcmcg= github.com/CycloneDX/cyclonedx-go v0.7.2-0.20230625092137-07e2f29defc3 h1:NqeV+ZMqpcosu0Xg2VW14Ru9ayBs/toe2oihS7sN6Xo= @@ -76,6 +80,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/containerd/containerd v1.2.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -90,6 +95,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw= github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/docker/cli v0.0.0-20190913211141-95327f4e6241/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v23.0.5+incompatible h1:ufWmAOuD3Vmr7JP2G5K3cyuNC4YZWiAsuDEvFVVDafE= @@ -216,13 +222,14 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licenseclassifier/v2 v2.0.0 h1:1Y57HHILNf4m0ABuMVb6xk4vAJYEUO0gDxNpog0pyeA= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc= +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/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -248,6 +255,8 @@ github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/intelops/go-common v1.0.19 h1:K53TIISpeTONS4g1squwGvo+1wmSbv2Kqp31mpw1090= +github.com/intelops/go-common v1.0.19/go.mod h1:GDDr2xP2uqtjMgATC4BLDt29kC7W9R3EW+8Du2LlNt8= github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -404,6 +413,8 @@ github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/showa-93/go-mask v0.6.0 h1:nNW3dgEocYB7QCGzgRx9wlYrepEg+tRw/keg7u1ftY8= +github.com/showa-93/go-mask v0.6.0/go.mod h1:aswIj007gm0EPAzOGES9ACy1jDm3QT08/LPSClMp410= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -487,8 +498,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= @@ -509,11 +520,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -537,18 +548,18 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/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.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -568,7 +579,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.121.0 h1:8Oopoo8Vavxx6gt+sgs8s8/X60WBAtKQq6JqnkF+xow= +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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -577,12 +589,16 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=