From 18d06bc7fb5d38a45776cf44643898b38e27d9c0 Mon Sep 17 00:00:00 2001 From: Valentyna Bukhalova Date: Fri, 18 Oct 2024 11:03:27 +0200 Subject: [PATCH] KUBE-566: refactor before multi cmd (#142) * nojira: refactor before multi cmd * set tls min version --- .github/workflows/golangci-lint.yaml | 6 +- .golangci.yaml | 93 ++ Makefile | 12 + actions/actions_test.go | 214 ---- actions/create_event_handler.go | 80 -- castai/logexporter_test.go | 49 - castai/mock/client.go | 62 -- go.mod | 165 ++-- go.sum | 925 ++++-------------- health/healthz.go | 4 +- health/healthz_test.go | 6 +- .../actions}/approve_csr_handler.go | 24 +- .../actions}/approve_csr_handler_test.go | 16 +- .../actions}/chart_rollback_handler.go | 16 +- .../actions}/chart_rollback_handler_test.go | 10 +- .../actions}/chart_uninstall_handler.go | 16 +- .../actions}/chart_uninstall_handler_test.go | 10 +- .../actions}/chart_upsert_handler.go | 17 +- .../actions}/chart_upsert_handler_test.go | 10 +- .../actions}/check_node_deleted.go | 16 +- .../actions}/check_node_handler_test.go | 9 +- .../actions}/check_node_status.go | 25 +- .../actions}/check_node_status_test.go | 23 +- internal/actions/create_event_handler.go | 108 ++ .../actions}/create_event_handler_test.go | 83 +- .../actions}/create_handler.go | 18 +- .../actions}/create_handler_test.go | 4 +- {csr => internal/actions/csr}/csr.go | 9 +- {csr => internal/actions/csr}/csr_test.go | 0 {csr => internal/actions/csr}/svc.go | 5 +- {csr => internal/actions/csr}/svc_test.go | 10 +- .../actions}/delete_handler.go | 12 +- .../actions}/delete_handler_test.go | 4 +- .../actions}/delete_node_handler.go | 25 +- .../actions}/delete_node_handler_test.go | 16 +- .../actions}/disconnect_cluster_handler.go | 17 +- .../disconnect_cluster_handler_test.go | 6 +- .../actions}/drain_node_handler.go | 44 +- .../actions}/drain_node_handler_test.go | 47 +- .../actions}/kubernetes_helpers.go | 6 +- internal/actions/mock/handler.go | 50 + internal/actions/mock/kubernetes.go | 844 ++++++++++++++++ .../actions}/patch_handler.go | 14 +- .../actions}/patch_handler_test.go | 4 +- .../actions}/patch_node_handler.go | 16 +- .../actions}/patch_node_handler_test.go | 8 +- .../actions}/send_aks_init_data_handler.go | 37 +- .../send_aks_init_data_handler_test.go | 24 +- internal/actions/types.go | 23 + {castai => internal/castai}/client.go | 26 +- {castai => internal/castai}/client_test.go | 0 internal/castai/mock/client.go | 79 ++ {castai => internal/castai}/types.go | 6 +- {config => internal/config}/config.go | 6 +- {config => internal/config}/config_test.go | 2 +- {config => internal/config}/version.go | 0 .../controller/controller.go | 105 +- internal/controller/controller_test.go | 236 +++++ {helm => internal/helm}/chart_loader.go | 4 +- {helm => internal/helm}/chart_loader_test.go | 2 +- {helm => internal/helm}/client.go | 4 +- {helm => internal/helm}/client_test.go | 2 +- {helm => internal/helm}/hook/hook.go | 2 +- {helm => internal/helm}/hook/hook_test.go | 5 +- .../helm}/hook/mock/kube_client.go | 4 +- {helm => internal/helm}/mock/chart_loader.go | 10 +- {helm => internal/helm}/mock/client.go | 12 +- .../k8sversion}/mock/version.go | 4 +- {version => internal/k8sversion}/version.go | 2 +- .../k8sversion}/version_test.go | 2 +- .../logexporter}/logexporter.go | 18 +- internal/logexporter/logexporter_test.go | 81 ++ internal/logexporter/mock/sender.go | 50 + ...D209E745FE4FC85066CBA305F32F9A1CFD89A3.prv | 0 .../config/1.settings | 0 .../testdata}/aks/ovf-env.xml | 0 {waitext => internal/waitext}/doc.go | 0 {waitext => internal/waitext}/extensions.go | 12 +- .../waitext}/extensions_test.go | 4 +- main.go | 50 +- 80 files changed, 2349 insertions(+), 1621 deletions(-) create mode 100644 .golangci.yaml delete mode 100644 actions/actions_test.go delete mode 100644 actions/create_event_handler.go delete mode 100644 castai/logexporter_test.go delete mode 100644 castai/mock/client.go rename {actions => internal/actions}/approve_csr_handler.go (84%) rename {actions => internal/actions}/approve_csr_handler_test.go (96%) rename {actions => internal/actions}/chart_rollback_handler.go (67%) rename {actions => internal/actions}/chart_rollback_handler_test.go (90%) rename {actions => internal/actions}/chart_uninstall_handler.go (63%) rename {actions => internal/actions}/chart_uninstall_handler_test.go (89%) rename {actions => internal/actions}/chart_upsert_handler.go (82%) rename {actions => internal/actions}/chart_upsert_handler_test.go (93%) rename {actions => internal/actions}/check_node_deleted.go (81%) rename {actions => internal/actions}/check_node_handler_test.go (91%) rename {actions => internal/actions}/check_node_status.go (85%) rename {actions => internal/actions}/check_node_status_test.go (95%) create mode 100644 internal/actions/create_event_handler.go rename {actions => internal/actions}/create_event_handler_test.go (73%) rename {actions => internal/actions}/create_handler.go (85%) rename {actions => internal/actions}/create_handler_test.go (98%) rename {csr => internal/actions/csr}/csr.go (98%) rename {csr => internal/actions/csr}/csr_test.go (100%) rename {csr => internal/actions/csr}/svc.go (97%) rename {csr => internal/actions/csr}/svc_test.go (97%) rename {actions => internal/actions}/delete_handler.go (80%) rename {actions => internal/actions}/delete_handler_test.go (97%) rename {actions => internal/actions}/delete_node_handler.go (90%) rename {actions => internal/actions}/delete_node_handler_test.go (93%) rename {actions => internal/actions}/disconnect_cluster_handler.go (70%) rename {actions => internal/actions}/disconnect_cluster_handler_test.go (87%) rename {actions => internal/actions}/drain_node_handler.go (93%) rename {actions => internal/actions}/drain_node_handler_test.go (96%) rename {actions => internal/actions}/kubernetes_helpers.go (98%) create mode 100644 internal/actions/mock/handler.go create mode 100644 internal/actions/mock/kubernetes.go rename {actions => internal/actions}/patch_handler.go (84%) rename {actions => internal/actions}/patch_handler_test.go (97%) rename {actions => internal/actions}/patch_node_handler.go (89%) rename {actions => internal/actions}/patch_node_handler_test.go (96%) rename {actions => internal/actions}/send_aks_init_data_handler.go (77%) rename {actions => internal/actions}/send_aks_init_data_handler_test.go (51%) create mode 100644 internal/actions/types.go rename {castai => internal/castai}/client.go (88%) rename {castai => internal/castai}/client_test.go (100%) create mode 100644 internal/castai/mock/client.go rename {castai => internal/castai}/types.go (98%) rename {config => internal/config}/config.go (96%) rename {config => internal/config}/config_test.go (97%) rename {config => internal/config}/version.go (100%) rename actions/actions.go => internal/controller/controller.go (60%) create mode 100644 internal/controller/controller_test.go rename {helm => internal/helm}/chart_loader.go (96%) rename {helm => internal/helm}/chart_loader_test.go (91%) rename {helm => internal/helm}/client.go (98%) rename {helm => internal/helm}/client_test.go (98%) rename {helm => internal/helm}/hook/hook.go (99%) rename {helm => internal/helm}/hook/hook_test.go (95%) rename {helm => internal/helm}/hook/mock/kube_client.go (97%) rename {helm => internal/helm}/mock/chart_loader.go (89%) rename {helm => internal/helm}/mock/client.go (95%) rename {version => internal/k8sversion}/mock/version.go (96%) rename {version => internal/k8sversion}/version.go (98%) rename {version => internal/k8sversion}/version_test.go (97%) rename {castai => internal/logexporter}/logexporter.go (84%) create mode 100644 internal/logexporter/logexporter_test.go create mode 100644 internal/logexporter/mock/sender.go rename {testdata => internal/testdata}/aks/CBD209E745FE4FC85066CBA305F32F9A1CFD89A3.prv (100%) rename {testdata => internal/testdata}/aks/Microsoft.Azure.Extensions.CustomScript-2.1.6/config/1.settings (100%) rename {testdata => internal/testdata}/aks/ovf-env.xml (100%) rename {waitext => internal/waitext}/doc.go (100%) rename {waitext => internal/waitext}/extensions.go (95%) rename {waitext => internal/waitext}/extensions_test.go (99%) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index fd09c5c6..1619a4f2 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -10,9 +10,9 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: '1.22.7' - - uses: actions/checkout@v3 + go-version: 'stable' + - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 with: args: --timeout=5m diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..b2e229d7 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,93 @@ +linters: + disable-all: true + enable: + - containedctx + - dogsled + - dupword + - durationcheck + - errcheck + - errname + - errorlint + - gci + - gocognit + - goconst + - gocritic +# - godot + - gofmt + - gofumpt + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - lll +# TODO FIX THE FOLLOWING +# - misspell +# - nakedret +# - paralleltest + - revive + - sqlclosecheck + - staticcheck +# - stylecheck + - typecheck + - unconvert + - unparam + - unused +# - whitespace + +linters-settings: + gocritic: + enabled-all: true + disabled-checks: + - commentFormatting + godot: + scope: all + gofumpt: + module-path: github.com/castai/cluster-controller + extra-rules: true + goconst: + min-len: 2 + min-occurrences: 5 + golint: + min-confidence: 0 + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: [argument,case,condition,return] + govet: + # shadow is marked as experimental feature, skip it for now. + check-shadowing: false + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + lll: + line-length: 200 + maligned: + suggest-new: true + misspell: + locale: US + revive: + rules: + - name: redefines-builtin-id + disabled: true + + # Allow code like: + # Items: binpacking.Items{ + # { + # }, + # } + - name: nested-structs + disabled: true + gci: + sections: + - standard + - default + - prefix(github.com/castai/cluster-controller) +issues: + exclude-dirs: + - mock diff --git a/Makefile b/Makefile index e67a2817..1641b325 100644 --- a/Makefile +++ b/Makefile @@ -6,3 +6,15 @@ push: docker push us-docker.pkg.dev/castai-hub/library/cluster-controller:$(VERSION) release: build push + +lint: + golangci-lint run ./... +.PHONY: lint + +fix: + golangci-lint run --fix ./... +.PHONY: fix + +test: + go test ./... -race +.PHONY: test \ No newline at end of file diff --git a/actions/actions_test.go b/actions/actions_test.go deleted file mode 100644 index 48f44664..00000000 --- a/actions/actions_test.go +++ /dev/null @@ -1,214 +0,0 @@ -package actions - -import ( - "context" - "errors" - "sort" - "testing" - "time" - - "github.com/google/uuid" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" - - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/castai/mock" - "github.com/castai/cluster-controller/health" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon")) -} - -func TestActions(t *testing.T) { - log := logrus.New() - log.SetLevel(logrus.DebugLevel) - cfg := Config{ - PollWaitInterval: 10 * time.Millisecond, - PollTimeout: 100 * time.Millisecond, - AckTimeout: 1 * time.Second, - AckRetriesCount: 3, - AckRetryWait: 1 * time.Millisecond, - ClusterID: uuid.New().String(), - } - - newTestService := func(handler ActionHandler, client castai.ActionsClient) *service { - svc := NewService( - log, - cfg, - "1.20.1", - nil, - nil, - client, - nil, - health.NewHealthzProvider(health.HealthzCfg{HealthyPollIntervalLimit: cfg.PollTimeout}, log), - ).(*service) - handlers := svc.actionHandlers - // Patch handlers with a mock one. - for k := range handlers { - handlers[k] = handler - } - return svc - } - - t.Run("poll handle and ack", func(t *testing.T) { - r := require.New(t) - - apiActions := []*castai.ClusterAction{ - { - ID: "a1", - CreatedAt: time.Now(), - ActionDeleteNode: &castai.ActionDeleteNode{ - NodeName: "n1", - }, - }, - { - ID: "a2", - CreatedAt: time.Now(), - ActionDrainNode: &castai.ActionDrainNode{ - NodeName: "n1", - }, - }, - { - ID: "a3", - CreatedAt: time.Now(), - ActionPatchNode: &castai.ActionPatchNode{ - NodeName: "n1", - }, - }, - } - client := mock.NewMockAPIClient(apiActions) - handler := &mockAgentActionHandler{handleDelay: 2 * time.Millisecond} - svc := newTestService(handler, client) - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) - defer func() { - cancel() - svc.startedActionsWg.Wait() - - r.Len(client.Acks, 3) - ids := make([]string, len(client.Acks)) - for i, ack := range client.Acks { - ids[i] = ack.ActionID - } - sort.Strings(ids) - r.Equal("a1", ids[0]) - r.Equal("a2", ids[1]) - r.Equal("a3", ids[2]) - }() - svc.Run(ctx) - }) - - t.Run("continue polling on api error", func(t *testing.T) { - r := require.New(t) - - client := mock.NewMockAPIClient([]*castai.ClusterAction{}) - client.GetActionsErr = errors.New("ups") - handler := &mockAgentActionHandler{err: errors.New("ups")} - svc := newTestService(handler, client) - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) - defer func() { - cancel() - svc.startedActionsWg.Wait() - - r.Len(client.Acks, 0) - }() - svc.Run(ctx) - }) - - t.Run("do not ack action on context canceled error", func(t *testing.T) { - r := require.New(t) - - apiActions := []*castai.ClusterAction{ - { - ID: "a1", - CreatedAt: time.Now(), - ActionPatchNode: &castai.ActionPatchNode{ - NodeName: "n1", - }, - }, - } - client := mock.NewMockAPIClient(apiActions) - handler := &mockAgentActionHandler{err: context.Canceled} - svc := newTestService(handler, client) - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) - defer func() { - cancel() - svc.startedActionsWg.Wait() - - r.NotEmpty(client.Actions) - r.Len(client.Acks, 0) - }() - svc.Run(ctx) - }) - - t.Run("ack with error when action handler failed", func(t *testing.T) { - r := require.New(t) - - apiActions := []*castai.ClusterAction{ - { - ID: "a1", - CreatedAt: time.Now(), - ActionPatchNode: &castai.ActionPatchNode{ - NodeName: "n1", - }, - }, - } - client := mock.NewMockAPIClient(apiActions) - handler := &mockAgentActionHandler{err: errors.New("ups")} - svc := newTestService(handler, client) - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) - defer func() { - cancel() - svc.startedActionsWg.Wait() - - r.Empty(client.Actions) - r.Len(client.Acks, 1) - r.Equal("a1", client.Acks[0].ActionID) - r.Equal("handling action *castai.ActionPatchNode: ups", *client.Acks[0].Err) - }() - svc.Run(ctx) - }) - - t.Run("ack with error when action handler panic occurred", func(t *testing.T) { - r := require.New(t) - - apiActions := []*castai.ClusterAction{ - { - ID: "a1", - CreatedAt: time.Now(), - ActionPatchNode: &castai.ActionPatchNode{ - NodeName: "n1", - }, - }, - } - client := mock.NewMockAPIClient(apiActions) - handler := &mockAgentActionHandler{panicErr: errors.New("ups")} - svc := newTestService(handler, client) - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond) - defer func() { - cancel() - svc.startedActionsWg.Wait() - - r.Empty(client.Actions) - r.Len(client.Acks, 1) - r.Equal("a1", client.Acks[0].ActionID) - r.Contains(*client.Acks[0].Err, "panic: handling action *castai.ActionPatchNode: ups: goroutine") - }() - svc.Run(ctx) - }) -} - -type mockAgentActionHandler struct { - err error - panicErr error - handleDelay time.Duration -} - -func (m *mockAgentActionHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { - time.Sleep(m.handleDelay) - if m.panicErr != nil { - panic(m.panicErr) - } - return m.err -} diff --git a/actions/create_event_handler.go b/actions/create_event_handler.go deleted file mode 100644 index 583de9e5..00000000 --- a/actions/create_event_handler.go +++ /dev/null @@ -1,80 +0,0 @@ -package actions - -import ( - "context" - "fmt" - "sync" - - "github.com/sirupsen/logrus" - v1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - typedv1core "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/tools/record" - - "github.com/castai/cluster-controller/castai" -) - -func newCreateEventHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - factory := func(ns, reporter string) (record.EventBroadcaster, record.EventRecorder) { - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartRecordingToSink(&typedv1core.EventSinkImpl{Interface: clientset.CoreV1().Events(ns)}) - eventBroadcaster.StartStructuredLogging(0) - log.Debug("create new broadcaster and recorder for namespace: %s", ns) - // Create an event recorder - return eventBroadcaster, eventBroadcaster.NewRecorder(nil, v1.EventSource{ - Component: reporter, - Host: reporter, - }) - } - return &createEventHandler{ - log: log, - clientSet: clientset, - recorderFactory: factory, - eventNsBroadcaster: map[string]record.EventBroadcaster{}, - eventNsRecorder: map[string]record.EventRecorder{}, - } -} - -type createEventHandler struct { - log logrus.FieldLogger - clientSet kubernetes.Interface - recorderFactory func(string, string) (record.EventBroadcaster, record.EventRecorder) - mu sync.RWMutex - eventNsBroadcaster map[string]record.EventBroadcaster - eventNsRecorder map[string]record.EventRecorder -} - -func (h *createEventHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { - req, ok := action.Data().(*castai.ActionCreateEvent) - if !ok { - return fmt.Errorf("unexpected type %T for create event handler", action.Data()) - } - namespace := req.ObjectRef.Namespace - if namespace == "" { - namespace = v1.NamespaceDefault - } - h.handleEventV1(ctx, req, namespace) - return nil -} - -func (h *createEventHandler) handleEventV1(_ context.Context, req *castai.ActionCreateEvent, namespace string) { - h.mu.RLock() - h.log.Debug("handling create event action: %s type: %s", req.Action, req.EventType) - if recorder, ok := h.eventNsRecorder[fmt.Sprintf("%s-%s", namespace, req.Reporter)]; ok { - recorder.Event(&req.ObjectRef, v1.EventTypeNormal, req.Reason, req.Message) - h.mu.RUnlock() - } else { - h.mu.RUnlock() - h.mu.Lock() - // Double check after acquiring the lock. - if recorder, ok := h.eventNsRecorder[namespace]; !ok { - broadcaster, rec := h.recorderFactory(namespace, req.Reporter) - h.eventNsBroadcaster[fmt.Sprintf("%s-%s", namespace, req.Reporter)] = broadcaster - h.eventNsRecorder[fmt.Sprintf("%s-%s", namespace, req.Reporter)] = rec - rec.Event(&req.ObjectRef, req.EventType, req.Reason, req.Message) - } else { - recorder.Event(&req.ObjectRef, req.EventType, req.Reason, req.Message) - } - h.mu.Unlock() - } -} diff --git a/castai/logexporter_test.go b/castai/logexporter_test.go deleted file mode 100644 index b9f11063..00000000 --- a/castai/logexporter_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package castai - -import ( - "context" - "sync" - "testing" - - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon")) -} - -func TestLogExporter(t *testing.T) { - logger, hook := test.NewNullLogger() - defer hook.Reset() - - sender := &mockSender{} - e := NewLogExporter(nil, sender) - logger.AddHook(e) - log := logger.WithFields(logrus.Fields{ - "cluster_id": "test-cluster", - }) - log.Log(logrus.ErrorLevel, "foo") - log.Log(logrus.DebugLevel, "bar") - e.Wait() - - it := require.New(t) - it.Len(sender.entries, 1) - it.Equal(sender.entries[0].Message, "foo") - it.Equal(sender.entries[0].Level, "error") - it.Equal(sender.entries[0].Fields, logrus.Fields{"cluster_id": "test-cluster"}) -} - -type mockSender struct { - mu sync.Mutex - entries []*logEntry -} - -func (s *mockSender) SendLog(_ context.Context, entry *logEntry) error { - s.mu.Lock() - s.entries = append(s.entries, entry) - s.mu.Unlock() - return nil -} diff --git a/castai/mock/client.go b/castai/mock/client.go deleted file mode 100644 index 1bd56e3b..00000000 --- a/castai/mock/client.go +++ /dev/null @@ -1,62 +0,0 @@ -package mock - -import ( - "context" - "sync" - - "github.com/castai/cluster-controller/castai" -) - -var _ castai.ActionsClient = (*mockClient)(nil) - -func NewMockAPIClient(actions []*castai.ClusterAction) *mockClient { - return &mockClient{Actions: actions} -} - -type mockAck struct { - ActionID string - Err *string -} - -type mockClient struct { - Actions []*castai.ClusterAction - GetActionsErr error - Acks []*mockAck - AKSInitDataReq *castai.AKSInitDataRequest - - mu sync.Mutex -} - -func (m *mockClient) SendAKSInitData(ctx context.Context, req *castai.AKSInitDataRequest) error { - m.mu.Lock() - m.AKSInitDataReq = req - m.mu.Unlock() - return nil -} - -func (m *mockClient) GetActions(_ context.Context, _ string) ([]*castai.ClusterAction, error) { - m.mu.Lock() - actions := m.Actions - m.mu.Unlock() - return actions, m.GetActionsErr -} - -func (m *mockClient) AckAction(_ context.Context, actionID string, req *castai.AckClusterActionRequest) error { - m.mu.Lock() - defer m.mu.Unlock() - - m.removeAckedActions(actionID) - - m.Acks = append(m.Acks, &mockAck{ActionID: actionID, Err: req.Error}) - return nil -} - -func (m *mockClient) removeAckedActions(actionID string) { - var remaining []*castai.ClusterAction - for _, action := range m.Actions { - if action.ID != actionID { - remaining = append(remaining, action) - } - } - m.Actions = remaining -} diff --git a/go.mod b/go.mod index 4c55d8a5..2ed7f6da 100644 --- a/go.mod +++ b/go.mod @@ -1,73 +1,76 @@ module github.com/castai/cluster-controller -go 1.22 +go 1.22.5 require ( - github.com/bombsimon/logrusr/v4 v4.0.0 - github.com/evanphx/json-patch v5.7.0+incompatible - github.com/go-resty/resty/v2 v2.5.0 + github.com/bombsimon/logrusr/v4 v4.1.0 + github.com/evanphx/json-patch v5.9.0+incompatible + github.com/go-resty/resty/v2 v2.15.3 github.com/golang/mock v1.6.0 - github.com/google/uuid v1.3.1 - github.com/samber/lo v1.21.0 + github.com/google/uuid v1.6.0 + github.com/samber/lo v1.47.0 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/viper v1.10.0 - github.com/stretchr/testify v1.8.4 - go.uber.org/goleak v1.2.0 - golang.org/x/net v0.23.0 - helm.sh/helm/v3 v3.14.2 - k8s.io/api v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/apiserver v0.29.0 - k8s.io/cli-runtime v0.29.0 - k8s.io/client-go v0.29.0 - k8s.io/klog/v2 v2.110.1 - k8s.io/kubectl v0.29.0 - sigs.k8s.io/controller-runtime v0.8.3 - sigs.k8s.io/yaml v1.3.0 + github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 + go.uber.org/goleak v1.3.0 + golang.org/x/net v0.30.0 + helm.sh/helm/v3 v3.16.2 + k8s.io/api v0.31.1 + k8s.io/apimachinery v0.31.1 + k8s.io/apiserver v0.31.1 + k8s.io/cli-runtime v0.31.1 + k8s.io/client-go v0.31.1 + k8s.io/klog/v2 v2.130.1 + k8s.io/kubectl v0.31.1 + sigs.k8s.io/controller-runtime v0.19.0 + sigs.k8s.io/yaml v1.4.0 ) require ( + dario.cat/mergo v1.0.1 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect - github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/containerd v1.7.12 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.3.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/cli v25.0.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v26.1.5+incompatible // indirect + github.com/docker/docker v25.0.6+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fatih/color v1.14.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -80,29 +83,28 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/magiconair/properties v1.8.5 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect - github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/spdystream v0.4.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -110,59 +112,60 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc6 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // 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 - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/rubenv/sql-migrate v1.5.2 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/rubenv/sql-migrate v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.2.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/oauth2 v0.11.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/time v0.6.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + k8s.io/apiextensions-apiserver v0.31.1 // indirect + k8s.io/component-base v0.31.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect oras.land/oras-go v1.2.5 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) - -replace oras.land/oras-go v1.2.2 => oras.land/oras-go v1.2.3 diff --git a/go.sum b/go.sum index 3cd24762..e3893f14 100644 --- a/go.sum +++ b/go.sum @@ -1,91 +1,47 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bombsimon/logrusr/v4 v4.0.0 h1:Pm0InGphX0wMhPqC02t31onlq9OVyJ98eP/Vh63t1Oo= -github.com/bombsimon/logrusr/v4 v4.0.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= +github.com/bombsimon/logrusr/v4 v4.1.0 h1:uZNPbwusB0eUXlO8hIUwStE6Lr5bLN6IgYgG+75kuh4= +github.com/bombsimon/logrusr/v4 v4.1.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= @@ -95,47 +51,32 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 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/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= -github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE= +github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= 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/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/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= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= @@ -144,8 +85,8 @@ github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbT github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v26.1.5+incompatible h1:NEAxTwEjxV6VbBMBoGG3zPqbiJosIApZjxlbrG9q3/g= -github.com/docker/docker v26.1.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -156,129 +97,80 @@ github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -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/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= -github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= +github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -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.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= -github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-resty/resty/v2 v2.5.0 h1:WFb5bD49/85PO7WgAjZ+/TJQ+Ty1XOcWEfD1zIFCM1c= -github.com/go-resty/resty/v2 v2.5.0/go.mod h1:B88+xCTEwvfD94NOuE6GS1wMlnoKNY8eEiNizfNwOwA= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8= +github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= -github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= -github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= -github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= -github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= -github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= 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= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -289,126 +181,62 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/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/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= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= 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.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/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/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +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/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 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/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/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/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -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/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= -github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -416,74 +244,40 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= -github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= -github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= -github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= -github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -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= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= -github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 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/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= -github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= +github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -495,159 +289,102 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= -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= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= -github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= -github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +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= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -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.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= 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/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -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.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -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/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= -github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rubenv/sql-migrate v1.7.0 h1:HtQq1xyTN2ISmQDggnh0c9U3JlP8apWh8YO2jzlXpTI= +github.com/rubenv/sql-migrate v1.7.0/go.mod h1:S4wtDEG1CKn+0ShpTtzWhFpHHI5PvCUtiGI+C+Z2THE= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samber/lo v1.21.0 h1:FSby8pJQtX4KmyddTCCGhc3JvnnIVrDA+NW37rG+7G8= -github.com/samber/lo v1.21.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.10.0 h1:mXH0UwHS4D2HwWZa75im4xIQynLfblmWV7qcWpfv0yk= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= -github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= -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/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -655,456 +392,196 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -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.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -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/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-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.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -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/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -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/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/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.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -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/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -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-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -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= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/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= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 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= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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/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= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= -helm.sh/helm/v3 v3.14.2 h1:V71fv+NGZv0icBlr+in1MJXuUIHCiPG1hW9gEBISTIA= -helm.sh/helm/v3 v3.14.2/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= +helm.sh/helm/v3 v3.16.2 h1:Y9v7ry+ubQmi+cb5zw1Llx8OKHU9Hk9NQ/+P+LGBe2o= +helm.sh/helm/v3 v3.16.2/go.mod h1:SyTXgKBjNqi2NPsHCW5dDAsHqvGIu0kdNYNH9gQaw70= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o= -k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM= -k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= -k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= -k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI= -k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= +k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= +k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40= +k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ= +k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= +k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= +k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= +k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk= +k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U= +k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= +k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= +k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= +k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24= +k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao= -sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= +sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= +sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= +sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/health/healthz.go b/health/healthz.go index d67a22f8..2360f20f 100644 --- a/health/healthz.go +++ b/health/healthz.go @@ -9,9 +9,9 @@ import ( ) type HealthzCfg struct { - // Max time between successful poll actions to consider cluster-controller alive + // Max time between successful poll actions to consider cluster-controller alive. HealthyPollIntervalLimit time.Duration - // Max wait time for application to start + // Max wait time for application to start. StartTimeLimit time.Duration } diff --git a/health/healthz_test.go b/health/healthz_test.go index a694501f..630e4945 100644 --- a/health/healthz_test.go +++ b/health/healthz_test.go @@ -1,9 +1,8 @@ package health import ( - "time" - "testing" + "time" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" @@ -11,7 +10,6 @@ import ( func TestNewHealthzProvider(t *testing.T) { t.Run("unhealthy statuses", func(t *testing.T) { - log := logrus.New() t.Run("should return initialize timeout error", func(t *testing.T) { @@ -36,7 +34,6 @@ func TestNewHealthzProvider(t *testing.T) { }) t.Run("healthy statuses", func(t *testing.T) { - log := logrus.New() t.Run("cluster-controller is considered healthy before initialization", func(t *testing.T) { @@ -62,5 +59,4 @@ func TestNewHealthzProvider(t *testing.T) { r.NoError(h.Check(nil)) }) }) - } diff --git a/actions/approve_csr_handler.go b/internal/actions/approve_csr_handler.go similarity index 84% rename from actions/approve_csr_handler.go rename to internal/actions/approve_csr_handler.go index 0d9875d9..f015436e 100644 --- a/actions/approve_csr_handler.go +++ b/internal/actions/approve_csr_handler.go @@ -11,17 +11,19 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/csr" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/actions/csr" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) const ( approveCSRTimeout = 4 * time.Minute ) -func newApproveCSRHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - return &approveCSRHandler{ +var _ ActionHandler = &ApproveCSRHandler{} + +func NewApproveCSRHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *ApproveCSRHandler { + return &ApproveCSRHandler{ log: log, clientset: clientset, initialCSRFetchTimeout: 5 * time.Minute, @@ -29,14 +31,14 @@ func newApproveCSRHandler(log logrus.FieldLogger, clientset kubernetes.Interface } } -type approveCSRHandler struct { +type ApproveCSRHandler struct { log logrus.FieldLogger clientset kubernetes.Interface initialCSRFetchTimeout time.Duration csrFetchInterval time.Duration } -func (h *approveCSRHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *ApproveCSRHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionApproveCSR) if !ok { return fmt.Errorf("unexpected type %T for approve csr handler", action.Data()) @@ -45,7 +47,7 @@ func (h *approveCSRHandler) Handle(ctx context.Context, action *castai.ClusterAc "node_name": req.NodeName, "node_id": req.NodeID, "type": reflect.TypeOf(action.Data().(*castai.ActionApproveCSR)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) if req.AllowAutoApprove != nil { @@ -69,7 +71,7 @@ func (h *approveCSRHandler) Handle(ctx context.Context, action *castai.ClusterAc return h.handleWithRetry(ctx, log, cert) } -func (h *approveCSRHandler) handleWithRetry(ctx context.Context, log *logrus.Entry, cert *csr.Certificate) error { +func (h *ApproveCSRHandler) handleWithRetry(ctx context.Context, log *logrus.Entry, cert *csr.Certificate) error { ctx, cancel := context.WithTimeout(ctx, approveCSRTimeout) defer cancel() @@ -87,7 +89,7 @@ func (h *approveCSRHandler) handleWithRetry(ctx context.Context, log *logrus.Ent ) } -func (h *approveCSRHandler) handle(ctx context.Context, log logrus.FieldLogger, cert *csr.Certificate) (reterr error) { +func (h *ApproveCSRHandler) handle(ctx context.Context, log logrus.FieldLogger, cert *csr.Certificate) (reterr error) { // Since this new csr may be denied we need to delete it. log.Debug("deleting old csr") if err := cert.DeleteCertificate(ctx, h.clientset); err != nil { @@ -114,7 +116,7 @@ func (h *approveCSRHandler) handle(ctx context.Context, log logrus.FieldLogger, return errors.New("certificate signing request was not approved") } -func (h *approveCSRHandler) getInitialNodeCSR(ctx context.Context, log logrus.FieldLogger, nodeName string) (*csr.Certificate, error) { +func (h *ApproveCSRHandler) getInitialNodeCSR(ctx context.Context, log logrus.FieldLogger, nodeName string) (*csr.Certificate, error) { log.Debug("getting initial csr") ctx, cancel := context.WithTimeout(ctx, h.initialCSRFetchTimeout) diff --git a/actions/approve_csr_handler_test.go b/internal/actions/approve_csr_handler_test.go similarity index 96% rename from actions/approve_csr_handler_test.go rename to internal/actions/approve_csr_handler_test.go index f10900de..fa921659 100644 --- a/actions/approve_csr_handler_test.go +++ b/internal/actions/approve_csr_handler_test.go @@ -22,8 +22,8 @@ import ( "k8s.io/client-go/kubernetes/fake" ktest "k8s.io/client-go/testing" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/csr" + "github.com/castai/cluster-controller/internal/actions/csr" + "github.com/castai/cluster-controller/internal/castai" ) func TestApproveCSRHandler(t *testing.T) { @@ -63,7 +63,7 @@ func TestApproveCSRHandler(t *testing.T) { CreatedAt: time.Time{}, } - h := &approveCSRHandler{ + h := &ApproveCSRHandler{ log: log, clientset: client, csrFetchInterval: 1 * time.Millisecond, @@ -95,7 +95,7 @@ func TestApproveCSRHandler(t *testing.T) { ActionApproveCSR: &castai.ActionApproveCSR{NodeName: "gke-am-gcp-cast-5dc4f4ec"}, CreatedAt: time.Time{}, } - h := &approveCSRHandler{ + h := &ApproveCSRHandler{ log: log, clientset: client, csrFetchInterval: 1 * time.Millisecond, @@ -128,7 +128,7 @@ func TestApproveCSRHandler(t *testing.T) { ActionApproveCSR: &castai.ActionApproveCSR{NodeName: "gke-am-gcp-cast-5dc4f4ec"}, CreatedAt: time.Time{}, } - h := &approveCSRHandler{ + h := &ApproveCSRHandler{ log: log, clientset: client, csrFetchInterval: 500 * time.Millisecond, @@ -187,7 +187,7 @@ AiAHVYZXHxxspoV0hcfn2Pdsl89fIPCOFy/K1PqSUR6QNAIgYdt51ZbQt9rgM2BD ActionApproveCSR: &castai.ActionApproveCSR{NodeName: "gke-am-gcp-cast-5dc4f4ec"}, CreatedAt: time.Time{}, } - h := &approveCSRHandler{ + h := &ApproveCSRHandler{ log: log, clientset: client, csrFetchInterval: 1 * time.Millisecond, @@ -203,7 +203,7 @@ AiAHVYZXHxxspoV0hcfn2Pdsl89fIPCOFy/K1PqSUR6QNAIgYdt51ZbQt9rgM2BD r := require.New(t) client := fake.NewSimpleClientset() - h := &approveCSRHandler{ + h := &ApproveCSRHandler{ log: log, clientset: client, csrFetchInterval: 1 * time.Millisecond, @@ -253,6 +253,6 @@ AiAHVYZXHxxspoV0hcfn2Pdsl89fIPCOFy/K1PqSUR6QNAIgYdt51ZbQt9rgM2BD Usages: []certv1.KeyUsage{"kubelet"}, Username: "kubelet-bootstrap", }, - //Status: certv1.CertificateSigningRequestStatus{}, + // Status: certv1.CertificateSigningRequestStatus{},. } } diff --git a/actions/chart_rollback_handler.go b/internal/actions/chart_rollback_handler.go similarity index 67% rename from actions/chart_rollback_handler.go rename to internal/actions/chart_rollback_handler.go index 17c0060c..8ef36c25 100644 --- a/actions/chart_rollback_handler.go +++ b/internal/actions/chart_rollback_handler.go @@ -7,25 +7,27 @@ import ( "github.com/sirupsen/logrus" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" ) -func newChartRollbackHandler(log logrus.FieldLogger, helm helm.Client, version string) ActionHandler { - return &chartRollbackHandler{ +var _ ActionHandler = &ChartRollbackHandler{} + +func NewChartRollbackHandler(log logrus.FieldLogger, helm helm.Client, version string) *ChartRollbackHandler { + return &ChartRollbackHandler{ log: log, helm: helm, version: version, } } -type chartRollbackHandler struct { +type ChartRollbackHandler struct { log logrus.FieldLogger helm helm.Client version string } -func (c *chartRollbackHandler) Handle(_ context.Context, action *castai.ClusterAction) error { +func (c *ChartRollbackHandler) Handle(_ context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionChartRollback) if !ok { return fmt.Errorf("unexpected type %T for chart rollback handler", action.Data()) @@ -46,7 +48,7 @@ func (c *chartRollbackHandler) Handle(_ context.Context, action *castai.ClusterA }) } -func (c *chartRollbackHandler) validateRequest(req *castai.ActionChartRollback) error { +func (c *ChartRollbackHandler) validateRequest(req *castai.ActionChartRollback) error { if req.ReleaseName == "" { return errors.New("bad request: releaseName not provided") } diff --git a/actions/chart_rollback_handler_test.go b/internal/actions/chart_rollback_handler_test.go similarity index 90% rename from actions/chart_rollback_handler_test.go rename to internal/actions/chart_rollback_handler_test.go index 8989ce70..f5ce076c 100644 --- a/actions/chart_rollback_handler_test.go +++ b/internal/actions/chart_rollback_handler_test.go @@ -3,16 +3,16 @@ package actions import ( "context" "fmt" - "github.com/google/uuid" "testing" "github.com/golang/mock/gomock" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" - mock_helm "github.com/castai/cluster-controller/helm/mock" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" + "github.com/castai/cluster-controller/internal/helm/mock" ) func TestChartRollbackHandler(t *testing.T) { @@ -21,7 +21,7 @@ func TestChartRollbackHandler(t *testing.T) { helmMock := mock_helm.NewMockClient(ctrl) ctx := context.Background() - handler := newChartRollbackHandler(logrus.New(), helmMock, "v0.20.0") + handler := NewChartRollbackHandler(logrus.New(), helmMock, "v0.20.0") t.Run("successfully rollback chart", func(t *testing.T) { action := &castai.ClusterAction{ diff --git a/actions/chart_uninstall_handler.go b/internal/actions/chart_uninstall_handler.go similarity index 63% rename from actions/chart_uninstall_handler.go rename to internal/actions/chart_uninstall_handler.go index 3692da05..97cd36c4 100644 --- a/actions/chart_uninstall_handler.go +++ b/internal/actions/chart_uninstall_handler.go @@ -7,23 +7,25 @@ import ( "github.com/sirupsen/logrus" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" ) -func newChartUninstallHandler(log logrus.FieldLogger, helm helm.Client) ActionHandler { - return &chartUninstallHandler{ +var _ ActionHandler = &ChartUninstallHandler{} + +func NewChartUninstallHandler(log logrus.FieldLogger, helm helm.Client) *ChartUninstallHandler { + return &ChartUninstallHandler{ log: log, helm: helm, } } -type chartUninstallHandler struct { +type ChartUninstallHandler struct { log logrus.FieldLogger helm helm.Client } -func (c *chartUninstallHandler) Handle(_ context.Context, action *castai.ClusterAction) error { +func (c *ChartUninstallHandler) Handle(_ context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionChartUninstall) if !ok { return fmt.Errorf("unexpected type %T for upsert uninstall handler", action.Data()) @@ -39,7 +41,7 @@ func (c *chartUninstallHandler) Handle(_ context.Context, action *castai.Cluster return err } -func (c *chartUninstallHandler) validateRequest(req *castai.ActionChartUninstall) error { +func (c *ChartUninstallHandler) validateRequest(req *castai.ActionChartUninstall) error { if req.ReleaseName == "" { return errors.New("bad request: releaseName not provided") } diff --git a/actions/chart_uninstall_handler_test.go b/internal/actions/chart_uninstall_handler_test.go similarity index 89% rename from actions/chart_uninstall_handler_test.go rename to internal/actions/chart_uninstall_handler_test.go index 7985dfae..20cf4781 100644 --- a/actions/chart_uninstall_handler_test.go +++ b/internal/actions/chart_uninstall_handler_test.go @@ -3,16 +3,16 @@ package actions import ( "context" "fmt" - "github.com/google/uuid" "testing" "github.com/golang/mock/gomock" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" - mock_helm "github.com/castai/cluster-controller/helm/mock" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" + "github.com/castai/cluster-controller/internal/helm/mock" ) func TestChartUninstallHandler(t *testing.T) { @@ -21,7 +21,7 @@ func TestChartUninstallHandler(t *testing.T) { helmMock := mock_helm.NewMockClient(ctrl) ctx := context.Background() - handler := newChartUninstallHandler(logrus.New(), helmMock) + handler := NewChartUninstallHandler(logrus.New(), helmMock) t.Run("successfully uninstall chart", func(t *testing.T) { action := &castai.ClusterAction{ diff --git a/actions/chart_upsert_handler.go b/internal/actions/chart_upsert_handler.go similarity index 82% rename from actions/chart_upsert_handler.go rename to internal/actions/chart_upsert_handler.go index c9e90587..b68716c5 100644 --- a/actions/chart_upsert_handler.go +++ b/internal/actions/chart_upsert_handler.go @@ -9,23 +9,25 @@ import ( "helm.sh/helm/v3/pkg/release" helmdriver "helm.sh/helm/v3/pkg/storage/driver" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" ) -func newChartUpsertHandler(log logrus.FieldLogger, helm helm.Client) ActionHandler { - return &chartUpsertHandler{ +var _ ActionHandler = &ChartUpsertHandler{} + +func NewChartUpsertHandler(log logrus.FieldLogger, helm helm.Client) *ChartUpsertHandler { + return &ChartUpsertHandler{ log: log, helm: helm, } } -type chartUpsertHandler struct { +type ChartUpsertHandler struct { log logrus.FieldLogger helm helm.Client } -func (c *chartUpsertHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (c *ChartUpsertHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionChartUpsert) if !ok { return fmt.Errorf("unexpected type %T for upsert chart handler", action.Data()) @@ -39,7 +41,6 @@ func (c *chartUpsertHandler) Handle(ctx context.Context, action *castai.ClusterA Namespace: req.Namespace, ReleaseName: req.ReleaseName, }) - if err != nil { if !errors.Is(err, helmdriver.ErrReleaseNotFound) { return fmt.Errorf("getting helm release %q in namespace %q: %w", req.ReleaseName, req.Namespace, err) @@ -76,7 +77,7 @@ func (c *chartUpsertHandler) Handle(ctx context.Context, action *castai.ClusterA return err } -func (c *chartUpsertHandler) validateRequest(req *castai.ActionChartUpsert) error { +func (c *ChartUpsertHandler) validateRequest(req *castai.ActionChartUpsert) error { if req.ReleaseName == "" { return errors.New("bad request: releaseName not provided") } diff --git a/actions/chart_upsert_handler_test.go b/internal/actions/chart_upsert_handler_test.go similarity index 93% rename from actions/chart_upsert_handler_test.go rename to internal/actions/chart_upsert_handler_test.go index d4090cc9..8e52c70b 100644 --- a/actions/chart_upsert_handler_test.go +++ b/internal/actions/chart_upsert_handler_test.go @@ -2,18 +2,18 @@ package actions import ( "context" - "github.com/google/uuid" "testing" "github.com/golang/mock/gomock" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "helm.sh/helm/v3/pkg/release" helmdriver "helm.sh/helm/v3/pkg/storage/driver" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm" - mock_helm "github.com/castai/cluster-controller/helm/mock" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" + "github.com/castai/cluster-controller/internal/helm/mock" ) func TestChartUpsertHandler(t *testing.T) { @@ -22,7 +22,7 @@ func TestChartUpsertHandler(t *testing.T) { helmMock := mock_helm.NewMockClient(ctrl) ctx := context.Background() - handler := newChartUpsertHandler(logrus.New(), helmMock) + handler := NewChartUpsertHandler(logrus.New(), helmMock) t.Run("install chart given release is not found", func(t *testing.T) { action := &castai.ClusterAction{ diff --git a/actions/check_node_deleted.go b/internal/actions/check_node_deleted.go similarity index 81% rename from actions/check_node_deleted.go rename to internal/actions/check_node_deleted.go index c12cb4e5..229792e1 100644 --- a/actions/check_node_deleted.go +++ b/internal/actions/check_node_deleted.go @@ -12,17 +12,19 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) +var _ ActionHandler = &CheckNodeDeletedHandler{} + type checkNodeDeletedConfig struct { retries int retryWait time.Duration } -func newCheckNodeDeletedHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - return &checkNodeDeletedHandler{ +func NewCheckNodeDeletedHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *CheckNodeDeletedHandler { + return &CheckNodeDeletedHandler{ log: log, clientset: clientset, cfg: checkNodeDeletedConfig{ @@ -32,13 +34,13 @@ func newCheckNodeDeletedHandler(log logrus.FieldLogger, clientset kubernetes.Int } } -type checkNodeDeletedHandler struct { +type CheckNodeDeletedHandler struct { log logrus.FieldLogger clientset kubernetes.Interface cfg checkNodeDeletedConfig } -func (h *checkNodeDeletedHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *CheckNodeDeletedHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionCheckNodeDeleted) if !ok { return fmt.Errorf("unexpected type %T for check node deleted handler", action.Data()) @@ -48,7 +50,7 @@ func (h *checkNodeDeletedHandler) Handle(ctx context.Context, action *castai.Clu "node_name": req.NodeName, "node_id": req.NodeID, "type": reflect.TypeOf(action.Data().(*castai.ActionCheckNodeDeleted)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) log.Info("checking if node is deleted") diff --git a/actions/check_node_handler_test.go b/internal/actions/check_node_handler_test.go similarity index 91% rename from actions/check_node_handler_test.go rename to internal/actions/check_node_handler_test.go index 2cd06505..00a99f3b 100644 --- a/actions/check_node_handler_test.go +++ b/internal/actions/check_node_handler_test.go @@ -2,18 +2,19 @@ package actions import ( "context" - "github.com/google/uuid" "testing" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) +//nolint:goconst func TestCheckNodeDeletedHandler(t *testing.T) { r := require.New(t) @@ -29,7 +30,7 @@ func TestCheckNodeDeletedHandler(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeDeletedHandler{ + h := CheckNodeDeletedHandler{ log: log, clientset: clientset, cfg: checkNodeDeletedConfig{}, @@ -47,7 +48,7 @@ func TestCheckNodeDeletedHandler(t *testing.T) { t.Run("handle check successfully when node is not found", func(t *testing.T) { clientset := fake.NewSimpleClientset() - h := checkNodeDeletedHandler{ + h := CheckNodeDeletedHandler{ log: log, clientset: clientset, cfg: checkNodeDeletedConfig{}, diff --git a/actions/check_node_status.go b/internal/actions/check_node_status.go similarity index 85% rename from actions/check_node_status.go rename to internal/actions/check_node_status.go index 3f24e731..849a9b8f 100644 --- a/actions/check_node_status.go +++ b/internal/actions/check_node_status.go @@ -11,26 +11,27 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) -func newCheckNodeStatusHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - return &checkNodeStatusHandler{ +var _ ActionHandler = &CheckNodeStatusHandler{} + +func NewCheckNodeStatusHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *CheckNodeStatusHandler { + return &CheckNodeStatusHandler{ log: log, clientset: clientset, } } -type checkNodeStatusHandler struct { +type CheckNodeStatusHandler struct { log logrus.FieldLogger clientset kubernetes.Interface } -func (h *checkNodeStatusHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *CheckNodeStatusHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionCheckNodeStatus) if !ok { return fmt.Errorf("unexpected type %T for check node status handler", action.Data()) @@ -41,7 +42,7 @@ func (h *checkNodeStatusHandler) Handle(ctx context.Context, action *castai.Clus "node_id": req.NodeID, "node_status": req.NodeStatus, "type": reflect.TypeOf(action.Data().(*castai.ActionCheckNodeStatus)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) switch req.NodeStatus { @@ -57,7 +58,7 @@ func (h *checkNodeStatusHandler) Handle(ctx context.Context, action *castai.Clus return fmt.Errorf("unknown status to check provided node=%s status=%s", req.NodeName, req.NodeStatus) } -func (h *checkNodeStatusHandler) checkNodeDeleted(ctx context.Context, log *logrus.Entry, req *castai.ActionCheckNodeStatus) error { +func (h *CheckNodeStatusHandler) checkNodeDeleted(ctx context.Context, log *logrus.Entry, req *castai.ActionCheckNodeStatus) error { timeout := 10 if req.WaitTimeoutSeconds != nil { timeout = int(*req.WaitTimeoutSeconds) @@ -79,7 +80,7 @@ func (h *checkNodeStatusHandler) checkNodeDeleted(ctx context.Context, log *logr // If node is nil - deleted // If label is present and doesn't match - node was reused - deleted // If label is present and matches - node is not deleted - // If label is not present and node is not nil - node is not deleted (potentially corrupted state) + // If label is not present and node is not nil - node is not deleted (potentially corrupted state). if n == nil { return false, nil @@ -111,7 +112,7 @@ func (h *checkNodeStatusHandler) checkNodeDeleted(ctx context.Context, log *logr ) } -func (h *checkNodeStatusHandler) checkNodeReady(ctx context.Context, log *logrus.Entry, req *castai.ActionCheckNodeStatus) error { +func (h *CheckNodeStatusHandler) checkNodeReady(ctx context.Context, _ *logrus.Entry, req *castai.ActionCheckNodeStatus) error { timeout := 9 * time.Minute watchObject := metav1.SingleObject(metav1.ObjectMeta{Name: req.NodeName}) if req.WaitTimeoutSeconds != nil { @@ -139,7 +140,7 @@ func (h *checkNodeStatusHandler) checkNodeReady(ctx context.Context, log *logrus func isNodeReady(node *corev1.Node, castNodeID string) bool { // if node has castai node id label, check if it matches the one we are waiting for - // if it doesn't match, we can skip this node + // if it doesn't match, we can skip this node. if val, ok := node.Labels[castai.LabelNodeID]; ok { if val != "" && val != castNodeID { return false diff --git a/actions/check_node_status_test.go b/internal/actions/check_node_status_test.go similarity index 95% rename from actions/check_node_status_test.go rename to internal/actions/check_node_status_test.go index dc96b187..09b56dd1 100644 --- a/actions/check_node_status_test.go +++ b/internal/actions/check_node_status_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/google/uuid" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -16,7 +15,7 @@ import ( "k8s.io/client-go/kubernetes/fake" k8stest "k8s.io/client-go/testing" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestCheckStatus_Deleted(t *testing.T) { @@ -36,7 +35,7 @@ func TestCheckStatus_Deleted(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -64,7 +63,7 @@ func TestCheckStatus_Deleted(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -86,7 +85,7 @@ func TestCheckStatus_Deleted(t *testing.T) { r := require.New(t) clientset := fake.NewSimpleClientset() - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -116,7 +115,7 @@ func TestCheckStatus_Deleted(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -143,7 +142,7 @@ func TestCheckStatus_Ready(t *testing.T) { r := require.New(t) clientset := fake.NewSimpleClientset() - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -188,7 +187,7 @@ func TestCheckStatus_Ready(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -243,7 +242,7 @@ func TestCheckStatus_Ready(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -297,7 +296,7 @@ func TestCheckStatus_Ready(t *testing.T) { watcher.Stop() }() - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -336,7 +335,7 @@ func TestCheckStatus_Ready(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := checkNodeStatusHandler{ + h := CheckNodeStatusHandler{ log: log, clientset: clientset, } @@ -356,7 +355,7 @@ func TestCheckStatus_Ready(t *testing.T) { // 1. node is deleted // 2. new node is created with the same name and different id // 3. node is ready - // 4. checkNodeStatusHandler.Handle() is called + // 4. checkNodeStatusHandler.Handle() is called. var wg sync.WaitGroup wg.Add(2) var err error diff --git a/internal/actions/create_event_handler.go b/internal/actions/create_event_handler.go new file mode 100644 index 00000000..846ca280 --- /dev/null +++ b/internal/actions/create_event_handler.go @@ -0,0 +1,108 @@ +//go:generate mockgen -package=mock_actions -destination ./mock/kubernetes.go k8s.io/client-go/kubernetes Interface + +package actions + +import ( + "context" + "fmt" + "sync" + + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + typedv1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/record" + + "github.com/castai/cluster-controller/internal/castai" +) + +var _ ActionHandler = &CreateEventHandler{} + +func NewCreateEventHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *CreateEventHandler { + factory := func(ns, reporter string) (record.EventBroadcaster, record.EventRecorder) { + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartRecordingToSink(&typedv1core.EventSinkImpl{Interface: clientset.CoreV1().Events(ns)}) + eventBroadcaster.StartStructuredLogging(0) + log.Debug("create new broadcaster and recorder for namespace: %s", ns) + // Create an event recorder. + return eventBroadcaster, eventBroadcaster.NewRecorder(nil, v1.EventSource{ + Component: reporter, + Host: reporter, + }) + } + return &CreateEventHandler{ + log: log, + clientSet: clientset, + recorderFactory: factory, + eventNsBroadcaster: map[string]record.EventBroadcaster{}, + eventNsRecorder: map[string]record.EventRecorder{}, + } +} + +type CreateEventHandler struct { + log logrus.FieldLogger + clientSet kubernetes.Interface + recorderFactory func(string, string) (record.EventBroadcaster, record.EventRecorder) + mu sync.RWMutex + eventNsBroadcaster map[string]record.EventBroadcaster + eventNsRecorder map[string]record.EventRecorder +} + +func (h *CreateEventHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { + req, ok := action.Data().(*castai.ActionCreateEvent) + if !ok { + return fmt.Errorf("unexpected type %T for create event handler", action.Data()) + } + namespace := req.ObjectRef.Namespace + if namespace == "" { + namespace = v1.NamespaceDefault + } + + h.handleEventV1(ctx, req, namespace) + return nil +} + +func (h *CreateEventHandler) handleEventV1(_ context.Context, req *castai.ActionCreateEvent, namespace string) { + h.log.Debugf("handling create event action: %s type: %s", req.Action, req.EventType) + if recorder, ok := h.getRecorder(namespace, req.Reporter); ok { + recorder.Event(&req.ObjectRef, v1.EventTypeNormal, req.Reason, req.Message) + } else { + rec := h.createRecorder(namespace, req.Reporter) + rec.Event(&req.ObjectRef, req.EventType, req.Reason, req.Message) + } +} + +func (h *CreateEventHandler) getRecorder(namespace, reporter string) (record.EventRecorder, bool) { + h.mu.RLock() + defer h.mu.RUnlock() + recorder, ok := h.eventNsRecorder[fmt.Sprintf("%s-%s", namespace, reporter)] + return recorder, ok +} + +func (h *CreateEventHandler) createRecorder(namespace, reporter string) record.EventRecorder { + h.mu.Lock() + defer h.mu.Unlock() + + key := fmt.Sprintf("%s-%s", namespace, reporter) + if _, ok := h.eventNsRecorder[key]; !ok { + h.log.Infof("creating event recorder and broadcaster for %v", fmt.Sprintf("%s-%s", namespace, reporter)) + broadcaster, rec := h.recorderFactory(namespace, reporter) + h.eventNsBroadcaster[key] = broadcaster + h.eventNsRecorder[key] = rec + } + + return h.eventNsRecorder[key] +} + +func (h *CreateEventHandler) Close() error { + h.mu.Lock() + defer h.mu.Unlock() + + for _, broadcaster := range h.eventNsBroadcaster { + broadcaster.Shutdown() + } + h.eventNsBroadcaster = map[string]record.EventBroadcaster{} + h.eventNsRecorder = map[string]record.EventRecorder{} + + return nil +} diff --git a/actions/create_event_handler_test.go b/internal/actions/create_event_handler_test.go similarity index 73% rename from actions/create_event_handler_test.go rename to internal/actions/create_event_handler_test.go index 1d074b7e..06dcb17a 100644 --- a/actions/create_event_handler_test.go +++ b/internal/actions/create_event_handler_test.go @@ -7,22 +7,24 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" + k8s_types "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/record" - "github.com/castai/cluster-controller/castai" + mock_actions "github.com/castai/cluster-controller/internal/actions/mock" + "github.com/castai/cluster-controller/internal/castai" ) func TestCreateEvent(t *testing.T) { r := require.New(t) - id := types.UID(uuid.New().String()) + id := k8s_types.UID(uuid.New().String()) tests := []struct { name string @@ -86,17 +88,18 @@ func TestCreateEvent(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - clientSet := fake.NewSimpleClientset(test.object) + clientSet := fake.NewClientset(test.object) recorder := record.NewFakeRecorder(test.actionCount) broadCaster := record.NewBroadcasterForTests(time.Second * 10) - h := createEventHandler{ + h := CreateEventHandler{ log: logrus.New(), clientSet: clientSet, eventNsRecorder: map[string]record.EventRecorder{ - "castai": recorder, + "castai-autoscaler.cast.ai": recorder, + "castai-provisioning.cast.ai": recorder, }, eventNsBroadcaster: map[string]record.EventBroadcaster{ - "castai": broadCaster, + "castai-provisioning.cast.ai": broadCaster, }, } ctx := context.Background() @@ -133,9 +136,9 @@ func TestRandomNs(t *testing.T) { t.Parallel() r := require.New(t) actionCount := 10 - clientSet := fake.NewSimpleClientset(testPod(types.UID(uuid.New().String()))) + clientSet := fake.NewClientset(testPod(k8s_types.UID(uuid.New().String()))) recorders := make([]*record.FakeRecorder, 0, actionCount) - h := createEventHandler{ + h := CreateEventHandler{ log: logrus.New(), clientSet: clientSet, recorderFactory: func(ns, reporter string) (record.EventBroadcaster, record.EventRecorder) { @@ -196,7 +199,7 @@ func TestRandomNs(t *testing.T) { } } -func testPod(id types.UID) *corev1.Pod { +func testPod(id k8s_types.UID) *corev1.Pod { return &corev1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", @@ -220,3 +223,63 @@ func podObjReference(p *corev1.Pod) corev1.ObjectReference { ResourceVersion: p.ResourceVersion, } } + +func TestCreateEventHandler_Handle(t *testing.T) { + t.Parallel() + type fields struct { + tuneMockClientSey func(m *mock_actions.MockInterface) + } + type args struct { + action *castai.ClusterAction + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "detect race condition: recorder and broadcaster should be called only once", + fields: fields{ + tuneMockClientSey: func(m *mock_actions.MockInterface) { + fakeClientSet := fake.NewClientset() + m.EXPECT().CoreV1().Return(fakeClientSet.CoreV1()) + }, + }, + args: args{ + action: &castai.ClusterAction{ + ID: "test-id", + ActionCreateEvent: &castai.ActionCreateEvent{ + Reporter: "test-reporter", + }, + }, + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + m := gomock.NewController(t) + defer m.Finish() + client := mock_actions.NewMockInterface(m) + if tt.fields.tuneMockClientSey != nil { + tt.fields.tuneMockClientSey(client) + } + handler := NewCreateEventHandler(logrus.New(), client) + // defer handler.Close() + actionCount := 10000 + wg := sync.WaitGroup{} + for i := 0; i < actionCount; i++ { + wg.Add(1) + go func() { + defer wg.Done() + if err := handler.Handle(context.Background(), tt.args.action); (err != nil) != tt.wantErr { + t.Errorf("Handle() error = %v, wantErr %v", err, tt.wantErr) + } + }() + } + wg.Wait() + }) + } +} diff --git a/actions/create_handler.go b/internal/actions/create_handler.go similarity index 85% rename from actions/create_handler.go rename to internal/actions/create_handler.go index 4c5bc8d8..0551f018 100644 --- a/actions/create_handler.go +++ b/internal/actions/create_handler.go @@ -12,25 +12,27 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" + k8s_types "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/dynamic" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) -type createHandler struct { +var _ ActionHandler = &CreateHandler{} + +type CreateHandler struct { log logrus.FieldLogger client dynamic.Interface } -func newCreateHandler(log logrus.FieldLogger, client dynamic.Interface) ActionHandler { - return &createHandler{ +func NewCreateHandler(log logrus.FieldLogger, client dynamic.Interface) *CreateHandler { + return &CreateHandler{ log: log, client: client, } } -func (h *createHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *CreateHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionCreate) if !ok { return newUnexpectedTypeErr(action.Data(), req) @@ -46,7 +48,7 @@ func (h *createHandler) Handle(ctx context.Context, action *castai.ClusterAction } log := h.log.WithFields(logrus.Fields{ - actionIDLogField: action.ID, + ActionIDLogField: action.ID, "action": reflect.TypeOf(action.Data()).String(), "gvr": req.GroupVersionResource.String(), "name": newObj.GetName(), @@ -105,7 +107,7 @@ func (h *createHandler) Handle(ctx context.Context, action *castai.ClusterAction } log.Infof("patching resource: %s", patch) - _, err = r.Patch(ctx, obj.GetName(), types.MergePatchType, patch, metav1.PatchOptions{}) + _, err = r.Patch(ctx, obj.GetName(), k8s_types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { return fmt.Errorf("patching resource %v: %w", obj.GetName(), err) } diff --git a/actions/create_handler_test.go b/internal/actions/create_handler_test.go similarity index 98% rename from actions/create_handler_test.go rename to internal/actions/create_handler_test.go index b853b217..dfa3f406 100644 --- a/actions/create_handler_test.go +++ b/internal/actions/create_handler_test.go @@ -16,7 +16,7 @@ import ( "k8s.io/client-go/dynamic/fake" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func Test_newCreateHandler(t *testing.T) { @@ -125,7 +125,7 @@ func Test_newCreateHandler(t *testing.T) { log := logrus.New() c := fake.NewSimpleDynamicClient(scheme, test.objs...) - handler := newCreateHandler(log, c) + handler := NewCreateHandler(log, c) err := handler.Handle(ctx, test.action) if test.err != nil { r.Error(err) diff --git a/csr/csr.go b/internal/actions/csr/csr.go similarity index 98% rename from csr/csr.go rename to internal/actions/csr/csr.go index dcb30f40..88e90cf5 100644 --- a/csr/csr.go +++ b/internal/actions/csr/csr.go @@ -19,7 +19,7 @@ import ( "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/waitext" ) const ( @@ -27,9 +27,7 @@ const ( approvedMessage = "This CSR was approved by CAST AI" ) -var ( - ErrNodeCertificateNotFound = errors.New("node certificate not found") -) +var ErrNodeCertificateNotFound = errors.New("node certificate not found") // Certificate wraps v1 and v1beta1 csr. type Certificate struct { @@ -311,7 +309,7 @@ func WatchCastAINodeCSRs(ctx context.Context, log logrus.FieldLogger, client kub case event, ok := <-w.ResultChan(): if !ok { log.Info("watcher closed") - go WatchCastAINodeCSRs(ctx, log, client, c) // start over in case of any error + go WatchCastAINodeCSRs(ctx, log, client, c) // start over in case of any error. return } @@ -421,6 +419,7 @@ func parseCSR(pemData []byte) (*x509.CertificateRequest, error) { return x509.ParseCertificateRequest(block.Bytes) } +//nolint:unparam func getOptions(signer string) metav1.ListOptions { return metav1.ListOptions{ FieldSelector: fields.SelectorFromSet(fields.Set{ diff --git a/csr/csr_test.go b/internal/actions/csr/csr_test.go similarity index 100% rename from csr/csr_test.go rename to internal/actions/csr/csr_test.go diff --git a/csr/svc.go b/internal/actions/csr/svc.go similarity index 97% rename from csr/svc.go rename to internal/actions/csr/svc.go index 08e1c7f0..817eba85 100644 --- a/csr/svc.go +++ b/internal/actions/csr/svc.go @@ -12,7 +12,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/waitext" ) const ( @@ -36,6 +36,7 @@ type ApprovalManager struct { func (h *ApprovalManager) Start(ctx context.Context) { go h.runAutoApproveForCastAINodes(ctx) } + func (h *ApprovalManager) Stop(ctx context.Context) { h.stopAutoApproveForCastAINodes() } @@ -96,7 +97,7 @@ func (h *ApprovalManager) runAutoApproveForCastAINodes(ctx context.Context) { defer cancel() if !h.startAutoApprove(cancel) { - return // already running + return // already running. } defer h.stopAutoApproveForCastAINodes() diff --git a/csr/svc_test.go b/internal/actions/csr/svc_test.go similarity index 97% rename from csr/svc_test.go rename to internal/actions/csr/svc_test.go index 7ed2c512..4b40fad6 100644 --- a/csr/svc_test.go +++ b/internal/actions/csr/svc_test.go @@ -3,19 +3,17 @@ package csr import ( "context" "sync" - + "testing" "time" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" certv1 "k8s.io/api/certificates/v1" - "k8s.io/apimachinery/pkg/watch" - ktest "k8s.io/client-go/testing" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes/fake" + ktest "k8s.io/client-go/testing" ) -import "testing" func getCSR(name, username string) *certv1.CertificateSigningRequest { return &certv1.CertificateSigningRequest{ @@ -34,7 +32,7 @@ S59zc2bEaJ3y4aSMXLY3gmri14jZvvnFrxaPDT2PAiEA7C3hvZwrCJsoO61JWKqc Usages: []certv1.KeyUsage{"kubelet"}, Username: username, }, - //Status: certv1.CertificateSigningRequestStatus{}, + // Status: certv1.CertificateSigningRequestStatus{},. } } diff --git a/actions/delete_handler.go b/internal/actions/delete_handler.go similarity index 80% rename from actions/delete_handler.go rename to internal/actions/delete_handler.go index 8394a34d..f652e0b8 100644 --- a/actions/delete_handler.go +++ b/internal/actions/delete_handler.go @@ -11,22 +11,24 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) -type deleteHandler struct { +var _ ActionHandler = &DeleteHandler{} + +type DeleteHandler struct { log logrus.FieldLogger client dynamic.Interface } -func newDeleteHandler(log logrus.FieldLogger, client dynamic.Interface) ActionHandler { - return &deleteHandler{ +func NewDeleteHandler(log logrus.FieldLogger, client dynamic.Interface) *DeleteHandler { + return &DeleteHandler{ log: log, client: client, } } -func (h *deleteHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *DeleteHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionDelete) if !ok { return newUnexpectedTypeErr(action.Data(), req) diff --git a/actions/delete_handler_test.go b/internal/actions/delete_handler_test.go similarity index 97% rename from actions/delete_handler_test.go rename to internal/actions/delete_handler_test.go index 0c019970..25b159e1 100644 --- a/actions/delete_handler_test.go +++ b/internal/actions/delete_handler_test.go @@ -14,7 +14,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic/fake" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func Test_newDeleteHandler(t *testing.T) { @@ -103,7 +103,7 @@ func Test_newDeleteHandler(t *testing.T) { log := logrus.New() c := fake.NewSimpleDynamicClient(scheme, test.objs...) - handler := newDeleteHandler(log, c) + handler := NewDeleteHandler(log, c) err := handler.Handle(ctx, test.action) if test.err != nil { r.Error(err) diff --git a/actions/delete_node_handler.go b/internal/actions/delete_node_handler.go similarity index 90% rename from actions/delete_node_handler.go rename to internal/actions/delete_node_handler.go index a445e43b..5f143ad7 100644 --- a/actions/delete_node_handler.go +++ b/internal/actions/delete_node_handler.go @@ -14,10 +14,12 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) +var _ ActionHandler = &DeleteNodeHandler{} + type deleteNodeConfig struct { deleteRetries int deleteRetryWait time.Duration @@ -26,8 +28,8 @@ type deleteNodeConfig struct { var errNodeMismatch = errors.New("node id mismatch") -func newDeleteNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - return &deleteNodeHandler{ +func NewDeleteNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *DeleteNodeHandler { + return &DeleteNodeHandler{ log: log, clientset: clientset, cfg: deleteNodeConfig{ @@ -35,21 +37,21 @@ func newDeleteNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface deleteRetryWait: 5 * time.Second, podsTerminationWait: 30 * time.Second, }, - drainNodeHandler: drainNodeHandler{ + DrainNodeHandler: DrainNodeHandler{ log: log, clientset: clientset, }, } } -type deleteNodeHandler struct { - drainNodeHandler +type DeleteNodeHandler struct { + DrainNodeHandler log logrus.FieldLogger clientset kubernetes.Interface cfg deleteNodeConfig } -func (h *deleteNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *DeleteNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionDeleteNode) if !ok { return fmt.Errorf("unexpected type %T for delete node handler", action.Data()) @@ -59,7 +61,7 @@ func (h *deleteNodeHandler) Handle(ctx context.Context, action *castai.ClusterAc "node_name": req.NodeName, "node_id": req.NodeID, "type": reflect.TypeOf(action.Data().(*castai.ActionDeleteNode)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) log.Info("deleting kubernetes node") @@ -175,7 +177,7 @@ func (h *deleteNodeHandler) Handle(ctx context.Context, action *castai.ClusterAc ) } -func (h *deleteNodeHandler) deleteNodeVolumeAttachments(ctx context.Context, nodeName string) error { +func (h *DeleteNodeHandler) deleteNodeVolumeAttachments(ctx context.Context, nodeName string) error { volumeAttachments, err := h.clientset.StorageV1().VolumeAttachments().List(ctx, metav1.ListOptions{}) if err != nil { return err @@ -187,7 +189,8 @@ func (h *deleteNodeHandler) deleteNodeVolumeAttachments(ctx context.Context, nod // Delete the volume attachment. if err := h.clientset.StorageV1().VolumeAttachments(). Delete(ctx, va.Name, metav1.DeleteOptions{ - GracePeriodSeconds: &gracePeriod}); err != nil { + GracePeriodSeconds: &gracePeriod, + }); err != nil { return err } } diff --git a/actions/delete_node_handler_test.go b/internal/actions/delete_node_handler_test.go similarity index 93% rename from actions/delete_node_handler_test.go rename to internal/actions/delete_node_handler_test.go index 1ed1a970..4d3e9fe0 100644 --- a/actions/delete_node_handler_test.go +++ b/internal/actions/delete_node_handler_test.go @@ -5,18 +5,18 @@ import ( "testing" "github.com/google/uuid" - "k8s.io/apimachinery/pkg/fields" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "k8s.io/client-go/kubernetes/fake" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) +//nolint:goconst func TestDeleteNodeHandler(t *testing.T) { log := logrus.New() log.SetLevel(logrus.DebugLevel) @@ -38,7 +38,7 @@ func TestDeleteNodeHandler(t *testing.T) { }, } - h := deleteNodeHandler{ + h := DeleteNodeHandler{ log: log, clientset: clientset, cfg: deleteNodeConfig{}, @@ -69,7 +69,7 @@ func TestDeleteNodeHandler(t *testing.T) { }, } - h := deleteNodeHandler{ + h := DeleteNodeHandler{ log: log, clientset: clientset, cfg: deleteNodeConfig{}, @@ -103,7 +103,7 @@ func TestDeleteNodeHandler(t *testing.T) { }, } - h := deleteNodeHandler{ + h := DeleteNodeHandler{ log: log, clientset: clientset, cfg: deleteNodeConfig{}, @@ -130,13 +130,13 @@ func TestDeleteNodeHandler(t *testing.T) { }, } - h := deleteNodeHandler{ + h := DeleteNodeHandler{ log: log, clientset: clientset, cfg: deleteNodeConfig{ podsTerminationWait: 1, }, - drainNodeHandler: drainNodeHandler{clientset: clientset, log: log}, + DrainNodeHandler: DrainNodeHandler{clientset: clientset, log: log}, } err := h.Handle(context.Background(), action) diff --git a/actions/disconnect_cluster_handler.go b/internal/actions/disconnect_cluster_handler.go similarity index 70% rename from actions/disconnect_cluster_handler.go rename to internal/actions/disconnect_cluster_handler.go index 1acbad70..d165d265 100644 --- a/actions/disconnect_cluster_handler.go +++ b/internal/actions/disconnect_cluster_handler.go @@ -3,28 +3,31 @@ package actions import ( "context" "fmt" - "github.com/castai/cluster-controller/castai" "reflect" "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + + "github.com/castai/cluster-controller/internal/castai" ) -func newDisconnectClusterHandler(log logrus.FieldLogger, client kubernetes.Interface) ActionHandler { - return &disconnectClusterHandler{ +var _ ActionHandler = &DisconnectClusterHandler{} + +func NewDisconnectClusterHandler(log logrus.FieldLogger, client kubernetes.Interface) *DisconnectClusterHandler { + return &DisconnectClusterHandler{ log: log, client: client, } } -type disconnectClusterHandler struct { +type DisconnectClusterHandler struct { log logrus.FieldLogger client kubernetes.Interface } -func (c *disconnectClusterHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (c *DisconnectClusterHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { ns := "castai-agent" _, err := c.client.CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) if err != nil { @@ -41,13 +44,13 @@ func (c *disconnectClusterHandler) Handle(ctx context.Context, action *castai.Cl } log := c.log.WithFields(logrus.Fields{ "type": reflect.TypeOf(action.Data().(*castai.ActionDisconnectCluster)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) log.Infof("deleting namespace %q", ns) gracePeriod := int64(0) // Delete immediately. if err := c.client.CoreV1().Namespaces().Delete(ctx, ns, metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod}); err != nil { - return fmt.Errorf("deleting namespace %q: %v", ns, err) + return fmt.Errorf("deleting namespace %q: %w", ns, err) } return nil diff --git a/actions/disconnect_cluster_handler_test.go b/internal/actions/disconnect_cluster_handler_test.go similarity index 87% rename from actions/disconnect_cluster_handler_test.go rename to internal/actions/disconnect_cluster_handler_test.go index 5bf06e1d..5cef8f80 100644 --- a/actions/disconnect_cluster_handler_test.go +++ b/internal/actions/disconnect_cluster_handler_test.go @@ -2,9 +2,9 @@ package actions import ( "context" - "github.com/google/uuid" "testing" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -12,7 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestDisconnectClusterHandler(t *testing.T) { @@ -31,7 +31,7 @@ func TestDisconnectClusterHandler(t *testing.T) { ID: uuid.New().String(), ActionDisconnectCluster: &castai.ActionDisconnectCluster{}, } - handler := newDisconnectClusterHandler(logrus.New(), clientset) + handler := NewDisconnectClusterHandler(logrus.New(), clientset) err := handler.Handle(ctx, action) r.NoError(err) diff --git a/actions/drain_node_handler.go b/internal/actions/drain_node_handler.go similarity index 93% rename from actions/drain_node_handler.go rename to internal/actions/drain_node_handler.go index e3e93371..ec5d09a0 100644 --- a/actions/drain_node_handler.go +++ b/internal/actions/drain_node_handler.go @@ -20,12 +20,14 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/kubectl/pkg/drain" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) +var _ ActionHandler = &DrainNodeHandler{} + const ( - minDrainTimeout = 0 // Minimal pod drain timeout + minDrainTimeout = 0 // Minimal pod drain timeout. ) type drainNodeConfig struct { @@ -38,8 +40,8 @@ type drainNodeConfig struct { skipDeletedTimeoutSeconds int } -func newDrainNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface, castNamespace string) ActionHandler { - return &drainNodeHandler{ +func NewDrainNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface, castNamespace string) *DrainNodeHandler { + return &DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{ @@ -56,7 +58,7 @@ func newDrainNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface, // getDrainTimeout returns drain timeout adjusted to action creation time. // the result is clamped between 0s and the requested timeout. -func (h *drainNodeHandler) getDrainTimeout(action *castai.ClusterAction) time.Duration { +func (h *DrainNodeHandler) getDrainTimeout(action *castai.ClusterAction) time.Duration { timeSinceCreated := time.Since(action.CreatedAt) requestedTimeout := time.Duration(action.ActionDrainNode.DrainTimeoutSeconds) * time.Second @@ -65,13 +67,13 @@ func (h *drainNodeHandler) getDrainTimeout(action *castai.ClusterAction) time.Du return lo.Clamp(drainTimeout, minDrainTimeout*time.Second, requestedTimeout) } -type drainNodeHandler struct { +type DrainNodeHandler struct { log logrus.FieldLogger clientset kubernetes.Interface cfg drainNodeConfig } -func (h *drainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *DrainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionDrainNode) if !ok { return fmt.Errorf("unexpected type %T for drain handler", action.Data()) @@ -82,7 +84,7 @@ func (h *drainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct "node_name": req.NodeName, "node_id": req.NodeID, "action": reflect.TypeOf(action.Data().(*castai.ActionDrainNode)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) node, err := h.clientset.CoreV1().Nodes().Get(ctx, req.NodeName, metav1.GetOptions{}) @@ -124,7 +126,7 @@ func (h *drainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct case errors.As(err, &podsFailedEvictionErr): log.Infof("some pods failed eviction, force=%v, starting pod deletion: %v", req.Force, err) default: - // Expected to be errors where we can't continue at all; e.g. missing permissions or lack of connectivity + // Expected to be errors where we can't continue at all; e.g. missing permissions or lack of connectivity. return fmt.Errorf("evicting node pods: %w", err) } @@ -141,7 +143,7 @@ func (h *drainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct deleteErr = h.deleteNodePods(deleteCtx, log, node, o) - // Clean-up the child context if we got here; no reason to wait for the function to exit + // Clean-up the child context if we got here; no reason to wait for the function to exit. deleteCancel() if deleteErr == nil { @@ -165,7 +167,7 @@ func (h *drainNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct return deleteErr } -func (h *drainNodeHandler) cordonNode(ctx context.Context, node *v1.Node) error { +func (h *DrainNodeHandler) cordonNode(ctx context.Context, node *v1.Node) error { if node.Spec.Unschedulable { return nil } @@ -179,7 +181,7 @@ func (h *drainNodeHandler) cordonNode(ctx context.Context, node *v1.Node) error return nil } -// Return error if at least one pod failed (but don't wait for it!) => to signal if we should do force delete +// Return error if at least one pod failed (but don't wait for it!) => to signal if we should do force delete. // evictNodePods attempts voluntarily eviction for all pods on node. // This method will wait until all evictable pods on the node either terminate or fail deletion. @@ -187,7 +189,7 @@ func (h *drainNodeHandler) cordonNode(ctx context.Context, node *v1.Node) error // Errors in calling EVICT for individual pods are accumulated. If at least one pod failed this but termination was successful, an instance of podFailedActionError is returned. // The method will still wait for termination of other evicted pods first. // A return value of nil means all pods on the node should be evicted and terminated. -func (h *drainNodeHandler) evictNodePods(ctx context.Context, log logrus.FieldLogger, node *v1.Node) error { +func (h *DrainNodeHandler) evictNodePods(ctx context.Context, log logrus.FieldLogger, node *v1.Node) error { pods, err := h.listNodePodsToEvict(ctx, log, node) if err != nil { return err @@ -239,7 +241,7 @@ func (h *drainNodeHandler) evictNodePods(ctx context.Context, log logrus.FieldLo // Errors in calling DELETE for individual pods are accumulated. If at least one pod failed this but termination was successful, an instance of podFailedActionError is returned. // The method will still wait for termination of other deleted pods first. // A return value of nil means all pods on the node should be deleted and terminated. -func (h *drainNodeHandler) deleteNodePods(ctx context.Context, log logrus.FieldLogger, node *v1.Node, options metav1.DeleteOptions) error { +func (h *DrainNodeHandler) deleteNodePods(ctx context.Context, log logrus.FieldLogger, node *v1.Node, options metav1.DeleteOptions) error { pods, err := h.listNodePodsToEvict(ctx, log, node) if err != nil { return err @@ -293,7 +295,7 @@ func (h *drainNodeHandler) deleteNodePods(ctx context.Context, log logrus.FieldL // - DaemonSet pods // - pods that are already finished (Succeeded or Failed) // - pods that were marked for deletion recently (Terminating state); the meaning of "recently" is controlled by config -func (h *drainNodeHandler) listNodePodsToEvict(ctx context.Context, log logrus.FieldLogger, node *v1.Node) ([]v1.Pod, error) { +func (h *DrainNodeHandler) listNodePodsToEvict(ctx context.Context, log logrus.FieldLogger, node *v1.Node) ([]v1.Pod, error) { var pods *v1.PodList err := waitext.Retry( ctx, @@ -319,7 +321,7 @@ func (h *drainNodeHandler) listNodePodsToEvict(ctx context.Context, log logrus.F podsToEvict := make([]v1.Pod, 0) castPods := make([]v1.Pod, 0) - // Evict CAST PODs as last ones + // Evict CAST PODs as last ones. for _, p := range pods.Items { // Skip pods that have been recently removed. if !p.ObjectMeta.DeletionTimestamp.IsZero() && @@ -352,13 +354,13 @@ func (h *drainNodeHandler) listNodePodsToEvict(ctx context.Context, log logrus.F // If podsToIgnore is not empty, the list is further filtered by it. // This is useful when you don't expect some pods on the node to terminate (e.g. because eviction failed for them) so there is no reason to wait until timeout. // The wait can potentially run forever if pods are scheduled on the node and are not evicted/deleted by anything. Use a timeout to avoid infinite wait. -func (h *drainNodeHandler) waitNodePodsTerminated(ctx context.Context, log logrus.FieldLogger, node *v1.Node, podsToIgnore []*v1.Pod) error { +func (h *DrainNodeHandler) waitNodePodsTerminated(ctx context.Context, log logrus.FieldLogger, node *v1.Node, podsToIgnore []*v1.Pod) error { // Check if context is cancelled before starting any work. select { case <-ctx.Done(): return ctx.Err() default: - // Continue with the work + // Continue with the work. } podsToIgnoreLookup := make(map[string]struct{}) @@ -399,7 +401,7 @@ func (h *drainNodeHandler) waitNodePodsTerminated(ctx context.Context, log logru // evictPod from the k8s node. Error handling is based on eviction api documentation: // https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/#the-eviction-api -func (h *drainNodeHandler) evictPod(ctx context.Context, pod v1.Pod, groupVersion schema.GroupVersion) error { +func (h *DrainNodeHandler) evictPod(ctx context.Context, pod v1.Pod, groupVersion schema.GroupVersion) error { b := waitext.NewConstantBackoff(h.cfg.podEvictRetryDelay) action := func(ctx context.Context) (bool, error) { var err error @@ -453,7 +455,7 @@ func (h *drainNodeHandler) evictPod(ctx context.Context, pod v1.Pod, groupVersio return nil } -func (h *drainNodeHandler) deletePod(ctx context.Context, options metav1.DeleteOptions, pod v1.Pod) error { +func (h *DrainNodeHandler) deletePod(ctx context.Context, options metav1.DeleteOptions, pod v1.Pod) error { b := waitext.NewConstantBackoff(h.cfg.podDeleteRetryDelay) action := func(ctx context.Context) (bool, error) { err := h.clientset.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, options) diff --git a/actions/drain_node_handler_test.go b/internal/actions/drain_node_handler_test.go similarity index 96% rename from actions/drain_node_handler_test.go rename to internal/actions/drain_node_handler_test.go index 7e36475b..4e20647d 100644 --- a/actions/drain_node_handler_test.go +++ b/internal/actions/drain_node_handler_test.go @@ -19,7 +19,7 @@ import ( "k8s.io/client-go/kubernetes/fake" ktest "k8s.io/client-go/testing" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestDrainNodeHandler(t *testing.T) { @@ -46,7 +46,7 @@ func TestDrainNodeHandler(t *testing.T) { }, CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{}, @@ -89,7 +89,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{}, @@ -120,7 +120,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{}, @@ -157,7 +157,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{}, @@ -217,7 +217,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{ @@ -226,7 +226,8 @@ func TestDrainNodeHandler(t *testing.T) { podDeleteRetryDelay: 500 * time.Millisecond, podEvictRetryDelay: 500 * time.Millisecond, podsTerminationWaitRetryDelay: 1000 * time.Millisecond, - }} + }, + } actualCalls := 0 clientset.PrependReactor("delete", "pods", func(action ktest.Action) (handled bool, ret runtime.Object, err error) { @@ -234,11 +235,11 @@ func TestDrainNodeHandler(t *testing.T) { if deleteAction.Name == podName { actualCalls++ // First call should be graceful; simulate it failed to validate we'll do the forced part. - // This relies on us not retrying 404s (or let's say it tests it :) ) + // This relies on us not retrying 404s (or let's say it tests it :) ). if deleteAction.DeleteOptions.GracePeriodSeconds == nil { return true, nil, &apierrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonNotFound}} } - // Second call should be forced + // Second call should be forced. r.Equal(int64(0), *deleteAction.DeleteOptions.GracePeriodSeconds) return false, nil, nil } @@ -276,7 +277,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{ @@ -285,7 +286,8 @@ func TestDrainNodeHandler(t *testing.T) { podDeleteRetryDelay: 5 * time.Second, podEvictRetryDelay: 5 * time.Second, podsTerminationWaitRetryDelay: 10 * time.Second, - }} + }, + } clientset.PrependReactor("delete", "pods", func(action ktest.Action) (handled bool, ret runtime.Object, err error) { deleteAction := action.(ktest.DeleteActionImpl) @@ -325,16 +327,17 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{ - podsDeleteTimeout: 0, // Force delete to timeout immediately + podsDeleteTimeout: 0, // Force delete to timeout immediately. podDeleteRetries: 5, podDeleteRetryDelay: 5 * time.Second, podEvictRetryDelay: 5 * time.Second, podsTerminationWaitRetryDelay: 10 * time.Second, - }} + }, + } actualDeleteCalls := 0 clientset.PrependReactor("delete", "pods", func(action ktest.Action) (handled bool, ret runtime.Object, err error) { @@ -358,7 +361,7 @@ func TestDrainNodeHandler(t *testing.T) { t.Run("force=true, failed eviction for PDBs should be retried until timeout before deleting", func(t *testing.T) { t.Parallel() - // tests specifically that PDB error in eviction is retried and not failed fast + // tests specifically that PDB error in eviction is retried and not failed fast. nodeName := "node1" podName := "pod1" clientset := setupFakeClientWithNodePodEviction(nodeName, podName) @@ -393,7 +396,7 @@ func TestDrainNodeHandler(t *testing.T) { CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, clientset: clientset, cfg: drainNodeConfig{}, @@ -429,14 +432,14 @@ func TestGetDrainTimeout(t *testing.T) { }, CreatedAt: time.Now().UTC(), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, cfg: drainNodeConfig{}, } timeout := h.getDrainTimeout(action) - // We give some wiggle room as the test might get here a few milliseconds late + // We give some wiggle room as the test might get here a few milliseconds late. r.InDelta((100 * time.Second).Milliseconds(), timeout.Milliseconds(), 10) }) @@ -451,7 +454,7 @@ func TestGetDrainTimeout(t *testing.T) { }, CreatedAt: time.Now().UTC().Add(-3 * time.Minute), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, cfg: drainNodeConfig{}, } @@ -471,7 +474,7 @@ func TestGetDrainTimeout(t *testing.T) { }, CreatedAt: time.Now().UTC().Add(-60 * time.Minute), } - h := drainNodeHandler{ + h := DrainNodeHandler{ log: log, cfg: drainNodeConfig{}, } @@ -504,7 +507,6 @@ func TestLogCastPodsToEvict(t *testing.T) { r.Len(hook.Entries, 0) }) - } func prependEvictionReaction(t *testing.T, c *fake.Clientset, success, retryableFailure bool) { @@ -524,7 +526,7 @@ func prependEvictionReaction(t *testing.T, c *fake.Clientset, success, retryable return true, nil, nil } - // Simulate failure that should be retried by client + // Simulate failure that should be retried by client. if retryableFailure { return true, nil, &apierrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonTooManyRequests}} } @@ -533,6 +535,7 @@ func prependEvictionReaction(t *testing.T, c *fake.Clientset, success, retryable }) } +// nolint: unparam func setupFakeClientWithNodePodEviction(nodeName, podName string) *fake.Clientset { node := &v1.Node{ ObjectMeta: metav1.ObjectMeta{ diff --git a/actions/kubernetes_helpers.go b/internal/actions/kubernetes_helpers.go similarity index 98% rename from actions/kubernetes_helpers.go rename to internal/actions/kubernetes_helpers.go index e0f3403f..bc471072 100644 --- a/actions/kubernetes_helpers.go +++ b/internal/actions/kubernetes_helpers.go @@ -17,7 +17,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/waitext" ) const ( @@ -69,7 +69,7 @@ func patchNodeStatus(ctx context.Context, log logrus.FieldLogger, clientset kube func(ctx context.Context) (bool, error) { _, err := clientset.CoreV1().Nodes().PatchStatus(ctx, name, patch) if k8serrors.IsForbidden(err) { - // permissions might be of older version that can't patch node/status + // permissions might be of older version that can't patch node/status. log.WithField("node", name).WithError(err).Warn("skip patch node/status") return false, nil } @@ -79,7 +79,6 @@ func patchNodeStatus(ctx context.Context, log logrus.FieldLogger, clientset kube log.Warnf("patch node status, will retry: %v", err) }, ) - if err != nil { return fmt.Errorf("patch status: %w", err) } @@ -117,7 +116,6 @@ func getNodeForPatching(ctx context.Context, log logrus.FieldLogger, clientset k return nil, err } return node, nil - } // executeBatchPodActions executes the action for each pod in the list. diff --git a/internal/actions/mock/handler.go b/internal/actions/mock/handler.go new file mode 100644 index 00000000..b653dbbe --- /dev/null +++ b/internal/actions/mock/handler.go @@ -0,0 +1,50 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/castai/cluster-controller/internal/actions (interfaces: ActionHandler) + +// Package mock_actions is a generated GoMock package. +package mock_actions + +import ( + context "context" + reflect "reflect" + + castai "github.com/castai/cluster-controller/internal/castai" + gomock "github.com/golang/mock/gomock" +) + +// MockActionHandler is a mock of ActionHandler interface. +type MockActionHandler struct { + ctrl *gomock.Controller + recorder *MockActionHandlerMockRecorder +} + +// MockActionHandlerMockRecorder is the mock recorder for MockActionHandler. +type MockActionHandlerMockRecorder struct { + mock *MockActionHandler +} + +// NewMockActionHandler creates a new mock instance. +func NewMockActionHandler(ctrl *gomock.Controller) *MockActionHandler { + mock := &MockActionHandler{ctrl: ctrl} + mock.recorder = &MockActionHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockActionHandler) EXPECT() *MockActionHandlerMockRecorder { + return m.recorder +} + +// Handle mocks base method. +func (m *MockActionHandler) Handle(arg0 context.Context, arg1 *castai.ClusterAction) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Handle", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Handle indicates an expected call of Handle. +func (mr *MockActionHandlerMockRecorder) Handle(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handle", reflect.TypeOf((*MockActionHandler)(nil).Handle), arg0, arg1) +} diff --git a/internal/actions/mock/kubernetes.go b/internal/actions/mock/kubernetes.go new file mode 100644 index 00000000..02b834cd --- /dev/null +++ b/internal/actions/mock/kubernetes.go @@ -0,0 +1,844 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: k8s.io/client-go/kubernetes (interfaces: Interface) + +// Package mock_actions is a generated GoMock package. +package mock_actions + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + discovery "k8s.io/client-go/discovery" + v1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" + v1alpha1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1" + v1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1" + v1alpha10 "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1" + v10 "k8s.io/client-go/kubernetes/typed/apps/v1" + v1beta10 "k8s.io/client-go/kubernetes/typed/apps/v1beta1" + v1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" + v11 "k8s.io/client-go/kubernetes/typed/authentication/v1" + v1alpha11 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1" + v1beta11 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1" + v12 "k8s.io/client-go/kubernetes/typed/authorization/v1" + v1beta12 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1" + v13 "k8s.io/client-go/kubernetes/typed/autoscaling/v1" + v2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2" + v2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" + v2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" + v14 "k8s.io/client-go/kubernetes/typed/batch/v1" + v1beta13 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" + v15 "k8s.io/client-go/kubernetes/typed/certificates/v1" + v1alpha12 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" + v1beta14 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" + v16 "k8s.io/client-go/kubernetes/typed/coordination/v1" + v1alpha13 "k8s.io/client-go/kubernetes/typed/coordination/v1alpha1" + v1beta15 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" + v17 "k8s.io/client-go/kubernetes/typed/core/v1" + v18 "k8s.io/client-go/kubernetes/typed/discovery/v1" + v1beta16 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1" + v19 "k8s.io/client-go/kubernetes/typed/events/v1" + v1beta17 "k8s.io/client-go/kubernetes/typed/events/v1beta1" + v1beta18 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1" + v110 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1" + v1beta19 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1" + v1beta20 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2" + v1beta3 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" + v111 "k8s.io/client-go/kubernetes/typed/networking/v1" + v1alpha14 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1" + v1beta110 "k8s.io/client-go/kubernetes/typed/networking/v1beta1" + v112 "k8s.io/client-go/kubernetes/typed/node/v1" + v1alpha15 "k8s.io/client-go/kubernetes/typed/node/v1alpha1" + v1beta111 "k8s.io/client-go/kubernetes/typed/node/v1beta1" + v113 "k8s.io/client-go/kubernetes/typed/policy/v1" + v1beta112 "k8s.io/client-go/kubernetes/typed/policy/v1beta1" + v114 "k8s.io/client-go/kubernetes/typed/rbac/v1" + v1alpha16 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" + v1beta113 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" + v1alpha3 "k8s.io/client-go/kubernetes/typed/resource/v1alpha3" + v115 "k8s.io/client-go/kubernetes/typed/scheduling/v1" + v1alpha17 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" + v1beta114 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" + v116 "k8s.io/client-go/kubernetes/typed/storage/v1" + v1alpha18 "k8s.io/client-go/kubernetes/typed/storage/v1alpha1" + v1beta115 "k8s.io/client-go/kubernetes/typed/storage/v1beta1" + v1alpha19 "k8s.io/client-go/kubernetes/typed/storagemigration/v1alpha1" +) + +// MockInterface is a mock of Interface interface. +type MockInterface struct { + ctrl *gomock.Controller + recorder *MockInterfaceMockRecorder +} + +// MockInterfaceMockRecorder is the mock recorder for MockInterface. +type MockInterfaceMockRecorder struct { + mock *MockInterface +} + +// NewMockInterface creates a new mock instance. +func NewMockInterface(ctrl *gomock.Controller) *MockInterface { + mock := &MockInterface{ctrl: ctrl} + mock.recorder = &MockInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder { + return m.recorder +} + +// AdmissionregistrationV1 mocks base method. +func (m *MockInterface) AdmissionregistrationV1() v1.AdmissionregistrationV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdmissionregistrationV1") + ret0, _ := ret[0].(v1.AdmissionregistrationV1Interface) + return ret0 +} + +// AdmissionregistrationV1 indicates an expected call of AdmissionregistrationV1. +func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1)) +} + +// AdmissionregistrationV1alpha1 mocks base method. +func (m *MockInterface) AdmissionregistrationV1alpha1() v1alpha1.AdmissionregistrationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdmissionregistrationV1alpha1") + ret0, _ := ret[0].(v1alpha1.AdmissionregistrationV1alpha1Interface) + return ret0 +} + +// AdmissionregistrationV1alpha1 indicates an expected call of AdmissionregistrationV1alpha1. +func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1alpha1)) +} + +// AdmissionregistrationV1beta1 mocks base method. +func (m *MockInterface) AdmissionregistrationV1beta1() v1beta1.AdmissionregistrationV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdmissionregistrationV1beta1") + ret0, _ := ret[0].(v1beta1.AdmissionregistrationV1beta1Interface) + return ret0 +} + +// AdmissionregistrationV1beta1 indicates an expected call of AdmissionregistrationV1beta1. +func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1beta1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1beta1)) +} + +// AppsV1 mocks base method. +func (m *MockInterface) AppsV1() v10.AppsV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AppsV1") + ret0, _ := ret[0].(v10.AppsV1Interface) + return ret0 +} + +// AppsV1 indicates an expected call of AppsV1. +func (mr *MockInterfaceMockRecorder) AppsV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1", reflect.TypeOf((*MockInterface)(nil).AppsV1)) +} + +// AppsV1beta1 mocks base method. +func (m *MockInterface) AppsV1beta1() v1beta10.AppsV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AppsV1beta1") + ret0, _ := ret[0].(v1beta10.AppsV1beta1Interface) + return ret0 +} + +// AppsV1beta1 indicates an expected call of AppsV1beta1. +func (mr *MockInterfaceMockRecorder) AppsV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1beta1", reflect.TypeOf((*MockInterface)(nil).AppsV1beta1)) +} + +// AppsV1beta2 mocks base method. +func (m *MockInterface) AppsV1beta2() v1beta2.AppsV1beta2Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AppsV1beta2") + ret0, _ := ret[0].(v1beta2.AppsV1beta2Interface) + return ret0 +} + +// AppsV1beta2 indicates an expected call of AppsV1beta2. +func (mr *MockInterfaceMockRecorder) AppsV1beta2() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1beta2", reflect.TypeOf((*MockInterface)(nil).AppsV1beta2)) +} + +// AuthenticationV1 mocks base method. +func (m *MockInterface) AuthenticationV1() v11.AuthenticationV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthenticationV1") + ret0, _ := ret[0].(v11.AuthenticationV1Interface) + return ret0 +} + +// AuthenticationV1 indicates an expected call of AuthenticationV1. +func (mr *MockInterfaceMockRecorder) AuthenticationV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1)) +} + +// AuthenticationV1alpha1 mocks base method. +func (m *MockInterface) AuthenticationV1alpha1() v1alpha11.AuthenticationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthenticationV1alpha1") + ret0, _ := ret[0].(v1alpha11.AuthenticationV1alpha1Interface) + return ret0 +} + +// AuthenticationV1alpha1 indicates an expected call of AuthenticationV1alpha1. +func (mr *MockInterfaceMockRecorder) AuthenticationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1alpha1)) +} + +// AuthenticationV1beta1 mocks base method. +func (m *MockInterface) AuthenticationV1beta1() v1beta11.AuthenticationV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthenticationV1beta1") + ret0, _ := ret[0].(v1beta11.AuthenticationV1beta1Interface) + return ret0 +} + +// AuthenticationV1beta1 indicates an expected call of AuthenticationV1beta1. +func (mr *MockInterfaceMockRecorder) AuthenticationV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1beta1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1beta1)) +} + +// AuthorizationV1 mocks base method. +func (m *MockInterface) AuthorizationV1() v12.AuthorizationV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthorizationV1") + ret0, _ := ret[0].(v12.AuthorizationV1Interface) + return ret0 +} + +// AuthorizationV1 indicates an expected call of AuthorizationV1. +func (mr *MockInterfaceMockRecorder) AuthorizationV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationV1", reflect.TypeOf((*MockInterface)(nil).AuthorizationV1)) +} + +// AuthorizationV1beta1 mocks base method. +func (m *MockInterface) AuthorizationV1beta1() v1beta12.AuthorizationV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthorizationV1beta1") + ret0, _ := ret[0].(v1beta12.AuthorizationV1beta1Interface) + return ret0 +} + +// AuthorizationV1beta1 indicates an expected call of AuthorizationV1beta1. +func (mr *MockInterfaceMockRecorder) AuthorizationV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationV1beta1", reflect.TypeOf((*MockInterface)(nil).AuthorizationV1beta1)) +} + +// AutoscalingV1 mocks base method. +func (m *MockInterface) AutoscalingV1() v13.AutoscalingV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AutoscalingV1") + ret0, _ := ret[0].(v13.AutoscalingV1Interface) + return ret0 +} + +// AutoscalingV1 indicates an expected call of AutoscalingV1. +func (mr *MockInterfaceMockRecorder) AutoscalingV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV1", reflect.TypeOf((*MockInterface)(nil).AutoscalingV1)) +} + +// AutoscalingV2 mocks base method. +func (m *MockInterface) AutoscalingV2() v2.AutoscalingV2Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AutoscalingV2") + ret0, _ := ret[0].(v2.AutoscalingV2Interface) + return ret0 +} + +// AutoscalingV2 indicates an expected call of AutoscalingV2. +func (mr *MockInterfaceMockRecorder) AutoscalingV2() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2)) +} + +// AutoscalingV2beta1 mocks base method. +func (m *MockInterface) AutoscalingV2beta1() v2beta1.AutoscalingV2beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AutoscalingV2beta1") + ret0, _ := ret[0].(v2beta1.AutoscalingV2beta1Interface) + return ret0 +} + +// AutoscalingV2beta1 indicates an expected call of AutoscalingV2beta1. +func (mr *MockInterfaceMockRecorder) AutoscalingV2beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2beta1", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2beta1)) +} + +// AutoscalingV2beta2 mocks base method. +func (m *MockInterface) AutoscalingV2beta2() v2beta2.AutoscalingV2beta2Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AutoscalingV2beta2") + ret0, _ := ret[0].(v2beta2.AutoscalingV2beta2Interface) + return ret0 +} + +// AutoscalingV2beta2 indicates an expected call of AutoscalingV2beta2. +func (mr *MockInterfaceMockRecorder) AutoscalingV2beta2() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2beta2", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2beta2)) +} + +// BatchV1 mocks base method. +func (m *MockInterface) BatchV1() v14.BatchV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BatchV1") + ret0, _ := ret[0].(v14.BatchV1Interface) + return ret0 +} + +// BatchV1 indicates an expected call of BatchV1. +func (mr *MockInterfaceMockRecorder) BatchV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchV1", reflect.TypeOf((*MockInterface)(nil).BatchV1)) +} + +// BatchV1beta1 mocks base method. +func (m *MockInterface) BatchV1beta1() v1beta13.BatchV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BatchV1beta1") + ret0, _ := ret[0].(v1beta13.BatchV1beta1Interface) + return ret0 +} + +// BatchV1beta1 indicates an expected call of BatchV1beta1. +func (mr *MockInterfaceMockRecorder) BatchV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchV1beta1", reflect.TypeOf((*MockInterface)(nil).BatchV1beta1)) +} + +// CertificatesV1 mocks base method. +func (m *MockInterface) CertificatesV1() v15.CertificatesV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CertificatesV1") + ret0, _ := ret[0].(v15.CertificatesV1Interface) + return ret0 +} + +// CertificatesV1 indicates an expected call of CertificatesV1. +func (mr *MockInterfaceMockRecorder) CertificatesV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1)) +} + +// CertificatesV1alpha1 mocks base method. +func (m *MockInterface) CertificatesV1alpha1() v1alpha12.CertificatesV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CertificatesV1alpha1") + ret0, _ := ret[0].(v1alpha12.CertificatesV1alpha1Interface) + return ret0 +} + +// CertificatesV1alpha1 indicates an expected call of CertificatesV1alpha1. +func (mr *MockInterfaceMockRecorder) CertificatesV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1alpha1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1alpha1)) +} + +// CertificatesV1beta1 mocks base method. +func (m *MockInterface) CertificatesV1beta1() v1beta14.CertificatesV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CertificatesV1beta1") + ret0, _ := ret[0].(v1beta14.CertificatesV1beta1Interface) + return ret0 +} + +// CertificatesV1beta1 indicates an expected call of CertificatesV1beta1. +func (mr *MockInterfaceMockRecorder) CertificatesV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1beta1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1beta1)) +} + +// CoordinationV1 mocks base method. +func (m *MockInterface) CoordinationV1() v16.CoordinationV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CoordinationV1") + ret0, _ := ret[0].(v16.CoordinationV1Interface) + return ret0 +} + +// CoordinationV1 indicates an expected call of CoordinationV1. +func (mr *MockInterfaceMockRecorder) CoordinationV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoordinationV1", reflect.TypeOf((*MockInterface)(nil).CoordinationV1)) +} + +// CoordinationV1alpha1 mocks base method. +func (m *MockInterface) CoordinationV1alpha1() v1alpha13.CoordinationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CoordinationV1alpha1") + ret0, _ := ret[0].(v1alpha13.CoordinationV1alpha1Interface) + return ret0 +} + +// CoordinationV1alpha1 indicates an expected call of CoordinationV1alpha1. +func (mr *MockInterfaceMockRecorder) CoordinationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoordinationV1alpha1", reflect.TypeOf((*MockInterface)(nil).CoordinationV1alpha1)) +} + +// CoordinationV1beta1 mocks base method. +func (m *MockInterface) CoordinationV1beta1() v1beta15.CoordinationV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CoordinationV1beta1") + ret0, _ := ret[0].(v1beta15.CoordinationV1beta1Interface) + return ret0 +} + +// CoordinationV1beta1 indicates an expected call of CoordinationV1beta1. +func (mr *MockInterfaceMockRecorder) CoordinationV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoordinationV1beta1", reflect.TypeOf((*MockInterface)(nil).CoordinationV1beta1)) +} + +// CoreV1 mocks base method. +func (m *MockInterface) CoreV1() v17.CoreV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CoreV1") + ret0, _ := ret[0].(v17.CoreV1Interface) + return ret0 +} + +// CoreV1 indicates an expected call of CoreV1. +func (mr *MockInterfaceMockRecorder) CoreV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoreV1", reflect.TypeOf((*MockInterface)(nil).CoreV1)) +} + +// Discovery mocks base method. +func (m *MockInterface) Discovery() discovery.DiscoveryInterface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Discovery") + ret0, _ := ret[0].(discovery.DiscoveryInterface) + return ret0 +} + +// Discovery indicates an expected call of Discovery. +func (mr *MockInterfaceMockRecorder) Discovery() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discovery", reflect.TypeOf((*MockInterface)(nil).Discovery)) +} + +// DiscoveryV1 mocks base method. +func (m *MockInterface) DiscoveryV1() v18.DiscoveryV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DiscoveryV1") + ret0, _ := ret[0].(v18.DiscoveryV1Interface) + return ret0 +} + +// DiscoveryV1 indicates an expected call of DiscoveryV1. +func (mr *MockInterfaceMockRecorder) DiscoveryV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscoveryV1", reflect.TypeOf((*MockInterface)(nil).DiscoveryV1)) +} + +// DiscoveryV1beta1 mocks base method. +func (m *MockInterface) DiscoveryV1beta1() v1beta16.DiscoveryV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DiscoveryV1beta1") + ret0, _ := ret[0].(v1beta16.DiscoveryV1beta1Interface) + return ret0 +} + +// DiscoveryV1beta1 indicates an expected call of DiscoveryV1beta1. +func (mr *MockInterfaceMockRecorder) DiscoveryV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscoveryV1beta1", reflect.TypeOf((*MockInterface)(nil).DiscoveryV1beta1)) +} + +// EventsV1 mocks base method. +func (m *MockInterface) EventsV1() v19.EventsV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EventsV1") + ret0, _ := ret[0].(v19.EventsV1Interface) + return ret0 +} + +// EventsV1 indicates an expected call of EventsV1. +func (mr *MockInterfaceMockRecorder) EventsV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsV1", reflect.TypeOf((*MockInterface)(nil).EventsV1)) +} + +// EventsV1beta1 mocks base method. +func (m *MockInterface) EventsV1beta1() v1beta17.EventsV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EventsV1beta1") + ret0, _ := ret[0].(v1beta17.EventsV1beta1Interface) + return ret0 +} + +// EventsV1beta1 indicates an expected call of EventsV1beta1. +func (mr *MockInterfaceMockRecorder) EventsV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsV1beta1", reflect.TypeOf((*MockInterface)(nil).EventsV1beta1)) +} + +// ExtensionsV1beta1 mocks base method. +func (m *MockInterface) ExtensionsV1beta1() v1beta18.ExtensionsV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExtensionsV1beta1") + ret0, _ := ret[0].(v1beta18.ExtensionsV1beta1Interface) + return ret0 +} + +// ExtensionsV1beta1 indicates an expected call of ExtensionsV1beta1. +func (mr *MockInterfaceMockRecorder) ExtensionsV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExtensionsV1beta1", reflect.TypeOf((*MockInterface)(nil).ExtensionsV1beta1)) +} + +// FlowcontrolV1 mocks base method. +func (m *MockInterface) FlowcontrolV1() v110.FlowcontrolV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FlowcontrolV1") + ret0, _ := ret[0].(v110.FlowcontrolV1Interface) + return ret0 +} + +// FlowcontrolV1 indicates an expected call of FlowcontrolV1. +func (mr *MockInterfaceMockRecorder) FlowcontrolV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1)) +} + +// FlowcontrolV1beta1 mocks base method. +func (m *MockInterface) FlowcontrolV1beta1() v1beta19.FlowcontrolV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FlowcontrolV1beta1") + ret0, _ := ret[0].(v1beta19.FlowcontrolV1beta1Interface) + return ret0 +} + +// FlowcontrolV1beta1 indicates an expected call of FlowcontrolV1beta1. +func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta1", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta1)) +} + +// FlowcontrolV1beta2 mocks base method. +func (m *MockInterface) FlowcontrolV1beta2() v1beta20.FlowcontrolV1beta2Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FlowcontrolV1beta2") + ret0, _ := ret[0].(v1beta20.FlowcontrolV1beta2Interface) + return ret0 +} + +// FlowcontrolV1beta2 indicates an expected call of FlowcontrolV1beta2. +func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta2() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta2", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta2)) +} + +// FlowcontrolV1beta3 mocks base method. +func (m *MockInterface) FlowcontrolV1beta3() v1beta3.FlowcontrolV1beta3Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FlowcontrolV1beta3") + ret0, _ := ret[0].(v1beta3.FlowcontrolV1beta3Interface) + return ret0 +} + +// FlowcontrolV1beta3 indicates an expected call of FlowcontrolV1beta3. +func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta3() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta3", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta3)) +} + +// InternalV1alpha1 mocks base method. +func (m *MockInterface) InternalV1alpha1() v1alpha10.InternalV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InternalV1alpha1") + ret0, _ := ret[0].(v1alpha10.InternalV1alpha1Interface) + return ret0 +} + +// InternalV1alpha1 indicates an expected call of InternalV1alpha1. +func (mr *MockInterfaceMockRecorder) InternalV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InternalV1alpha1", reflect.TypeOf((*MockInterface)(nil).InternalV1alpha1)) +} + +// NetworkingV1 mocks base method. +func (m *MockInterface) NetworkingV1() v111.NetworkingV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkingV1") + ret0, _ := ret[0].(v111.NetworkingV1Interface) + return ret0 +} + +// NetworkingV1 indicates an expected call of NetworkingV1. +func (mr *MockInterfaceMockRecorder) NetworkingV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1)) +} + +// NetworkingV1alpha1 mocks base method. +func (m *MockInterface) NetworkingV1alpha1() v1alpha14.NetworkingV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkingV1alpha1") + ret0, _ := ret[0].(v1alpha14.NetworkingV1alpha1Interface) + return ret0 +} + +// NetworkingV1alpha1 indicates an expected call of NetworkingV1alpha1. +func (mr *MockInterfaceMockRecorder) NetworkingV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1alpha1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1alpha1)) +} + +// NetworkingV1beta1 mocks base method. +func (m *MockInterface) NetworkingV1beta1() v1beta110.NetworkingV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkingV1beta1") + ret0, _ := ret[0].(v1beta110.NetworkingV1beta1Interface) + return ret0 +} + +// NetworkingV1beta1 indicates an expected call of NetworkingV1beta1. +func (mr *MockInterfaceMockRecorder) NetworkingV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1beta1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1beta1)) +} + +// NodeV1 mocks base method. +func (m *MockInterface) NodeV1() v112.NodeV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeV1") + ret0, _ := ret[0].(v112.NodeV1Interface) + return ret0 +} + +// NodeV1 indicates an expected call of NodeV1. +func (mr *MockInterfaceMockRecorder) NodeV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1", reflect.TypeOf((*MockInterface)(nil).NodeV1)) +} + +// NodeV1alpha1 mocks base method. +func (m *MockInterface) NodeV1alpha1() v1alpha15.NodeV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeV1alpha1") + ret0, _ := ret[0].(v1alpha15.NodeV1alpha1Interface) + return ret0 +} + +// NodeV1alpha1 indicates an expected call of NodeV1alpha1. +func (mr *MockInterfaceMockRecorder) NodeV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1alpha1", reflect.TypeOf((*MockInterface)(nil).NodeV1alpha1)) +} + +// NodeV1beta1 mocks base method. +func (m *MockInterface) NodeV1beta1() v1beta111.NodeV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeV1beta1") + ret0, _ := ret[0].(v1beta111.NodeV1beta1Interface) + return ret0 +} + +// NodeV1beta1 indicates an expected call of NodeV1beta1. +func (mr *MockInterfaceMockRecorder) NodeV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1beta1", reflect.TypeOf((*MockInterface)(nil).NodeV1beta1)) +} + +// PolicyV1 mocks base method. +func (m *MockInterface) PolicyV1() v113.PolicyV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PolicyV1") + ret0, _ := ret[0].(v113.PolicyV1Interface) + return ret0 +} + +// PolicyV1 indicates an expected call of PolicyV1. +func (mr *MockInterfaceMockRecorder) PolicyV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PolicyV1", reflect.TypeOf((*MockInterface)(nil).PolicyV1)) +} + +// PolicyV1beta1 mocks base method. +func (m *MockInterface) PolicyV1beta1() v1beta112.PolicyV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PolicyV1beta1") + ret0, _ := ret[0].(v1beta112.PolicyV1beta1Interface) + return ret0 +} + +// PolicyV1beta1 indicates an expected call of PolicyV1beta1. +func (mr *MockInterfaceMockRecorder) PolicyV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PolicyV1beta1", reflect.TypeOf((*MockInterface)(nil).PolicyV1beta1)) +} + +// RbacV1 mocks base method. +func (m *MockInterface) RbacV1() v114.RbacV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RbacV1") + ret0, _ := ret[0].(v114.RbacV1Interface) + return ret0 +} + +// RbacV1 indicates an expected call of RbacV1. +func (mr *MockInterfaceMockRecorder) RbacV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1", reflect.TypeOf((*MockInterface)(nil).RbacV1)) +} + +// RbacV1alpha1 mocks base method. +func (m *MockInterface) RbacV1alpha1() v1alpha16.RbacV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RbacV1alpha1") + ret0, _ := ret[0].(v1alpha16.RbacV1alpha1Interface) + return ret0 +} + +// RbacV1alpha1 indicates an expected call of RbacV1alpha1. +func (mr *MockInterfaceMockRecorder) RbacV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1alpha1", reflect.TypeOf((*MockInterface)(nil).RbacV1alpha1)) +} + +// RbacV1beta1 mocks base method. +func (m *MockInterface) RbacV1beta1() v1beta113.RbacV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RbacV1beta1") + ret0, _ := ret[0].(v1beta113.RbacV1beta1Interface) + return ret0 +} + +// RbacV1beta1 indicates an expected call of RbacV1beta1. +func (mr *MockInterfaceMockRecorder) RbacV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1beta1", reflect.TypeOf((*MockInterface)(nil).RbacV1beta1)) +} + +// ResourceV1alpha3 mocks base method. +func (m *MockInterface) ResourceV1alpha3() v1alpha3.ResourceV1alpha3Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResourceV1alpha3") + ret0, _ := ret[0].(v1alpha3.ResourceV1alpha3Interface) + return ret0 +} + +// ResourceV1alpha3 indicates an expected call of ResourceV1alpha3. +func (mr *MockInterfaceMockRecorder) ResourceV1alpha3() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResourceV1alpha3", reflect.TypeOf((*MockInterface)(nil).ResourceV1alpha3)) +} + +// SchedulingV1 mocks base method. +func (m *MockInterface) SchedulingV1() v115.SchedulingV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SchedulingV1") + ret0, _ := ret[0].(v115.SchedulingV1Interface) + return ret0 +} + +// SchedulingV1 indicates an expected call of SchedulingV1. +func (mr *MockInterfaceMockRecorder) SchedulingV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1)) +} + +// SchedulingV1alpha1 mocks base method. +func (m *MockInterface) SchedulingV1alpha1() v1alpha17.SchedulingV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SchedulingV1alpha1") + ret0, _ := ret[0].(v1alpha17.SchedulingV1alpha1Interface) + return ret0 +} + +// SchedulingV1alpha1 indicates an expected call of SchedulingV1alpha1. +func (mr *MockInterfaceMockRecorder) SchedulingV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1alpha1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1alpha1)) +} + +// SchedulingV1beta1 mocks base method. +func (m *MockInterface) SchedulingV1beta1() v1beta114.SchedulingV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SchedulingV1beta1") + ret0, _ := ret[0].(v1beta114.SchedulingV1beta1Interface) + return ret0 +} + +// SchedulingV1beta1 indicates an expected call of SchedulingV1beta1. +func (mr *MockInterfaceMockRecorder) SchedulingV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1beta1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1beta1)) +} + +// StorageV1 mocks base method. +func (m *MockInterface) StorageV1() v116.StorageV1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageV1") + ret0, _ := ret[0].(v116.StorageV1Interface) + return ret0 +} + +// StorageV1 indicates an expected call of StorageV1. +func (mr *MockInterfaceMockRecorder) StorageV1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1", reflect.TypeOf((*MockInterface)(nil).StorageV1)) +} + +// StorageV1alpha1 mocks base method. +func (m *MockInterface) StorageV1alpha1() v1alpha18.StorageV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageV1alpha1") + ret0, _ := ret[0].(v1alpha18.StorageV1alpha1Interface) + return ret0 +} + +// StorageV1alpha1 indicates an expected call of StorageV1alpha1. +func (mr *MockInterfaceMockRecorder) StorageV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1alpha1", reflect.TypeOf((*MockInterface)(nil).StorageV1alpha1)) +} + +// StorageV1beta1 mocks base method. +func (m *MockInterface) StorageV1beta1() v1beta115.StorageV1beta1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageV1beta1") + ret0, _ := ret[0].(v1beta115.StorageV1beta1Interface) + return ret0 +} + +// StorageV1beta1 indicates an expected call of StorageV1beta1. +func (mr *MockInterfaceMockRecorder) StorageV1beta1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1beta1", reflect.TypeOf((*MockInterface)(nil).StorageV1beta1)) +} + +// StoragemigrationV1alpha1 mocks base method. +func (m *MockInterface) StoragemigrationV1alpha1() v1alpha19.StoragemigrationV1alpha1Interface { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StoragemigrationV1alpha1") + ret0, _ := ret[0].(v1alpha19.StoragemigrationV1alpha1Interface) + return ret0 +} + +// StoragemigrationV1alpha1 indicates an expected call of StoragemigrationV1alpha1. +func (mr *MockInterfaceMockRecorder) StoragemigrationV1alpha1() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StoragemigrationV1alpha1", reflect.TypeOf((*MockInterface)(nil).StoragemigrationV1alpha1)) +} diff --git a/actions/patch_handler.go b/internal/actions/patch_handler.go similarity index 84% rename from actions/patch_handler.go rename to internal/actions/patch_handler.go index d3e5e34b..e488f4c3 100644 --- a/actions/patch_handler.go +++ b/internal/actions/patch_handler.go @@ -13,22 +13,24 @@ import ( apitypes "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/dynamic" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) -type patchHandler struct { +var _ ActionHandler = &PatchHandler{} + +type PatchHandler struct { log logrus.FieldLogger client dynamic.Interface } -func newPatchHandler(log logrus.FieldLogger, client dynamic.Interface) ActionHandler { - return &patchHandler{ +func NewPatchHandler(log logrus.FieldLogger, client dynamic.Interface) *PatchHandler { + return &PatchHandler{ log: log, client: client, } } -func (h *patchHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *PatchHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionPatch) if !ok { return newUnexpectedTypeErr(action.Data(), req) @@ -40,7 +42,7 @@ func (h *patchHandler) Handle(ctx context.Context, action *castai.ClusterAction) } log := h.log.WithFields(logrus.Fields{ - actionIDLogField: action.ID, + ActionIDLogField: action.ID, "action": reflect.TypeOf(action.Data()).String(), "gvr": req.ID.GroupVersionResource.String(), "name": req.ID.Name, diff --git a/actions/patch_handler_test.go b/internal/actions/patch_handler_test.go similarity index 97% rename from actions/patch_handler_test.go rename to internal/actions/patch_handler_test.go index 341e73a8..a0a8d1b9 100644 --- a/actions/patch_handler_test.go +++ b/internal/actions/patch_handler_test.go @@ -15,7 +15,7 @@ import ( "k8s.io/client-go/dynamic/fake" client_testing "k8s.io/client-go/testing" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestPatchHandler(t *testing.T) { @@ -81,7 +81,7 @@ func TestPatchHandler(t *testing.T) { r.NoError(appsv1.AddToScheme(scheme)) r.NoError(metav1.AddMetaToScheme(scheme)) client := fake.NewSimpleDynamicClient(scheme, test.objs...) - handler := newPatchHandler(log, client) + handler := NewPatchHandler(log, client) err := handler.Handle(ctx, test.action) if test.err != nil { r.Error(err) diff --git a/actions/patch_node_handler.go b/internal/actions/patch_node_handler.go similarity index 89% rename from actions/patch_node_handler.go rename to internal/actions/patch_node_handler.go index 9ef7c4ca..7e840bef 100644 --- a/actions/patch_node_handler.go +++ b/internal/actions/patch_node_handler.go @@ -13,22 +13,24 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) -func newPatchNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface) ActionHandler { - return &patchNodeHandler{ +var _ ActionHandler = &PatchNodeHandler{} + +func NewPatchNodeHandler(log logrus.FieldLogger, clientset kubernetes.Interface) *PatchNodeHandler { + return &PatchNodeHandler{ log: log, clientset: clientset, } } -type patchNodeHandler struct { +type PatchNodeHandler struct { log logrus.FieldLogger clientset kubernetes.Interface } -func (h *patchNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { +func (h *PatchNodeHandler) Handle(ctx context.Context, action *castai.ClusterAction) error { req, ok := action.Data().(*castai.ActionPatchNode) if !ok { return fmt.Errorf("unexpected type %T for delete patch handler", action.Data()) @@ -53,7 +55,7 @@ func (h *patchNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct "node_name": req.NodeName, "node_id": req.NodeID, "action": reflect.TypeOf(action.Data().(*castai.ActionPatchNode)).String(), - actionIDLogField: action.ID, + ActionIDLogField: action.ID, }) node, err := getNodeForPatching(ctx, h.log, h.clientset, req.NodeName) @@ -106,7 +108,7 @@ func (h *patchNodeHandler) Handle(ctx context.Context, action *castai.ClusterAct return nil } -func patchNodeMapField(values map[string]string, patch map[string]string) map[string]string { +func patchNodeMapField(values, patch map[string]string) map[string]string { if values == nil { values = map[string]string{} } diff --git a/actions/patch_node_handler_test.go b/internal/actions/patch_node_handler_test.go similarity index 96% rename from actions/patch_node_handler_test.go rename to internal/actions/patch_node_handler_test.go index 59b9cfd8..0c4d2a26 100644 --- a/actions/patch_node_handler_test.go +++ b/internal/actions/patch_node_handler_test.go @@ -13,7 +13,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestPatchNodeHandler(t *testing.T) { @@ -51,7 +51,7 @@ func TestPatchNodeHandler(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := patchNodeHandler{ + h := PatchNodeHandler{ log: log, clientset: clientset, } @@ -126,7 +126,7 @@ func TestPatchNodeHandler(t *testing.T) { NodeName: "already-deleted-node", }, } - h := patchNodeHandler{ + h := PatchNodeHandler{ log: log, clientset: clientset, } @@ -150,7 +150,7 @@ func TestPatchNodeHandler(t *testing.T) { } clientset := fake.NewSimpleClientset(node) - h := patchNodeHandler{ + h := PatchNodeHandler{ log: log, clientset: clientset, } diff --git a/actions/send_aks_init_data_handler.go b/internal/actions/send_aks_init_data_handler.go similarity index 77% rename from actions/send_aks_init_data_handler.go rename to internal/actions/send_aks_init_data_handler.go index 8e2bd83e..ba81e447 100644 --- a/actions/send_aks_init_data_handler.go +++ b/internal/actions/send_aks_init_data_handler.go @@ -18,11 +18,13 @@ import ( "github.com/sirupsen/logrus" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) -func newSendAKSInitDataHandler(log logrus.FieldLogger, client castai.ActionsClient) ActionHandler { - return &sendAKSInitDataHandler{ +var _ ActionHandler = &SendAKSInitDataHandler{} + +func NewSendAKSInitDataHandler(log logrus.FieldLogger, client castai.CastAIClient) *SendAKSInitDataHandler { + return &SendAKSInitDataHandler{ log: log, client: client, @@ -31,15 +33,15 @@ func newSendAKSInitDataHandler(log logrus.FieldLogger, client castai.ActionsClie } } -type sendAKSInitDataHandler struct { +type SendAKSInitDataHandler struct { log logrus.FieldLogger - client castai.ActionsClient + client castai.CastAIClient baseDir string cloudConfigPath string } -func (s *sendAKSInitDataHandler) Handle(ctx context.Context, _ *castai.ClusterAction) error { +func (s *SendAKSInitDataHandler) Handle(ctx context.Context, _ *castai.ClusterAction) error { cloudConfig, err := s.readCloudConfigBase64(s.cloudConfigPath) if err != nil { return fmt.Errorf("reading cloud config: %w", err) @@ -62,16 +64,14 @@ func (s *sendAKSInitDataHandler) Handle(ctx context.Context, _ *castai.ClusterAc }) } +var customDataRegex = regexp.MustCompile(`(.*?)<\/ns1:CustomData>`) + // readCloudConfigBase64 extracts base64 encoded cloud config content from XML file. -func (s *sendAKSInitDataHandler) readCloudConfigBase64(cloudConfigPath string) ([]byte, error) { +func (s *SendAKSInitDataHandler) readCloudConfigBase64(cloudConfigPath string) ([]byte, error) { xmlContent, err := os.ReadFile(cloudConfigPath) if err != nil { return nil, err } - customDataRegex, err := regexp.Compile(`(.*?)<\/ns1:CustomData>`) - if err != nil { - return nil, err - } matches := customDataRegex.FindSubmatch(xmlContent) if len(matches) < 2 { return nil, errors.New("no custom data xml tag found") @@ -80,7 +80,7 @@ func (s *sendAKSInitDataHandler) readCloudConfigBase64(cloudConfigPath string) ( } // findSettingsPath searches for custom script settings file path which contains encrypted init data env variables. -func (s *sendAKSInitDataHandler) findSettingsPath(baseDir string) (string, error) { +func (s *SendAKSInitDataHandler) findSettingsPath(baseDir string) (string, error) { var res string err := filepath.WalkDir(baseDir, func(path string, d fs.DirEntry, err error) error { if strings.Contains(path, "Microsoft.Azure.Extensions.CustomScript-") && strings.HasSuffix(path, "settings") { @@ -89,7 +89,7 @@ func (s *sendAKSInitDataHandler) findSettingsPath(baseDir string) (string, error } return err }) - if err != nil && err != io.EOF { + if !errors.Is(err, io.EOF) { return "", err } if res == "" { @@ -98,7 +98,7 @@ func (s *sendAKSInitDataHandler) findSettingsPath(baseDir string) (string, error return res, nil } -func (s *sendAKSInitDataHandler) readSettings(settingsFilePath string) (*settings, error) { +func (s *SendAKSInitDataHandler) readSettings(settingsFilePath string) (*settings, error) { var res settings settingsContent, err := os.ReadFile(settingsFilePath) if err != nil { @@ -110,7 +110,7 @@ func (s *sendAKSInitDataHandler) readSettings(settingsFilePath string) (*setting return &res, nil } -func (s *sendAKSInitDataHandler) decryptProtectedSettings(settings *settings) ([]byte, error) { +func (s *SendAKSInitDataHandler) decryptProtectedSettings(settings *settings) ([]byte, error) { protectedsettings := settings.Runtimesettings[0].Handlersettings.Protectedsettings protectedSettingsBytes, err := base64.StdEncoding.DecodeString(protectedsettings) if err != nil { @@ -143,10 +143,9 @@ func (s *sendAKSInitDataHandler) decryptProtectedSettings(settings *settings) ([ type settings struct { Runtimesettings []struct { Handlersettings struct { - Publicsettings struct { - } `json:"publicSettings"` - Protectedsettings string `json:"protectedSettings"` - Protectedsettingscertthumbprint string `json:"protectedSettingsCertThumbprint"` + Publicsettings struct{} `json:"publicSettings"` + Protectedsettings string `json:"protectedSettings"` + Protectedsettingscertthumbprint string `json:"protectedSettingsCertThumbprint"` } `json:"handlerSettings"` } `json:"runtimeSettings"` } diff --git a/actions/send_aks_init_data_handler_test.go b/internal/actions/send_aks_init_data_handler_test.go similarity index 51% rename from actions/send_aks_init_data_handler_test.go rename to internal/actions/send_aks_init_data_handler_test.go index d2512474..dd28dcc3 100644 --- a/actions/send_aks_init_data_handler_test.go +++ b/internal/actions/send_aks_init_data_handler_test.go @@ -2,23 +2,30 @@ package actions import ( "context" - "github.com/google/uuid" "testing" + "github.com/golang/mock/gomock" + "github.com/google/uuid" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/castai/mock" + "github.com/castai/cluster-controller/internal/castai" + mock_castai "github.com/castai/cluster-controller/internal/castai/mock" ) func TestAKSInitDataHandler(t *testing.T) { - r := require.New(t) log := logrus.New() log.SetLevel(logrus.DebugLevel) - client := mock.NewMockAPIClient(nil) - h := sendAKSInitDataHandler{ + m := gomock.NewController(t) + client := mock_castai.NewMockCastAIClient(m) + client.EXPECT().SendAKSInitData(gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, req *castai.AKSInitDataRequest) error { + require.NotEmpty(t, req.CloudConfigBase64) + require.NotEmpty(t, req.ProtectedSettingsBase64) + return nil + }) + h := SendAKSInitDataHandler{ log: log, client: client, cloudConfigPath: "../testdata/aks/ovf-env.xml", @@ -31,8 +38,5 @@ func TestAKSInitDataHandler(t *testing.T) { } ctx := context.Background() err := h.Handle(ctx, action) - - r.NoError(err) - r.NotEmpty(client.AKSInitDataReq.CloudConfigBase64) - r.NotEmpty(client.AKSInitDataReq.ProtectedSettingsBase64) + require.NoError(t, err) } diff --git a/internal/actions/types.go b/internal/actions/types.go new file mode 100644 index 00000000..3e21a6be --- /dev/null +++ b/internal/actions/types.go @@ -0,0 +1,23 @@ +//go:generate mockgen -destination ./mock/handler.go . ActionHandler +package actions + +import ( + "context" + "fmt" + + "github.com/castai/cluster-controller/internal/castai" +) + +const ( + // ActionIDLogField is the log field name for action ID. + // This field is used in backend to detect actions ID in logs. + ActionIDLogField = "id" +) + +func newUnexpectedTypeErr(value, expectedType interface{}) error { + return fmt.Errorf("unexpected type %T, expected %T", value, expectedType) +} + +type ActionHandler interface { + Handle(ctx context.Context, action *castai.ClusterAction) error +} diff --git a/castai/client.go b/internal/castai/client.go similarity index 88% rename from castai/client.go rename to internal/castai/client.go index c8bee84e..5152723f 100644 --- a/castai/client.go +++ b/internal/castai/client.go @@ -1,3 +1,4 @@ +//go:generate mockgen -destination ./mock/client.go . CastAIClient package castai import ( @@ -13,18 +14,18 @@ import ( "github.com/sirupsen/logrus" "golang.org/x/net/http2" - "github.com/castai/cluster-controller/config" + "github.com/castai/cluster-controller/internal/config" + "github.com/castai/cluster-controller/internal/logexporter" ) const ( - headerAPIKey = "X-API-Key" + headerAPIKey = "X-API-Key" //nolint: gosec headerUserAgent = "User-Agent" headerKubernetesVersion = "X-K8s-Version" ) -// ActionsClient lists functions used by actions package. -// TODO: move interface into actions package. -type ActionsClient interface { +// CastAIClient lists functions used by actions package. +type CastAIClient interface { GetActions(ctx context.Context, k8sVersion string) ([]*ClusterAction, error) AckAction(ctx context.Context, actionID string, req *AckClusterActionRequest) error SendAKSInitData(ctx context.Context, req *AKSInitDataRequest) error @@ -59,7 +60,7 @@ func NewRestyClient(url, key, ca string, level logrus.Level, binVersion *config. Transport: clientTransport, }) - client.SetHostURL(url) + client.SetBaseURL(url) client.Header.Set(headerAPIKey, key) client.Header.Set(headerUserAgent, "castai-cluster-controller/"+binVersion.Version) if level == logrus.TraceLevel { @@ -72,7 +73,7 @@ func NewRestyClient(url, key, ca string, level logrus.Level, binVersion *config. func createHTTPTransport(ca string) (*http.Transport, error) { tlsConfig, err := createTLSConfig(ca) if err != nil { - return nil, fmt.Errorf("creating TLS config: %v", err) + return nil, fmt.Errorf("creating TLS config: %w", err) } t1 := &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -113,7 +114,8 @@ func createTLSConfig(ca string) (*tls.Config, error) { } return &tls.Config{ - RootCAs: certPool, + RootCAs: certPool, + MinVersion: tls.VersionTLS12, }, nil } @@ -122,7 +124,6 @@ func (c *Client) SendAKSInitData(ctx context.Context, req *AKSInitDataRequest) e SetBody(req). SetContext(ctx). Post(fmt.Sprintf("/v1/kubernetes/external-clusters/%s/aks-init-data", c.clusterID)) - if err != nil { return fmt.Errorf("sending aks init data: %w", err) } @@ -133,7 +134,7 @@ func (c *Client) SendAKSInitData(ctx context.Context, req *AKSInitDataRequest) e return nil } -func (c *Client) SendLog(ctx context.Context, e *logEntry) error { +func (c *Client) SendLog(ctx context.Context, e *logexporter.LogEntry) error { // Server expects fields values to be strings. If they're not it fails with BAD_REQUEST/400. // Alternatively we could use "google/protobuf/any.proto" on server side but ATM it doesn't work. for k, v := range e.Fields { @@ -148,7 +149,6 @@ func (c *Client) SendLog(ctx context.Context, e *logEntry) error { SetBody(e). SetContext(ctx). Post(fmt.Sprintf("/v1/kubernetes/clusters/%s/actions/logs", c.clusterID)) - if err != nil { return fmt.Errorf("sending logs: %w", err) } @@ -170,7 +170,7 @@ func (c *Client) GetActions(ctx context.Context, k8sVersion string) ([]*ClusterA return nil, fmt.Errorf("failed to request cluster-actions: %w", err) } if resp.IsError() { - return nil, fmt.Errorf("get cluster-actions: request error host=%s, status_code=%d body=%s", c.rest.HostURL, resp.StatusCode(), resp.Body()) + return nil, fmt.Errorf("get cluster-actions: request error host=%s, status_code=%d body=%s", c.rest.BaseURL, resp.StatusCode(), resp.Body()) } return res.Items, nil } @@ -181,7 +181,7 @@ func (c *Client) AckAction(ctx context.Context, actionID string, req *AckCluster SetBody(req). Post(fmt.Sprintf("/v1/kubernetes/clusters/%s/actions/%s/ack", c.clusterID, actionID)) if err != nil { - return fmt.Errorf("failed to request cluster-actions ack: %v", err) + return fmt.Errorf("failed to request cluster-actions ack: %w", err) } if resp.IsError() { return fmt.Errorf("ack cluster-actions: request error status_code=%d body=%s", resp.StatusCode(), resp.Body()) diff --git a/castai/client_test.go b/internal/castai/client_test.go similarity index 100% rename from castai/client_test.go rename to internal/castai/client_test.go diff --git a/internal/castai/mock/client.go b/internal/castai/mock/client.go new file mode 100644 index 00000000..266b7eed --- /dev/null +++ b/internal/castai/mock/client.go @@ -0,0 +1,79 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/castai/cluster-controller/internal/castai (interfaces: CastAIClient) + +// Package mock_castai is a generated GoMock package. +package mock_castai + +import ( + context "context" + reflect "reflect" + + castai "github.com/castai/cluster-controller/internal/castai" + gomock "github.com/golang/mock/gomock" +) + +// MockCastAIClient is a mock of CastAIClient interface. +type MockCastAIClient struct { + ctrl *gomock.Controller + recorder *MockCastAIClientMockRecorder +} + +// MockCastAIClientMockRecorder is the mock recorder for MockCastAIClient. +type MockCastAIClientMockRecorder struct { + mock *MockCastAIClient +} + +// NewMockCastAIClient creates a new mock instance. +func NewMockCastAIClient(ctrl *gomock.Controller) *MockCastAIClient { + mock := &MockCastAIClient{ctrl: ctrl} + mock.recorder = &MockCastAIClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCastAIClient) EXPECT() *MockCastAIClientMockRecorder { + return m.recorder +} + +// AckAction mocks base method. +func (m *MockCastAIClient) AckAction(arg0 context.Context, arg1 string, arg2 *castai.AckClusterActionRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AckAction", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// AckAction indicates an expected call of AckAction. +func (mr *MockCastAIClientMockRecorder) AckAction(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AckAction", reflect.TypeOf((*MockCastAIClient)(nil).AckAction), arg0, arg1, arg2) +} + +// GetActions mocks base method. +func (m *MockCastAIClient) GetActions(arg0 context.Context, arg1 string) ([]*castai.ClusterAction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetActions", arg0, arg1) + ret0, _ := ret[0].([]*castai.ClusterAction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetActions indicates an expected call of GetActions. +func (mr *MockCastAIClientMockRecorder) GetActions(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActions", reflect.TypeOf((*MockCastAIClient)(nil).GetActions), arg0, arg1) +} + +// SendAKSInitData mocks base method. +func (m *MockCastAIClient) SendAKSInitData(arg0 context.Context, arg1 *castai.AKSInitDataRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendAKSInitData", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendAKSInitData indicates an expected call of SendAKSInitData. +func (mr *MockCastAIClientMockRecorder) SendAKSInitData(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAKSInitData", reflect.TypeOf((*MockCastAIClient)(nil).SendAKSInitData), arg0, arg1) +} diff --git a/castai/types.go b/internal/castai/types.go similarity index 98% rename from castai/types.go rename to internal/castai/types.go index 2179673e..08ae5d82 100644 --- a/castai/types.go +++ b/internal/castai/types.go @@ -178,11 +178,9 @@ type ActionCreateEvent struct { Message string `json:"message"` } -type ActionDisconnectCluster struct { -} +type ActionDisconnectCluster struct{} -type ActionSendAKSInitData struct { -} +type ActionSendAKSInitData struct{} type ActionCheckNodeDeleted struct { NodeName string `json:"nodeName"` diff --git a/config/config.go b/internal/config/config.go similarity index 96% rename from config/config.go rename to internal/config/config.go index 155fe01c..a2448040 100644 --- a/config/config.go +++ b/internal/config/config.go @@ -23,7 +23,7 @@ type Config struct { } type Log struct { - Level int + Level uint32 } type API struct { @@ -80,11 +80,11 @@ func Get() Config { cfg = &Config{} if err := viper.Unmarshal(&cfg); err != nil { - panic(fmt.Errorf("parsing configuration: %v", err)) + panic(fmt.Errorf("parsing configuration: %w", err)) } if cfg.Log.Level == 0 { - cfg.Log.Level = int(logrus.InfoLevel) + cfg.Log.Level = uint32(logrus.InfoLevel) } if cfg.PprofPort == 0 { cfg.PprofPort = 6060 diff --git a/config/config_test.go b/internal/config/config_test.go similarity index 97% rename from config/config_test.go rename to internal/config/config_test.go index fc5cb079..f72ad69c 100644 --- a/config/config_test.go +++ b/internal/config/config_test.go @@ -24,7 +24,7 @@ func TestConfig(t *testing.T) { expected := Config{ Log: Log{ - Level: int(logrus.InfoLevel), + Level: uint32(logrus.InfoLevel), }, PprofPort: 6060, API: API{ diff --git a/config/version.go b/internal/config/version.go similarity index 100% rename from config/version.go rename to internal/config/version.go diff --git a/actions/actions.go b/internal/controller/controller.go similarity index 60% rename from actions/actions.go rename to internal/controller/controller.go index 1af65195..170490f6 100644 --- a/actions/actions.go +++ b/internal/controller/controller.go @@ -1,4 +1,4 @@ -package actions +package controller import ( "context" @@ -14,22 +14,13 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" - "github.com/castai/cluster-controller/castai" "github.com/castai/cluster-controller/health" - "github.com/castai/cluster-controller/helm" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/actions" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm" + "github.com/castai/cluster-controller/internal/waitext" ) -const ( - // actionIDLogField is the log field name for action ID. - // This field is used in backend to detect actions ID in logs. - actionIDLogField = "id" -) - -func newUnexpectedTypeErr(value interface{}, expectedType interface{}) error { - return fmt.Errorf("unexpected type %T, expected %T", value, expectedType) -} - type Config struct { PollWaitInterval time.Duration // How long to wait unit next long polling request. PollTimeout time.Duration // hard timeout. Normally server should return empty result before this timeout. @@ -41,59 +32,51 @@ type Config struct { Namespace string } -type Service interface { - Run(ctx context.Context) -} - -type ActionHandler interface { - Handle(ctx context.Context, action *castai.ClusterAction) error -} - func NewService( log logrus.FieldLogger, cfg Config, k8sVersion string, clientset *kubernetes.Clientset, dynamicClient dynamic.Interface, - castaiClient castai.ActionsClient, + castaiClient castai.CastAIClient, helmClient helm.Client, healthCheck *health.HealthzProvider, -) Service { - return &service{ +) *Controller { + return &Controller{ log: log, cfg: cfg, k8sVersion: k8sVersion, castAIClient: castaiClient, startedActions: map[string]struct{}{}, - actionHandlers: map[reflect.Type]ActionHandler{ - reflect.TypeOf(&castai.ActionDeleteNode{}): newDeleteNodeHandler(log, clientset), - reflect.TypeOf(&castai.ActionDrainNode{}): newDrainNodeHandler(log, clientset, cfg.Namespace), - reflect.TypeOf(&castai.ActionPatchNode{}): newPatchNodeHandler(log, clientset), - reflect.TypeOf(&castai.ActionCreateEvent{}): newCreateEventHandler(log, clientset), - reflect.TypeOf(&castai.ActionApproveCSR{}): newApproveCSRHandler(log, clientset), - reflect.TypeOf(&castai.ActionChartUpsert{}): newChartUpsertHandler(log, helmClient), - reflect.TypeOf(&castai.ActionChartUninstall{}): newChartUninstallHandler(log, helmClient), - reflect.TypeOf(&castai.ActionChartRollback{}): newChartRollbackHandler(log, helmClient, cfg.Version), - reflect.TypeOf(&castai.ActionDisconnectCluster{}): newDisconnectClusterHandler(log, clientset), - reflect.TypeOf(&castai.ActionSendAKSInitData{}): newSendAKSInitDataHandler(log, castaiClient), - reflect.TypeOf(&castai.ActionCheckNodeDeleted{}): newCheckNodeDeletedHandler(log, clientset), - reflect.TypeOf(&castai.ActionCheckNodeStatus{}): newCheckNodeStatusHandler(log, clientset), - reflect.TypeOf(&castai.ActionPatch{}): newPatchHandler(log, dynamicClient), - reflect.TypeOf(&castai.ActionCreate{}): newCreateHandler(log, dynamicClient), - reflect.TypeOf(&castai.ActionDelete{}): newDeleteHandler(log, dynamicClient), + actionHandlers: map[reflect.Type]actions.ActionHandler{ + reflect.TypeOf(&castai.ActionDeleteNode{}): actions.NewDeleteNodeHandler(log, clientset), + reflect.TypeOf(&castai.ActionDrainNode{}): actions.NewDrainNodeHandler(log, clientset, cfg.Namespace), + reflect.TypeOf(&castai.ActionPatchNode{}): actions.NewPatchNodeHandler(log, clientset), + reflect.TypeOf(&castai.ActionCreateEvent{}): actions.NewCreateEventHandler(log, clientset), + reflect.TypeOf(&castai.ActionApproveCSR{}): actions.NewApproveCSRHandler(log, clientset), + reflect.TypeOf(&castai.ActionChartUpsert{}): actions.NewChartUpsertHandler(log, helmClient), + reflect.TypeOf(&castai.ActionChartUninstall{}): actions.NewChartUninstallHandler(log, helmClient), + reflect.TypeOf(&castai.ActionChartRollback{}): actions.NewChartRollbackHandler(log, helmClient, cfg.Version), + reflect.TypeOf(&castai.ActionDisconnectCluster{}): actions.NewDisconnectClusterHandler(log, clientset), + reflect.TypeOf(&castai.ActionSendAKSInitData{}): actions.NewSendAKSInitDataHandler(log, castaiClient), + reflect.TypeOf(&castai.ActionCheckNodeDeleted{}): actions.NewCheckNodeDeletedHandler(log, clientset), + reflect.TypeOf(&castai.ActionCheckNodeStatus{}): actions.NewCheckNodeStatusHandler(log, clientset), + reflect.TypeOf(&castai.ActionPatch{}): actions.NewPatchHandler(log, dynamicClient), + reflect.TypeOf(&castai.ActionCreate{}): actions.NewCreateHandler(log, dynamicClient), + reflect.TypeOf(&castai.ActionDelete{}): actions.NewDeleteHandler(log, dynamicClient), }, healthCheck: healthCheck, } } -type service struct { +type Controller struct { log logrus.FieldLogger cfg Config - castAIClient castai.ActionsClient + castAIClient castai.CastAIClient k8sVersion string - actionHandlers map[reflect.Type]ActionHandler + actionHandlers map[reflect.Type]actions.ActionHandler startedActionsWg sync.WaitGroup startedActions map[string]struct{} @@ -101,7 +84,7 @@ type service struct { healthCheck *health.HealthzProvider } -func (s *service) Run(ctx context.Context) { +func (s *Controller) Run(ctx context.Context) { s.healthCheck.Initializing() for { select { @@ -123,7 +106,7 @@ func (s *service) Run(ctx context.Context) { } } -func (s *service) doWork(ctx context.Context) error { +func (s *Controller) doWork(ctx context.Context) error { s.log.Info("polling actions") start := time.Now() var ( @@ -161,8 +144,8 @@ func (s *service) doWork(ctx context.Context) error { return nil } -func (s *service) handleActions(ctx context.Context, actions []*castai.ClusterAction) { - for _, action := range actions { +func (s *Controller) handleActions(ctx context.Context, clusterActions []*castai.ClusterAction) { + for _, action := range clusterActions { if !s.startProcessing(action.ID) { continue } @@ -181,19 +164,19 @@ func (s *service) handleActions(ctx context.Context, actions []*castai.ClusterAc err = handleErr } if ackErr != nil { - err = fmt.Errorf("%v:%w", err, ackErr) + err = fmt.Errorf("%v:%w", err, ackErr) // nolint:errorlint } if err != nil { s.log.WithFields(logrus.Fields{ - actionIDLogField: action.ID, - "error": err.Error(), + actions.ActionIDLogField: action.ID, + "error": err.Error(), }).Error("handle actions") } }(action) } } -func (s *service) finishProcessing(actionID string) { +func (s *Controller) finishProcessing(actionID string) { s.startedActionsMu.Lock() defer s.startedActionsMu.Unlock() @@ -201,7 +184,7 @@ func (s *service) finishProcessing(actionID string) { delete(s.startedActions, actionID) } -func (s *service) startProcessing(actionID string) bool { +func (s *Controller) startProcessing(actionID string) bool { s.startedActionsMu.Lock() defer s.startedActionsMu.Unlock() @@ -214,7 +197,7 @@ func (s *service) startProcessing(actionID string) bool { return true } -func (s *service) handleAction(ctx context.Context, action *castai.ClusterAction) (err error) { +func (s *Controller) handleAction(ctx context.Context, action *castai.ClusterAction) (err error) { actionType := reflect.TypeOf(action.Data()) defer func() { @@ -224,8 +207,8 @@ func (s *service) handleAction(ctx context.Context, action *castai.ClusterAction }() s.log.WithFields(logrus.Fields{ - actionIDLogField: action.ID, - "type": actionType.String(), + actions.ActionIDLogField: action.ID, + "type": actionType.String(), }).Info("handle action") handler, ok := s.actionHandlers[actionType] if !ok { @@ -238,11 +221,11 @@ func (s *service) handleAction(ctx context.Context, action *castai.ClusterAction return nil } -func (s *service) ackAction(ctx context.Context, action *castai.ClusterAction, handleErr error) error { +func (s *Controller) ackAction(ctx context.Context, action *castai.ClusterAction, handleErr error) error { actionType := reflect.TypeOf(action.Data()) s.log.WithFields(logrus.Fields{ - actionIDLogField: action.ID, - "type": actionType.String(), + actions.ActionIDLogField: action.ID, + "type": actionType.String(), }).Info("ack action") boff := waitext.NewConstantBackoff(s.cfg.AckRetryWait) @@ -265,3 +248,7 @@ func getHandlerError(err error) *string { } return nil } + +func (s *Controller) Close() error { + return s.actionHandlers[reflect.TypeOf(&castai.ActionCreateEvent{})].(*actions.CreateEventHandler).Close() +} diff --git a/internal/controller/controller_test.go b/internal/controller/controller_test.go new file mode 100644 index 00000000..ba555642 --- /dev/null +++ b/internal/controller/controller_test.go @@ -0,0 +1,236 @@ +package controller + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "go.uber.org/goleak" + "k8s.io/client-go/kubernetes" + + "github.com/castai/cluster-controller/health" + mock_actions "github.com/castai/cluster-controller/internal/actions/mock" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/castai/mock" +) + +// nolint: govet +func TestController_Run(t *testing.T) { + t.Parallel() + pollTimeout := 100 * time.Millisecond + cfg := Config{ + PollWaitInterval: 10 * time.Millisecond, + PollTimeout: pollTimeout, + AckTimeout: 1 * time.Second, + AckRetriesCount: 3, + AckRetryWait: 1 * time.Millisecond, + ClusterID: uuid.New().String(), + } + type fields struct { + cfg Config + tuneMockCastAIClient func(m *mock_castai.MockCastAIClient) + tuneMockHandler func(m *mock_actions.MockActionHandler) + k8sVersion string + } + type args struct { + ctx func() context.Context + } + tests := []struct { + name string + fields fields + args args + }{ + { + name: "no actions", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second) + return ctx + }, + }, + fields: fields{ + cfg: cfg, + tuneMockCastAIClient: func(m *mock_castai.MockCastAIClient) { + m.EXPECT().GetActions(gomock.Any(), gomock.Any()).Return(nil, nil).MinTimes(1) + }, + }, + }, + { + name: "poll handle and ack", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second) + return ctx + }, + }, + fields: fields{ + cfg: cfg, + k8sVersion: "1.20.1", + tuneMockHandler: func(m *mock_actions.MockActionHandler) { + m.EXPECT().Handle(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + }, + tuneMockCastAIClient: func(m *mock_castai.MockCastAIClient) { + m.EXPECT().GetActions(gomock.Any(), gomock.Any()).Return([]*castai.ClusterAction{ + { + ID: "a1", + CreatedAt: time.Now(), + ActionDeleteNode: &castai.ActionDeleteNode{ + NodeName: "n1", + }, + }, + { + ID: "a2", + CreatedAt: time.Now(), + ActionDrainNode: &castai.ActionDrainNode{ + NodeName: "n1", + }, + }, + { + ID: "a3", + CreatedAt: time.Now(), + ActionPatchNode: &castai.ActionPatchNode{ + NodeName: "n1", + }, + }, + }, nil).Times(1).MinTimes(1) + m.EXPECT().AckAction(gomock.Any(), "a1", gomock.Any()).Return(nil).MinTimes(1) + m.EXPECT().AckAction(gomock.Any(), "a2", gomock.Any()).Return(nil).MinTimes(1) + m.EXPECT().AckAction(gomock.Any(), "a3", gomock.Any()).Return(nil).MinTimes(1) + }, + }, + }, + { + name: "handle action error", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second) + return ctx + }, + }, + fields: fields{ + cfg: cfg, + k8sVersion: "1.20.1", + tuneMockHandler: func(m *mock_actions.MockActionHandler) { + m.EXPECT().Handle(gomock.Any(), gomock.Any()).Return(fmt.Errorf("test handle action error")).MinTimes(1) + }, + tuneMockCastAIClient: func(m *mock_castai.MockCastAIClient) { + m.EXPECT().GetActions(gomock.Any(), gomock.Any()).Return([]*castai.ClusterAction{ + { + ID: "a1", + CreatedAt: time.Now(), + ActionDeleteNode: &castai.ActionDeleteNode{ + NodeName: "n1", + }, + }, + }, nil).Times(1).MinTimes(1) + m.EXPECT().AckAction(gomock.Any(), "a1", gomock.Any()). + DoAndReturn(func(ctx context.Context, actionID string, req *castai.AckClusterActionRequest) error { + require.NotNil(t, req.Error) + return nil + }).MinTimes(1) + }, + }, + }, + { + name: "handle action: context canceled error", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second) + return ctx + }, + }, + fields: fields{ + cfg: cfg, + k8sVersion: "1.20.1", + tuneMockHandler: func(m *mock_actions.MockActionHandler) { + m.EXPECT().Handle(gomock.Any(), gomock.Any()).Return(context.Canceled).MinTimes(1) + }, + tuneMockCastAIClient: func(m *mock_castai.MockCastAIClient) { + m.EXPECT().GetActions(gomock.Any(), gomock.Any()).Return([]*castai.ClusterAction{ + { + ID: "a1", + CreatedAt: time.Now(), + ActionDeleteNode: &castai.ActionDeleteNode{ + NodeName: "n1", + }, + }, + }, nil).Times(1).MinTimes(1) + }, + }, + }, + { + name: "ack with error when action handler panic occurred", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second) + return ctx + }, + }, + fields: fields{ + cfg: cfg, + k8sVersion: "1.20.1", + tuneMockHandler: func(m *mock_actions.MockActionHandler) { + m.EXPECT().Handle(gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, action *castai.ClusterAction) error { + panic("ups") + }). + MinTimes(1) + }, + tuneMockCastAIClient: func(m *mock_castai.MockCastAIClient) { + m.EXPECT().GetActions(gomock.Any(), gomock.Any()).Return([]*castai.ClusterAction{ + { + ID: "a1", + CreatedAt: time.Now(), + ActionDeleteNode: &castai.ActionDeleteNode{ + NodeName: "n1", + }, + }, + }, nil).Times(1).MinTimes(1) + m.EXPECT().AckAction(gomock.Any(), "a1", gomock.Any()). + DoAndReturn(func(ctx context.Context, actionID string, req *castai.AckClusterActionRequest) error { + require.NotNil(t, req.Error) + return nil + }).MinTimes(1) + }, + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + m := gomock.NewController(t) + defer m.Finish() + client := mock_castai.NewMockCastAIClient(m) + if tt.fields.tuneMockCastAIClient != nil { + tt.fields.tuneMockCastAIClient(client) + } + s := NewService( + logrus.New(), + tt.fields.cfg, + tt.fields.k8sVersion, + kubernetes.New(nil), + nil, + client, + nil, + health.NewHealthzProvider(health.HealthzCfg{HealthyPollIntervalLimit: pollTimeout}, logrus.New())) + handler := mock_actions.NewMockActionHandler(m) + if tt.fields.tuneMockHandler != nil { + tt.fields.tuneMockHandler(handler) + } + for k := range s.actionHandlers { + s.actionHandlers[k] = handler + } + s.Run(tt.args.ctx()) + }) + } +} + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon")) +} diff --git a/helm/chart_loader.go b/internal/helm/chart_loader.go similarity index 96% rename from helm/chart_loader.go rename to internal/helm/chart_loader.go index 172f9d24..fc20154a 100644 --- a/helm/chart_loader.go +++ b/internal/helm/chart_loader.go @@ -17,8 +17,8 @@ import ( "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/repo" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/waitext" ) const ( diff --git a/helm/chart_loader_test.go b/internal/helm/chart_loader_test.go similarity index 91% rename from helm/chart_loader_test.go rename to internal/helm/chart_loader_test.go index b21e9b55..07fb65d7 100644 --- a/helm/chart_loader_test.go +++ b/internal/helm/chart_loader_test.go @@ -8,7 +8,7 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestIntegration_ChartLoader(t *testing.T) { diff --git a/helm/client.go b/internal/helm/client.go similarity index 98% rename from helm/client.go rename to internal/helm/client.go index 02f00a86..9bbeaefe 100644 --- a/helm/client.go +++ b/internal/helm/client.go @@ -20,8 +20,8 @@ import ( "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/helm/hook" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/helm/hook" ) type InstallOptions struct { diff --git a/helm/client_test.go b/internal/helm/client_test.go similarity index 98% rename from helm/client_test.go rename to internal/helm/client_test.go index ce8bb283..e78bef18 100644 --- a/helm/client_test.go +++ b/internal/helm/client_test.go @@ -16,7 +16,7 @@ import ( "helm.sh/helm/v3/pkg/storage/driver" "helm.sh/helm/v3/pkg/time" - "github.com/castai/cluster-controller/castai" + "github.com/castai/cluster-controller/internal/castai" ) func TestClientInstall(t *testing.T) { diff --git a/helm/hook/hook.go b/internal/helm/hook/hook.go similarity index 99% rename from helm/hook/hook.go rename to internal/helm/hook/hook.go index 0e2a1b0c..4b6168f7 100644 --- a/helm/hook/hook.go +++ b/internal/helm/hook/hook.go @@ -11,7 +11,7 @@ import ( "sigs.k8s.io/yaml" ) -// group/version/kind/namespace/name +// group/version/kind/namespace/name. var labelIgnoreResources = map[string]struct{}{ "rbac.authorization.k8s.io/v1/ClusterRole//castai-evictor": {}, "rbac.authorization.k8s.io/v1/ClusterRoleBinding//castai-evictor": {}, diff --git a/helm/hook/hook_test.go b/internal/helm/hook/hook_test.go similarity index 95% rename from helm/hook/hook_test.go rename to internal/helm/hook/hook_test.go index 0bb97b07..db1ba8e5 100644 --- a/helm/hook/hook_test.go +++ b/internal/helm/hook/hook_test.go @@ -11,7 +11,7 @@ import ( "helm.sh/helm/v3/pkg/release" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/castai/cluster-controller/helm/hook/mock" + "github.com/castai/cluster-controller/internal/helm/hook/mock" ) type componentVersions struct { @@ -26,7 +26,7 @@ type k8sObjectDetails struct { updateLabels bool } -func renderManifestTemplate(apiVersion string, kind string, name string, appVersion string, chartVersion string) (string, error) { +func renderManifestTemplate(apiVersion, kind, name, appVersion, chartVersion string) (string, error) { vars := map[string]interface{}{ "ApiVersion": apiVersion, "Kind": kind, @@ -61,7 +61,6 @@ metadata: } return renderedTemplate.String(), nil - } func TestIgnoreHook(t *testing.T) { diff --git a/helm/hook/mock/kube_client.go b/internal/helm/hook/mock/kube_client.go similarity index 97% rename from helm/hook/mock/kube_client.go rename to internal/helm/hook/mock/kube_client.go index 4b49df91..d52a8a89 100644 --- a/helm/hook/mock/kube_client.go +++ b/internal/helm/hook/mock/kube_client.go @@ -10,9 +10,9 @@ import ( ) // MockKubeClient mocks Helm KubernetesClient interface -type MockKubeClient struct {} +type MockKubeClient struct{} -func (m *MockKubeClient) Create(resources kube.ResourceList) (*kube.Result, error){ +func (m *MockKubeClient) Create(resources kube.ResourceList) (*kube.Result, error) { return nil, nil } diff --git a/helm/mock/chart_loader.go b/internal/helm/mock/chart_loader.go similarity index 89% rename from helm/mock/chart_loader.go rename to internal/helm/mock/chart_loader.go index 4cf60f98..05ebbaa6 100644 --- a/helm/mock/chart_loader.go +++ b/internal/helm/mock/chart_loader.go @@ -5,12 +5,12 @@ package mock_helm import ( - context "context" - reflect "reflect" + "context" + "reflect" - castai "github.com/castai/cluster-controller/castai" - gomock "github.com/golang/mock/gomock" - chart "helm.sh/helm/v3/pkg/chart" + "github.com/castai/cluster-controller/internal/castai" + "github.com/golang/mock/gomock" + "helm.sh/helm/v3/pkg/chart" ) // MockChartLoader is a mock of ChartLoader interface. diff --git a/helm/mock/client.go b/internal/helm/mock/client.go similarity index 95% rename from helm/mock/client.go rename to internal/helm/mock/client.go index 2c18c573..4b2d323e 100644 --- a/helm/mock/client.go +++ b/internal/helm/mock/client.go @@ -5,13 +5,13 @@ package mock_helm import ( - context "context" - reflect "reflect" + "context" + "reflect" - helm "github.com/castai/cluster-controller/helm" - gomock "github.com/golang/mock/gomock" - action "helm.sh/helm/v3/pkg/action" - release "helm.sh/helm/v3/pkg/release" + "github.com/castai/cluster-controller/internal/helm" + "github.com/golang/mock/gomock" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/release" ) // MockClient is a mock of Client interface. diff --git a/version/mock/version.go b/internal/k8sversion/mock/version.go similarity index 96% rename from version/mock/version.go rename to internal/k8sversion/mock/version.go index 77f2dd73..1b83ccbb 100644 --- a/version/mock/version.go +++ b/internal/k8sversion/mock/version.go @@ -5,9 +5,9 @@ package mock_version import ( - reflect "reflect" + "reflect" - gomock "github.com/golang/mock/gomock" + "github.com/golang/mock/gomock" ) // MockInterface is a mock of Interface interface. diff --git a/version/version.go b/internal/k8sversion/version.go similarity index 98% rename from version/version.go rename to internal/k8sversion/version.go index b9230dd1..df38f907 100644 --- a/version/version.go +++ b/internal/k8sversion/version.go @@ -1,5 +1,5 @@ //go:generate mockgen -destination ./mock/version.go . Interface -package version +package k8sversion import ( "fmt" diff --git a/version/version_test.go b/internal/k8sversion/version_test.go similarity index 97% rename from version/version_test.go rename to internal/k8sversion/version_test.go index f554954e..a4cccf0a 100644 --- a/version/version_test.go +++ b/internal/k8sversion/version_test.go @@ -1,4 +1,4 @@ -package version +package k8sversion import ( "encoding/json" diff --git a/castai/logexporter.go b/internal/logexporter/logexporter.go similarity index 84% rename from castai/logexporter.go rename to internal/logexporter/logexporter.go index e3ddc585..5a33a3aa 100644 --- a/castai/logexporter.go +++ b/internal/logexporter/logexporter.go @@ -1,4 +1,5 @@ -package castai +//go:generate mockgen -destination ./mock/sender.go . LogSender +package logexporter import ( "context" @@ -7,28 +8,28 @@ import ( "github.com/sirupsen/logrus" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/waitext" ) const ( sendTimeout = 15 * time.Second ) -type logEntry struct { +type LogEntry struct { Level string `json:"level"` Time time.Time `json:"time"` Message string `json:"message"` Fields logrus.Fields `json:"fields"` } -type logSender interface { - SendLog(ctx context.Context, e *logEntry) error +type LogSender interface { + SendLog(ctx context.Context, e *LogEntry) error } // LogExporter hooks into logrus and sends logs to Mothership. type LogExporter struct { logger *logrus.Logger - sender logSender + sender LogSender wg sync.WaitGroup } @@ -37,7 +38,7 @@ var _ logrus.Hook = new(LogExporter) // NewLogExporter returns new exporter that can be hooked into logrus // to inject logs into Cast AI. -func NewLogExporter(logger *logrus.Logger, sender logSender) *LogExporter { +func NewLogExporter(logger *logrus.Logger, sender LogSender) *LogExporter { return &LogExporter{ logger: logger, sender: sender, @@ -77,7 +78,7 @@ func (e *LogExporter) sendLogEvent(log *logrus.Entry) { ctx, cancel := context.WithTimeout(context.Background(), sendTimeout) defer cancel() - logEntry := &logEntry{ + logEntry := &LogEntry{ Level: log.Level.String(), Time: log.Time, Message: log.Message, @@ -90,7 +91,6 @@ func (e *LogExporter) sendLogEvent(log *logrus.Entry) { }, func(err error) { e.logger.Debugf("failed to send logs, will retry: %s", err) }) - if err != nil { e.logger.Debugf("sending logs: %v", err) } diff --git a/internal/logexporter/logexporter_test.go b/internal/logexporter/logexporter_test.go new file mode 100644 index 00000000..38ff050e --- /dev/null +++ b/internal/logexporter/logexporter_test.go @@ -0,0 +1,81 @@ +package logexporter_test + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "go.uber.org/goleak" + + "github.com/castai/cluster-controller/internal/logexporter" + mock_logexporter "github.com/castai/cluster-controller/internal/logexporter/mock" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon")) +} + +func TestSetupLogExporter(t *testing.T) { + t.Parallel() + type args struct { + tuneMockSender func(sender *mock_logexporter.MockLogSender) + msg map[uint32]string // level -> message. + } + tests := []struct { + name string + args args + }{ + { + name: "1 error, 1 debug", + args: args{ + msg: map[uint32]string{ + uint32(logrus.ErrorLevel): "foo", + uint32(logrus.DebugLevel): "bar", + }, + tuneMockSender: func(sender *mock_logexporter.MockLogSender) { + sender.EXPECT().SendLog(gomock.Any(), gomock.Any()). + Return(nil).Times(1) + }, + }, + }, + { + name: "sendLog error", + args: args{ + msg: map[uint32]string{ + uint32(logrus.ErrorLevel): "foo", + uint32(logrus.DebugLevel): "bar", + }, + tuneMockSender: func(sender *mock_logexporter.MockLogSender) { + sender.EXPECT().SendLog(gomock.Any(), gomock.Any()). + Return(fmt.Errorf("test-error")).Times(4) + }, + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + m := gomock.NewController(t) + defer m.Finish() + sender := mock_logexporter.NewMockLogSender(m) + if tt.args.tuneMockSender != nil { + tt.args.tuneMockSender(sender) + } + logger, hook := test.NewNullLogger() + defer hook.Reset() + + e := logexporter.NewLogExporter(logger, sender) + logger.AddHook(e) + log := logger.WithFields(logrus.Fields{ + "cluster_id": "test-cluster", + }) + for level, msg := range tt.args.msg { + log.Log(logrus.Level(level), msg) + } + e.Wait() + }) + } +} diff --git a/internal/logexporter/mock/sender.go b/internal/logexporter/mock/sender.go new file mode 100644 index 00000000..75264a2d --- /dev/null +++ b/internal/logexporter/mock/sender.go @@ -0,0 +1,50 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/castai/cluster-controller/internal/logexporter (interfaces: LogSender) + +// Package mock_logexporter is a generated GoMock package. +package mock_logexporter + +import ( + context "context" + reflect "reflect" + + logexporter "github.com/castai/cluster-controller/internal/logexporter" + gomock "github.com/golang/mock/gomock" +) + +// MockLogSender is a mock of LogSender interface. +type MockLogSender struct { + ctrl *gomock.Controller + recorder *MockLogSenderMockRecorder +} + +// MockLogSenderMockRecorder is the mock recorder for MockLogSender. +type MockLogSenderMockRecorder struct { + mock *MockLogSender +} + +// NewMockLogSender creates a new mock instance. +func NewMockLogSender(ctrl *gomock.Controller) *MockLogSender { + mock := &MockLogSender{ctrl: ctrl} + mock.recorder = &MockLogSenderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLogSender) EXPECT() *MockLogSenderMockRecorder { + return m.recorder +} + +// SendLog mocks base method. +func (m *MockLogSender) SendLog(arg0 context.Context, arg1 *logexporter.LogEntry) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendLog", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendLog indicates an expected call of SendLog. +func (mr *MockLogSenderMockRecorder) SendLog(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendLog", reflect.TypeOf((*MockLogSender)(nil).SendLog), arg0, arg1) +} diff --git a/testdata/aks/CBD209E745FE4FC85066CBA305F32F9A1CFD89A3.prv b/internal/testdata/aks/CBD209E745FE4FC85066CBA305F32F9A1CFD89A3.prv similarity index 100% rename from testdata/aks/CBD209E745FE4FC85066CBA305F32F9A1CFD89A3.prv rename to internal/testdata/aks/CBD209E745FE4FC85066CBA305F32F9A1CFD89A3.prv diff --git a/testdata/aks/Microsoft.Azure.Extensions.CustomScript-2.1.6/config/1.settings b/internal/testdata/aks/Microsoft.Azure.Extensions.CustomScript-2.1.6/config/1.settings similarity index 100% rename from testdata/aks/Microsoft.Azure.Extensions.CustomScript-2.1.6/config/1.settings rename to internal/testdata/aks/Microsoft.Azure.Extensions.CustomScript-2.1.6/config/1.settings diff --git a/testdata/aks/ovf-env.xml b/internal/testdata/aks/ovf-env.xml similarity index 100% rename from testdata/aks/ovf-env.xml rename to internal/testdata/aks/ovf-env.xml diff --git a/waitext/doc.go b/internal/waitext/doc.go similarity index 100% rename from waitext/doc.go rename to internal/waitext/doc.go diff --git a/waitext/extensions.go b/internal/waitext/extensions.go similarity index 95% rename from waitext/extensions.go rename to internal/waitext/extensions.go index b07f0205..7a704442 100644 --- a/waitext/extensions.go +++ b/internal/waitext/extensions.go @@ -21,7 +21,7 @@ const ( ) // DefaultExponentialBackoff creates an exponential backoff with sensible default values. -// Defaults should match ExponentialBackoff in github.com/cenkalti/backoff +// Defaults should match ExponentialBackoff in github.com/cenkalti/backoff. func DefaultExponentialBackoff() wait.Backoff { return wait.Backoff{ Duration: defaultInitialInterval, @@ -34,7 +34,7 @@ func DefaultExponentialBackoff() wait.Backoff { // NewConstantBackoff creates a backoff that steps at constant intervals. // This backoff will run "forever", use WithMaxRetries or a context to put a hard cap. -// This works similar to ConstantBackOff in github.com/cenkalti/backoff +// This works similar to ConstantBackOff in github.com/cenkalti/backoff. func NewConstantBackoff(interval time.Duration) wait.Backoff { return wait.Backoff{ Duration: interval, @@ -63,20 +63,20 @@ func NewConstantBackoff(interval time.Duration) wait.Backoff { // - a multi-error if context is cancelled that contains - the ctx.Err(), context.Cause() and last encountered error from the operation // // If retryNotify is passed, it is called when making retries. -// Caveat: this function is similar to wait.ExponentialBackoff but has some important behavior differences like at-least-one execution and retryable errors +// Caveat: this function is similar to wait.ExponentialBackoff but has some important behavior differences like at-least-one execution and retryable errors. func Retry(ctx context.Context, backoff wait.Backoff, retries int, operation func(context.Context) (bool, error), retryNotify func(error)) error { var lastErr error var shouldRetry bool shouldRetry, lastErr = operation(ctx) - // No retry needed + // No retry needed. if lastErr == nil || !shouldRetry { return lastErr } for retries > 0 { - // Notify about expected retry + // Notify about expected retry. if retryNotify != nil { retryNotify(lastErr) } @@ -91,7 +91,7 @@ func Retry(ctx context.Context, backoff wait.Backoff, retries int, operation fun shouldRetry, lastErr = operation(ctx) retries-- - // We are done + // We are done. if lastErr == nil || !shouldRetry { break } diff --git a/waitext/extensions_test.go b/internal/waitext/extensions_test.go similarity index 99% rename from waitext/extensions_test.go rename to internal/waitext/extensions_test.go index 24d24383..5d656a1a 100644 --- a/waitext/extensions_test.go +++ b/internal/waitext/extensions_test.go @@ -56,7 +56,7 @@ func TestRetry(t *testing.T) { backoff.Jitter = 0 // There is no "initial" wait so 0 index simulates zero. - // The rest are calculated as interval * factor^(ix) without jitter for simplicity + // The rest are calculated as interval * factor^(ix) without jitter for simplicity. expectedWaitTimes := []time.Duration{ time.Millisecond, 10 * time.Millisecond, @@ -76,7 +76,7 @@ func TestRetry(t *testing.T) { t.Log("wait time", waitTime) - // We give some tolerance as we can't be precise to the nanosecond here + // We give some tolerance as we can't be precise to the nanosecond here. r.InDelta(expectedWaitTimes[indexWaitTimes], waitTime, float64(2*time.Millisecond)) indexWaitTimes++ diff --git a/main.go b/main.go index 2b0b4e5e..973e5dca 100644 --- a/main.go +++ b/main.go @@ -28,14 +28,15 @@ import ( "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/manager/signals" - "github.com/castai/cluster-controller/actions" - "github.com/castai/cluster-controller/castai" - "github.com/castai/cluster-controller/config" - "github.com/castai/cluster-controller/csr" "github.com/castai/cluster-controller/health" - "github.com/castai/cluster-controller/helm" - "github.com/castai/cluster-controller/version" - "github.com/castai/cluster-controller/waitext" + "github.com/castai/cluster-controller/internal/actions/csr" + "github.com/castai/cluster-controller/internal/castai" + "github.com/castai/cluster-controller/internal/config" + "github.com/castai/cluster-controller/internal/controller" + "github.com/castai/cluster-controller/internal/helm" + "github.com/castai/cluster-controller/internal/k8sversion" + "github.com/castai/cluster-controller/internal/logexporter" + "github.com/castai/cluster-controller/internal/waitext" ) // These should be set via `go build` during a release. @@ -72,17 +73,16 @@ func main() { cl, err := castai.NewRestyClient(cfg.API.URL, cfg.API.Key, cfg.TLS.CACert, logger.Level, binVersion, maxRequestTimeout) if err != nil { log.Fatalf("failed to create castai client: %v", err) - } client := castai.NewClient(logger, cl, cfg.ClusterID) - e := castai.NewLogExporter(logger, client) + e := logexporter.NewLogExporter(logger, client) logger.AddHook(e) logrus.RegisterExitHandler(e.Wait) ctx := signals.SetupSignalHandler() if err := run(ctx, client, logger, cfg, binVersion); err != nil { - logErr := &logContextErr{} + logErr := &logContextError{} if errors.As(err, &logErr) { log = logger.WithFields(logErr.fields) } @@ -92,7 +92,7 @@ func main() { func run( ctx context.Context, - client castai.ActionsClient, + client castai.CastAIClient, logger *logrus.Logger, cfg config.Config, binVersion *config.ClusterControllerVersion, @@ -103,7 +103,7 @@ func run( if reterr == nil { return } - reterr = &logContextErr{ + reterr = &logContextError{ err: reterr, fields: fields, } @@ -136,7 +136,7 @@ func run( return err } - k8sVersion, err := version.Get(clientset) + k8sVersion, err := k8sversion.Get(clientset) if err != nil { return fmt.Errorf("getting kubernetes version: %w", err) } @@ -148,13 +148,13 @@ func run( "ctrl_pod_name": cfg.PodName, }) - // Set logr/klog to logrus adapter so all logging goes through logrus + // Set logr/klog to logrus adapter so all logging goes through logrus. logr := logrusr.New(log) klog.SetLogger(logr) log.Infof("running castai-cluster-controller version %v, log-level: %v", binVersion, logger.Level) - actionsConfig := actions.Config{ + actionsConfig := controller.Config{ PollWaitInterval: 5 * time.Second, PollTimeout: maxRequestTimeout, AckTimeout: 30 * time.Second, @@ -166,7 +166,7 @@ func run( } healthzAction := health.NewHealthzProvider(health.HealthzCfg{HealthyPollIntervalLimit: (actionsConfig.PollWaitInterval + actionsConfig.PollTimeout) * 2, StartTimeLimit: 2 * time.Minute}, log) - svc := actions.NewService( + svc := controller.NewService( log, actionsConfig, k8sVersion.Full(), @@ -176,6 +176,11 @@ func run( helmClient, healthzAction, ) + defer func() { + if err := svc.Close(); err != nil { + log.Errorf("failed to close controller service: %v", err) + } + }() httpMux := http.NewServeMux() var checks []healthz.HealthChecker @@ -193,6 +198,8 @@ func run( addr := fmt.Sprintf(":%d", cfg.PprofPort) log.Infof("starting pprof server on %s", addr) + //TODO: remove nolint when we have a proper solution for this + //nolint:gosec if err := http.ListenAndServe(addr, httpMux); err != nil { log.Errorf("failed to start pprof http server: %v", err) } @@ -237,7 +244,7 @@ func runWithLeaderElection( } id = id + "_" + uuid.New().String() - // Start the leader election code loop + // Start the leader election code loop. leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ Lock: &resourcelock.LeaseLock{ LeaseMeta: metav1.ObjectMeta{ @@ -378,16 +385,16 @@ func (rt *kubeRetryTransport) RoundTrip(req *http.Request) (*http.Response, erro return resp, err } -type logContextErr struct { +type logContextError struct { err error fields logrus.Fields } -func (e *logContextErr) Error() string { +func (e *logContextError) Error() string { return e.err.Error() } -func (e *logContextErr) Unwrap() error { +func (e *logContextError) Unwrap() error { return e.err } @@ -398,7 +405,7 @@ func runningOnGKE(clientset *kubernetes.Clientset, cfg config.Config) (isGKE boo return true, fmt.Errorf("getting node: %w", err) } - for k, _ := range node.Labels { + for k := range node.Labels { if strings.HasPrefix(k, "cloud.google.com/") { isGKE = true return false, nil @@ -407,7 +414,6 @@ func runningOnGKE(clientset *kubernetes.Clientset, cfg config.Config) (isGKE boo return false, nil }, func(err error) { - }) return