diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index c047d9a5..e3d5fe62 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -31,21 +31,93 @@ jobs: path: ./v3/services/conversionsvc image: conversion-service secrets: inherit + build-course-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/coursesvc + image: course-service + secrets: inherit + build-dbconfig-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/dbconfigsvc + image: dbconfig-service + secrets: inherit + build-environment-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/environmentsvc + image: environment-service + secrets: inherit + build-progress-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/progresssvc + image: progress-service + secrets: inherit build-rbac-service: uses: ./.github/workflows/build.yaml with: path: ./v3/services/rbacsvc image: rbac-service secrets: inherit + build-scenario-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/scenariosvc + image: scenario-service + secrets: inherit + build-scheduledevent-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/scheduledeventsvc + image: scheduledevent-service + secrets: inherit + build-session-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/sessionsvc + image: session-service + secrets: inherit build-setting-service: uses: ./.github/workflows/build.yaml with: path: ./v3/services/settingsvc image: setting-service secrets: inherit + build-terraform-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/terraformsvc + image: terraform-service + secrets: inherit build-user-service: uses: ./.github/workflows/build.yaml with: path: ./v3/services/usersvc image: user-service + secrets: inherit + build-vmclaim-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/vmclaimsvc + image: vmclaim-service + secrets: inherit + build-vmset-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/vmsetsvc + image: vmset-service + secrets: inherit + build-vm-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/vmsvc + image: vm-service + secrets: inherit + build-vmtemplate-service: + uses: ./.github/workflows/build.yaml + with: + path: ./v3/services/vmtemplatesvc + image: vmtemplate-service secrets: inherit \ No newline at end of file diff --git a/generate-protos.sh b/generate-protos.sh index fdc63b3e..21a2d575 100644 --- a/generate-protos.sh +++ b/generate-protos.sh @@ -12,7 +12,7 @@ docker run --rm \ -c "apt-get update && apt-get install -y protobuf-compiler && \ export PATH=\$PATH:/go/bin && \ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest && \ - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest && \ + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 && \ find ${PROTO_DIR} -type f -name '*.proto' -exec bash -c ' \ protoc -I ${PROTO_DIR} \ --go_out=./protos \ diff --git a/go.work b/go.work index 7fd0871a..b229ddb4 100644 --- a/go.work +++ b/go.work @@ -10,4 +10,16 @@ use ( ./v3/services/rbacsvc ./v3/services/settingsvc ./v3/services/usersvc + ./v3/services/dbconfigsvc + ./v3/services/vmclaimsvc + ./v3/services/vmsetsvc + ./v3/services/progresssvc + ./v3/services/vmtemplatesvc + ./v3/services/vmsvc + ./v3/services/sessionsvc + ./v3/services/scheduledeventsvc + ./v3/services/environmentsvc + ./v3/services/scenariosvc + ./v3/services/coursesvc + ./v3/services/terraformsvc ) diff --git a/main.go b/main.go index 3cacb60a..4dd76b20 100644 --- a/main.go +++ b/main.go @@ -5,46 +5,20 @@ import ( "flag" "os" - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - "github.com/hobbyfarm/gargantua/v3/pkg/authserver" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/pkg/controllers/scheduledevent" - "github.com/hobbyfarm/gargantua/v3/pkg/controllers/session" - "github.com/hobbyfarm/gargantua/v3/pkg/controllers/tfpcontroller" - "github.com/hobbyfarm/gargantua/v3/pkg/controllers/vmclaimcontroller" - "github.com/hobbyfarm/gargantua/v3/pkg/controllers/vmsetcontroller" - "github.com/hobbyfarm/gargantua/v3/pkg/courseclient" - "github.com/hobbyfarm/gargantua/v3/pkg/courseserver" "github.com/hobbyfarm/gargantua/v3/pkg/crd" - "github.com/hobbyfarm/gargantua/v3/pkg/environmentserver" "github.com/hobbyfarm/gargantua/v3/pkg/microservices" predefinedserviceserver "github.com/hobbyfarm/gargantua/v3/pkg/predefinedserviceserver" - "github.com/hobbyfarm/gargantua/v3/pkg/progressserver" - "github.com/hobbyfarm/gargantua/v3/pkg/scenarioclient" - "github.com/hobbyfarm/gargantua/v3/pkg/scenarioserver" - "github.com/hobbyfarm/gargantua/v3/pkg/scheduledeventserver" - "github.com/hobbyfarm/gargantua/v3/pkg/sessionserver" "github.com/hobbyfarm/gargantua/v3/pkg/shell" - "github.com/hobbyfarm/gargantua/v3/pkg/signals" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - "github.com/hobbyfarm/gargantua/v3/pkg/vmclaimserver" - "github.com/hobbyfarm/gargantua/v3/pkg/vmclient" - "github.com/hobbyfarm/gargantua/v3/pkg/vmserver" - "github.com/hobbyfarm/gargantua/v3/pkg/vmsetserver" - "github.com/hobbyfarm/gargantua/v3/pkg/vmtemplateserver" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - "github.com/hobbyfarm/gargantua/v3/protos/setting" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" "github.com/ebauman/crder" - "golang.org/x/sync/errgroup" - "k8s.io/client-go/informers" - "k8s.io/client-go/tools/leaderelection" "net/http" "sync" - "time" "github.com/golang/glog" "github.com/gorilla/handlers" @@ -61,26 +35,20 @@ const ( ) var ( - localMasterUrl string - localKubeconfig string - disableControllers bool - shellServer bool - tlsCA string + localMasterUrl string + localKubeconfig string + shellServer bool + tlsCA string ) func init() { flag.StringVar(&localKubeconfig, "kubeconfig", "", "Path to kubeconfig of local cluster. Only required if out-of-cluster.") flag.StringVar(&localMasterUrl, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.") - flag.BoolVar(&disableControllers, "disablecontrollers", false, "Disable the controllers") flag.BoolVar(&shellServer, "shellserver", false, "Be a shell server") flag.StringVar(&tlsCA, "tls-ca", "/etc/ssl/certs/ca.crt", "Path to CA cert for auth servers") } func main() { - //var signal chan struct{} - //signal = make(chan struct{}) - - stopCh := signals.SetupSignalHandler() ctx := context.Background() flag.Parse() glog.V(2).Infof("Starting Gargantua") @@ -95,8 +63,6 @@ func main() { } } - namespace := util.GetReleaseNamespace() - if !shellServer { crds := crd.GenerateCRDs() @@ -121,152 +87,44 @@ func main() { glog.Fatalf("Error building kubernetes clientset: %s", err.Error()) } - hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) - kubeInformerFactory := informers.NewSharedInformerFactoryWithOptions(kubeClient, time.Second*30, informers.WithNamespace(namespace)) - cert, err := microservices.BuildTLSClientCredentials(tlsCA) if err != nil { glog.Fatalf("error building cert: %v", err) } services := []microservices.MicroService{ - microservices.Setting, microservices.AuthN, microservices.AuthR, + microservices.VM, + microservices.VMTemplate, } connections := microservices.EstablishConnections(services, cert) for _, conn := range connections { defer conn.Close() } - settingClient := setting.NewSettingSvcClient(connections[microservices.Setting]) - authnClient := authn.NewAuthNClient(connections[microservices.AuthN]) - authrClient := authr.NewAuthRClient(connections[microservices.AuthR]) - - acClient, err := accesscode.NewAccessCodeClient(hfClient, ctx) - if err != nil { - glog.Fatal(err) - } - - authServer, err := authserver.NewAuthServer(authnClient, hfClient, ctx, acClient) - if err != nil { - glog.Fatal(err) - } - - courseServer, err := courseserver.NewCourseServer(authnClient, authrClient, acClient, hfClient, hfInformerFactory, ctx) - if err != nil { - glog.Fatal(err) - } - - courseClient, err := courseclient.NewCourseClient(courseServer) - if err != nil { - glog.Fatal(err) - } + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + vmClient := vmpb.NewVMSvcClient(connections[microservices.VM]) + vmTemplateClient := vmtemplatepb.NewVMTemplateSvcClient(connections[microservices.VMTemplate]) - scenarioServer, err := scenarioserver.NewScenarioServer(authnClient, authrClient, acClient, hfClient, hfInformerFactory, ctx, courseClient) - if err != nil { - glog.Fatal(err) - } - - scenarioClient, err := scenarioclient.NewScenarioClient(scenarioServer) - if err != nil { - glog.Fatal(err) - } - - sessionServer, err := sessionserver.NewSessionServer(authnClient, authrClient, acClient, scenarioClient, courseClient, hfClient, hfInformerFactory, ctx) - if err != nil { - glog.Fatal(err) - } - - vmServer, err := vmserver.NewVMServer(authnClient, authrClient, hfClient, hfInformerFactory, ctx) - if err != nil { - glog.Fatal(err) - } - - vmSetServer, err := vmsetserver.NewVMSetServer(authnClient, authrClient, hfClient, hfInformerFactory, ctx) - if err != nil { - glog.Fatal(err) - } - - vmClient, err := vmclient.NewVirtualMachineClient(vmServer) - if err != nil { - glog.Fatal(err) - } - - vmClaimServer, err := vmclaimserver.NewVMClaimServer(authnClient, authrClient, hfClient, hfInformerFactory) - if err != nil { - glog.Fatal(err) - } - - shellProxy, err := shell.NewShellProxy(authnClient, authrClient, vmClient, hfClient, kubeClient, ctx) - if err != nil { - glog.Fatal(err) - } - - environmentServer, err := environmentserver.NewEnvironmentServer(authnClient, authrClient, hfClient, ctx) - if err != nil { - glog.Fatal(err) - } - - scheduledEventServer, err := scheduledeventserver.NewScheduledEventServer(authnClient, authrClient, hfClient, ctx) - if err != nil { - glog.Fatal(err) - } - - vmTemplateServer, err := vmtemplateserver.NewVirtualMachineTemplateServer(authnClient, authrClient, hfClient, ctx) - if err != nil { - glog.Fatal(err) - } + shellProxy := shell.NewShellProxy(authnClient, authrClient, vmClient, vmTemplateClient, kubeClient) predefinedServiceServer, err := predefinedserviceserver.NewPredefinedServiceServer(authnClient, authrClient, hfClient, ctx) if err != nil { glog.Fatal(err) } - progressServer, err := progressserver.NewProgressServer(authnClient, authrClient, hfClient, ctx) - if err != nil { - glog.Fatal(err) - } - if shellServer { glog.V(2).Infof("Starting as a shell server") shellProxy.SetupRoutes(r) } else { - authServer.SetupRoutes(r) - sessionServer.SetupRoutes(r) - courseServer.SetupRoutes(r) - scenarioServer.SetupRoutes(r) - vmServer.SetupRoutes(r) - vmSetServer.SetupRoutes(r) - //shellProxy.SetupRoutes(r) - vmClaimServer.SetupRoutes(r) - environmentServer.SetupRoutes(r) - scheduledEventServer.SetupRoutes(r) - vmTemplateServer.SetupRoutes(r) - progressServer.SetupRoutes(r) predefinedServiceServer.SetupRoutes(r) } corsHeaders := handlers.AllowedHeaders([]string{"Authorization", "Content-Type"}) corsOrigins := handlers.AllowedOrigins([]string{"*"}) corsMethods := handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS", "DELETE"}) - /* - glog.V(6).Infof("Waiting for informers to synchronize") - if ok := cache.WaitForCacheSync(stopCh, - hfInformerFactory.Hobbyfarm().V1().Users().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().Sessions().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().Scenarios().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().AccessCodes().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Informer().HasSynced, - //hfInformerFactory.Hobbyfarm().V1().Environments().Informer().HasSynced, - hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Informer().HasSynced, - ); !ok { - glog.Fatalf("failed to wait for caches to sync") - } - glog.V(6).Infof("Informers have synchronized") - */ var wg sync.WaitGroup @@ -285,102 +143,5 @@ func main() { glog.Fatal(http.ListenAndServe(":"+apiPort, handlers.CORS(corsHeaders, corsOrigins, corsMethods)(r))) }() - if !disableControllers { - lock, err := util.GetLock("controller-manager-gargantua", cfg) - if err != nil { - glog.Fatal(err) - } - leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ - Lock: lock, - ReleaseOnCancel: true, - LeaseDuration: 10 * time.Second, - RenewDeadline: 5 * time.Second, - RetryPeriod: 2 * time.Second, - Callbacks: leaderelection.LeaderCallbacks{ - OnStartedLeading: func(c context.Context) { - err = bootStrapControllers(kubeClient, hfClient, hfInformerFactory, kubeInformerFactory, acClient, settingClient, ctx, stopCh) - if err != nil { - glog.Fatal(err) - } - }, - OnStoppedLeading: func() { - // Need to start informer factory since even when not leader to ensure api layer - // keeps working. - hfInformerFactory.Start(stopCh) - glog.Info("waiting to be elected leader") - }, - OnNewLeader: func(current_id string) { - hfInformerFactory.Start(stopCh) - if current_id == lock.Identity() { - glog.Info("currently the leader") - return - } - glog.Infof("current leader is %s", current_id) - }, - }, - }) - } else { - // default fire up hfInformer as this is still needed by the shell server - hfInformerFactory.Start(stopCh) - kubeInformerFactory.Start(stopCh) - } wg.Wait() } - -func bootStrapControllers(kubeClient *kubernetes.Clientset, hfClient *hfClientset.Clientset, - hfInformerFactory hfInformers.SharedInformerFactory, kubeInformerFactory informers.SharedInformerFactory, acClient *accesscode.AccessCodeClient, - settingClient setting.SettingSvcClient, ctx context.Context, stopCh <-chan struct{}) error { - - g, gctx := errgroup.WithContext(ctx) - glog.V(2).Infof("Starting controllers") - sessionController, err := session.NewSessionController(hfClient, hfInformerFactory, gctx) - if err != nil { - return err - } - scheduledEventController, err := scheduledevent.NewScheduledEventController(hfClient, hfInformerFactory, gctx, settingClient) - if err != nil { - return err - } - vmClaimController, err := vmclaimcontroller.NewVMClaimController(hfClient, hfInformerFactory, acClient, gctx) - if err != nil { - return err - } - tfpController, err := tfpcontroller.NewTerraformProvisionerController(kubeClient, hfClient, hfInformerFactory, gctx) - if err != nil { - return err - } - vmSetController, err := vmsetcontroller.NewVirtualMachineSetController(hfClient, hfInformerFactory, gctx) - if err != nil { - return err - } - - g.Go(func() error { - return sessionController.Run(stopCh) - }) - - g.Go(func() error { - return scheduledEventController.Run(stopCh) - }) - - g.Go(func() error { - return vmClaimController.Run(stopCh) - }) - - g.Go(func() error { - return tfpController.Run(stopCh) - }) - - g.Go(func() error { - return vmSetController.Run(stopCh) - }) - - hfInformerFactory.Start(stopCh) - kubeInformerFactory.Start(stopCh) - - if err = g.Wait(); err != nil { - glog.Errorf("error starting up the controllers: %v", err) - return err - } - - return nil -} diff --git a/v3/go.mod b/v3/go.mod index 4593ceea..dd66b9c4 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -7,6 +7,7 @@ replace k8s.io/client-go => k8s.io/client-go v0.28.2 require ( github.com/ebauman/crder v0.1.0 github.com/golang/glog v1.0.0 + github.com/golang/protobuf v1.5.3 github.com/gorilla/handlers v1.4.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 @@ -22,7 +23,6 @@ require ( k8s.io/apiextensions-apiserver v0.28.2 k8s.io/apimachinery v0.28.2 k8s.io/client-go v12.0.0+incompatible - k8s.io/code-generator v0.28.2 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 ) @@ -43,7 +43,6 @@ require ( github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/imdario/mergo v0.3.12 // indirect @@ -58,20 +57,17 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.8.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect sigs.k8s.io/controller-runtime v0.13.0 // indirect diff --git a/v3/go.sum b/v3/go.sum new file mode 100644 index 00000000..da034688 --- /dev/null +++ b/v3/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/pkg/accesscode/accesscode.go b/v3/pkg/accesscode/accesscode.go deleted file mode 100644 index 3cd8e13d..00000000 --- a/v3/pkg/accesscode/accesscode.go +++ /dev/null @@ -1,185 +0,0 @@ -package accesscode - -import ( - "context" - "fmt" - "time" - - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/golang/glog" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" -) - -type AccessCodeClient struct { - hfClientSet hfClientset.Interface - ctx context.Context -} - -func NewAccessCodeClient(hfClientset hfClientset.Interface, ctx context.Context) (*AccessCodeClient, error) { - acc := AccessCodeClient{} - acc.hfClientSet = hfClientset - acc.ctx = ctx - return &acc, nil -} - -func (acc AccessCodeClient) GetAccessCodesWithOTACs(codes []string) ([]hfv1.AccessCode, error) { - otacReq, err := labels.NewRequirement(util2.OneTimeAccessCodeLabel, selection.In, codes) - - selector := labels.NewSelector() - selector = selector.Add(*otacReq) - - // First get the oneTimeAccessCodes - otacList, err := acc.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util2.GetReleaseNamespace()).List(acc.ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) - - if err != nil { - return nil, fmt.Errorf("error while retrieving one time access codes %v", err) - } - - //Append the value of onetime access codes to the list - for _, otac := range otacList.Items { - se, err := acc.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(acc.ctx, otac.Labels[util2.ScheduledEventLabel], metav1.GetOptions{}) - if err != nil { - return nil, fmt.Errorf("error while retrieving one time access codes %v", err) - } - if otac.Spec.MaxDuration != "" { - otac.Spec.MaxDuration, err = util2.GetDurationWithDays(otac.Spec.MaxDuration) - - maxDuration, err := time.ParseDuration(otac.Spec.MaxDuration) - if err != nil { - glog.V(4).Infof("Error parsing OTAC %s MaxDuration '%s': %s", otac.Name, otac.Spec.MaxDuration, err) - continue - } - redeemedTimestamp, err := time.Parse(time.UnixDate, otac.Spec.RedeemedTimestamp) - - if err != nil { - return nil, fmt.Errorf("error while parsing redeemedTimestamp time for OTAC %s: %v", otac.Name, err) - } - - if time.Now().After(redeemedTimestamp.Add(maxDuration)) { // if the access code is expired don't return any scenarios - glog.V(4).Infof("OTAC %s reached MaxDuration of %s", otac.Name, otac.Spec.MaxDuration) - continue - } - } - codes = append(codes, se.Spec.AccessCode) - } - - accessCodes, err := acc.GetAccessCodes(codes) - return accessCodes, err -} - -func (acc AccessCodeClient) GetAccessCodes(codes []string) ([]hfv1.AccessCode, error) { - if len(codes) == 0 { - return nil, fmt.Errorf("code list passed in was less than 0") - } - - acReq, err := labels.NewRequirement(util2.AccessCodeLabel, selection.In, codes) - - selector := labels.NewSelector() - selector = selector.Add(*acReq) - - accessCodeList, err := acc.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).List(acc.ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) - - if err != nil { - return nil, fmt.Errorf("error while retrieving access codes %v", err) - } - - var accessCodes []hfv1.AccessCode - - for _, accessCode := range accessCodeList.Items { - - if accessCode.Spec.Expiration != "" { - expiration, err := time.Parse(time.UnixDate, accessCode.Spec.Expiration) - - if err != nil { - return nil, fmt.Errorf("error while parsing expiration time for access code %s %v", accessCode.Name, err) - } - - if time.Now().After(expiration) { // if the access code is expired don't return any scenarios - glog.V(4).Infof("access code %s was expired at %s", accessCode.Name, accessCode.Spec.Expiration) - continue - } - } - - accessCodes = append(accessCodes, accessCode) - } - - return accessCodes, nil - -} - -func (acc AccessCodeClient) GetAccessCodeWithOTACs(code string) (hfv1.AccessCode, error) { - if len(code) == 0 { - return hfv1.AccessCode{}, fmt.Errorf("code was empty") - } - - accessCodes, err := acc.GetAccessCodesWithOTACs([]string{code}) - - if err != nil { - return hfv1.AccessCode{}, fmt.Errorf("access code (%s) not found: %v", code, err) - } - - if len(accessCodes) != 1 { - return hfv1.AccessCode{}, fmt.Errorf("insane result found") - } - - return accessCodes[0], nil -} - -func (acc AccessCodeClient) GetAccessCode(code string) (hfv1.AccessCode, error) { - if len(code) == 0 { - return hfv1.AccessCode{}, fmt.Errorf("code was empty") - } - - accessCodes, err := acc.GetAccessCodes([]string{code}) - - if err != nil { - return hfv1.AccessCode{}, fmt.Errorf("access code (%s) not found: %v", code, err) - } - - if len(accessCodes) != 1 { - return hfv1.AccessCode{}, fmt.Errorf("insane result found") - } - - return accessCodes[0], nil -} - -func (acc AccessCodeClient) GetScenarioIds(code string) ([]string, error) { - var ids []string - - if len(code) == 0 { - return ids, fmt.Errorf("code was empty") - } - - accessCode, err := acc.GetAccessCodeWithOTACs(code) - - if err != nil { - return ids, fmt.Errorf("error finding access code %s: %v", code, err) - } - - return accessCode.Spec.Scenarios, nil -} - -func (acc AccessCodeClient) GetCourseIds(code string) ([]string, error) { - var ids []string - - if len(code) == 0 { - return ids, fmt.Errorf("code was empty") - } - - accessCode, err := acc.GetAccessCodeWithOTACs(code) - - if err != nil { - return ids, fmt.Errorf("error finding access code %s: %v", code, err) - } - - return accessCode.Spec.Courses, nil -} diff --git a/v3/pkg/authserver/authserver.go b/v3/pkg/authserver/authserver.go deleted file mode 100644 index 7f5d66bf..00000000 --- a/v3/pkg/authserver/authserver.go +++ /dev/null @@ -1,114 +0,0 @@ -package authserver - -import ( - "context" - "encoding/json" - "net/http" - "time" - - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" -) - -type AuthServer struct { - authClient authn.AuthNClient - hfClientSet hfClientset.Interface - accessCodeClient *accesscode.AccessCodeClient - ctx context.Context -} - -func NewAuthServer(authClient authn.AuthNClient, hfClientSet hfClientset.Interface, ctx context.Context, acClient *accesscode.AccessCodeClient) (AuthServer, error) { - a := AuthServer{} - a.authClient = authClient - a.hfClientSet = hfClientSet - a.ctx = ctx - a.accessCodeClient = acClient - return a, nil -} - -func (a AuthServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/auth/scheduledevents", a.ListScheduledEventsFunc).Methods("GET") - glog.V(2).Infof("set up route") -} - -type PreparedScheduledEvent struct { - Id string `json:"id"` - Description string `json:"description"` - Name string `json:"name"` - EndDate string `json:"end_timestamp"` -} - -func (a AuthServer) ListScheduledEventsFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac.AuthenticateRequest(r, a.authClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list suitable scheduledevents") - return - } - - // This holds a map of AC -> SE - accessCodeScheduledEvent := make(map[string]PreparedScheduledEvent) - - // First we add ScheduledEvents based on OneTimeAccessCodes - otacReq, _ := labels.NewRequirement(util2.OneTimeAccessCodeLabel, selection.In, user.GetAccessCodes()) - selector := labels.NewSelector() - selector = selector.Add(*otacReq) - - otacList, err := a.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util2.GetReleaseNamespace()).List(a.ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) - - if err == nil { - for _, otac := range otacList.Items { - se, err := a.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(a.ctx, otac.Labels[util2.ScheduledEventLabel], metav1.GetOptions{}) - if err != nil { - continue - } - endTime := se.Spec.EndTime - - // If OTAC specifies a max Duration we need to calculate the EndTime correctly - if otac.Spec.MaxDuration != "" { - otacEndTime, err := time.Parse(time.UnixDate, otac.Spec.RedeemedTimestamp) - if err != nil { - continue - } - otacDurationWithDays, err := util2.GetDurationWithDays(otac.Spec.MaxDuration) - otacDuration, err := time.ParseDuration(otacDurationWithDays) - if err != nil { - continue - } - otacEndTime = otacEndTime.Add(otacDuration) - endTime = otacEndTime.Format(time.UnixDate) - } - - accessCodeScheduledEvent[otac.Name] = PreparedScheduledEvent{se.Name, se.Spec.Description, se.Spec.Name, endTime} - } - } - - // Afterwards we retreive the normal AccessCodes - accessCodes, _ := a.accessCodeClient.GetAccessCodes(user.GetAccessCodes()) - - //Getting single SEs should be faster than listing all of them and iterating them in O(n^2), in most cases users only have a hand full of accessCodes. - for _, ac := range accessCodes { - se, err := a.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(a.ctx, ac.Labels[util2.ScheduledEventLabel], metav1.GetOptions{}) - if err != nil { - glog.Error(err) - continue - } - accessCodeScheduledEvent[ac.Spec.Code] = PreparedScheduledEvent{se.Name, se.Spec.Description, se.Spec.Name, se.Spec.EndTime} - } - - encodedMap, err := json.Marshal(accessCodeScheduledEvent) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedMap) -} diff --git a/v3/pkg/controllers/scheduledevent/scheduledeventcontroller.go b/v3/pkg/controllers/scheduledevent/scheduledeventcontroller.go deleted file mode 100644 index 4a3ee04d..00000000 --- a/v3/pkg/controllers/scheduledevent/scheduledeventcontroller.go +++ /dev/null @@ -1,658 +0,0 @@ -package scheduledevent - -import ( - "context" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "math/rand" - "os" - "strings" - "time" - - "github.com/golang/glog" - "github.com/hobbyfarm/gargantua/v3/protos/setting" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "k8s.io/client-go/util/workqueue" -) - -type ScheduledEventController struct { - hfClientSet hfClientset.Interface - seWorkqueue workqueue.DelayingInterface - seSynced cache.InformerSynced - ctx context.Context - settingClient setting.SettingSvcClient -} - -var baseNameScheduledPrefix string -var baseNameDynamicPrefix string - -const ( - ScheduledEventBaseDelay = 5 * time.Millisecond - ScheduledEventMaxDelay = 300 * time.Second -) - -func init() { - bnsp := os.Getenv("HF_BASENAME_SCHEDULED_PREFIX") - if bnsp == "" { - baseNameScheduledPrefix = "scheduled" - } else { - baseNameScheduledPrefix = bnsp - } - - bndp := os.Getenv("HF_BASENAME_DYNAMIC_PREFIX") - if bndp == "" { - baseNameDynamicPrefix = "dynamic" - } else { - baseNameDynamicPrefix = bndp - } -} - -func NewScheduledEventController(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context, settingClient setting.SettingSvcClient) (*ScheduledEventController, error) { - seController := ScheduledEventController{} - seController.ctx = ctx - seController.hfClientSet = hfClientSet - seController.settingClient = settingClient - seController.seSynced = hfInformerFactory.Hobbyfarm().V1().ScheduledEvents().Informer().HasSynced - - //seController.seWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "ScheduledEvent") - seController.seWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(ScheduledEventBaseDelay, ScheduledEventMaxDelay), "sec-se") - seInformer := hfInformerFactory.Hobbyfarm().V1().ScheduledEvents().Informer() - - seInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: seController.enqueueSE, - UpdateFunc: func(old, new interface{}) { - seController.enqueueSE(new) - }, - DeleteFunc: seController.enqueueSE, - }, time.Minute*30) - - return &seController, nil -} - -func (s *ScheduledEventController) enqueueSE(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - //utilruntime.HandleError(err) - return - } - glog.V(8).Infof("Enqueueing se %s", key) - //s.seWorkqueue.AddRateLimited(key) - s.seWorkqueue.Add(key) -} - -func (s *ScheduledEventController) Run(stopCh <-chan struct{}) error { - defer s.seWorkqueue.ShutDown() - - glog.V(4).Infof("Starting Scheduled Event controller") - glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, s.seSynced); !ok { - return fmt.Errorf("failed to wait for vm, vmc, and ss caches to sync") - } - glog.Info("Starting se controller workers") - go wait.Until(s.runSEWorker, time.Second, stopCh) - glog.Info("Started se controller workers") - //if ok := cache.WaitForCacheSync(stopCh, ) - <-stopCh - return nil -} - -func (s *ScheduledEventController) runSEWorker() { - glog.V(6).Infof("Starting scheduled event worker") - for s.processNextScheduledEvent() { - - } -} - -func (s *ScheduledEventController) processNextScheduledEvent() bool { - obj, shutdown := s.seWorkqueue.Get() - - if shutdown { - return false - } - - err := func() error { - defer s.seWorkqueue.Done(obj) - glog.V(8).Infof("processing se in se controller: %v", obj) - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) - if err != nil { - glog.Errorf("error while splitting meta namespace key %v", err) - return nil - } - - err = s.reconcileScheduledEvent(objName) - if err != nil { - if !apierrors.IsNotFound(err) { - glog.Error(err) - s.seWorkqueue.Add(objName) - } - } - //s.seWorkqueue.Forget(obj) - glog.V(8).Infof("se processed by scheduled event controller %v", objName) - - return nil - - }() - - if err != nil { - return true - } - - return true -} - -func (s ScheduledEventController) completeScheduledEvent(se *hfv1.ScheduledEvent) error { - glog.V(6).Infof("ScheduledEvent %s is done, deleting corresponding VMSets and marking as finished", se.Name) - // scheduled event is finished, we need to set the scheduled event to finished and delete the vm's - - err := s.deleteVMSetsFromScheduledEvent(se) - - if err != nil { - return err - } - - err = s.finishSessionsFromScheduledEvent(se) - - if err != nil { - return err - } - - // update the scheduled event and set the various flags accordingly (provisioned, ready, finished) - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - seToUpdate, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, se.Name, metav1.GetOptions{}) - - if err != nil { - return err - } - - seToUpdate.Status.Provisioned = true - seToUpdate.Status.Ready = false - seToUpdate.Status.Finished = true - - _, updateErr := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, seToUpdate, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for scheduled event") - - return updateErr - }) - - if retryErr != nil { - return retryErr - } - - return nil // break (return) here because we're done with this SE. -} - -func (s ScheduledEventController) deleteScheduledEvent(se *hfv1.ScheduledEvent) error { - glog.V(6).Infof("ScheduledEvent %s is done and retention time is over, deleting SE finally", se.Name) - - if !se.Status.Finished { - return fmt.Errorf("error attempting to delete SE that is not finished") - } - - // Delete Progress - err := s.deleteProgressFromScheduledEvent(se) - if err != nil { - return err - } - - err = s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Delete(s.ctx, se.Name, metav1.DeleteOptions{}) - - if err != nil { - return err - } - return nil // break (return) here because we're done with this SE. -} - -func (s ScheduledEventController) deleteVMSetsFromScheduledEvent(se *hfv1.ScheduledEvent) error { - // for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset - err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventController) deleteProgressFromScheduledEvent(se *hfv1.ScheduledEvent) error { - // for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset - err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventController) deleteAccessCode(se *hfv1.ScheduledEvent) error { - // delete the access code for the corresponding ScheduledEvent - err := s.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventController) finishSessionsFromScheduledEvent(se *hfv1.ScheduledEvent) error { - // get a list of sessions for the user - sessionList, err := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.AccessCodeLabel, se.Spec.AccessCode), - }) - - now := time.Now().Format(time.UnixDate) - - for _, session := range sessionList.Items { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(s.ctx, session.Name, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", session.Name, getErr) - } - - result.Status.ExpirationTime = now - result.Status.Active = false - - _, updateErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for session") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error updating session %v", err) - return fmt.Errorf("error attempting to update") - } - } - return nil -} - -func (s ScheduledEventController) provisionScheduledEvent(templates *hfv1.VirtualMachineTemplateList, se *hfv1.ScheduledEvent) error { - glog.V(6).Infof("ScheduledEvent %s is ready to be provisioned", se.Name) - // start creating resources related to this - vmSets := []string{} - - /** - The general flow here is to calculate how much resources (cpu, mem, storage) are currently - being used, and then compare that to what is needed. If needed > used, we're going to still - provision (for some reason), but at least we'll tell the user about it - e.g. --> glog.Errorf("we are overprovisioning this environment %s by CPU... - */ - - // begin by calculating what is currently being used in the environment - for envName, vmtMap := range se.Spec.RequiredVirtualMachines { - // get the environment we're provisioning into (envName) - env, err := s.hfClientSet.HobbyfarmV1().Environments(util2.GetReleaseNamespace()).Get(s.ctx, envName, metav1.GetOptions{}) - if err != nil { - glog.Errorf("error retreiving environment %s", err.Error()) - return err - } - - // TODO: actually check for capacity usage - - // create virtualmachinesets if not on demand - if !se.Spec.OnDemand { - for templateName, count := range vmtMap { - if count > 0 { // only setup vmsets if >0 VMs are requested, and they aren't ondemand - //1. Find existing VMset that match this SE and the current environment - existingVMSets, err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,%s=%s,virtualmachinetemplate.hobbyfarm.io/%s=true", util2.ScheduledEventLabel, se.Name, util2.EnvironmentLabel, envName, templateName), - }) - - if err != nil || len(existingVMSets.Items) == 0 { // create new vmset if no existing one was found - vmsRand := fmt.Sprintf("%s-%08x", baseNameScheduledPrefix, rand.Uint32()) - vmsName := strings.Join([]string{"se", se.Name, "vms", vmsRand}, "-") - vmSets = append(vmSets, vmsName) - vms := &hfv1.VirtualMachineSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: vmsName, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "ScheduledEvent", - Name: se.Name, - UID: se.UID, - }, - }, - Labels: map[string]string{ - util2.EnvironmentLabel: env.Name, - util2.ScheduledEventLabel: se.Name, - fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s", templateName): "true", - }, - }, - Spec: hfv1.VirtualMachineSetSpec{ - Count: count, - Environment: envName, - VMTemplate: templateName, - BaseName: vmsRand, - }, - } - if se.Spec.RestrictedBind { - vms.Spec.RestrictedBind = true - vms.Spec.RestrictedBindValue = se.Spec.RestrictedBindValue - } else { - vms.Spec.RestrictedBind = false - } - _, err = s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).Create(s.ctx, vms, metav1.CreateOptions{}) - if err != nil { - glog.Error(err) - return err - } - } else { // update existing vmset - // Todo support multiple VM Sets - existingVMSet := existingVMSets.Items[0] - vmSets = append(vmSets, existingVMSet.Name) - - existingVMSet.Labels[util2.EnvironmentLabel] = env.Name - existingVMSet.Spec.Count = count - if se.Spec.RestrictedBind { - existingVMSet.Spec.RestrictedBind = true - } else { - existingVMSet.Spec.RestrictedBind = false - } - _, err = s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).Update(s.ctx, &existingVMSet, metav1.UpdateOptions{}) - if err != nil { - glog.Errorf("error updating vmset config %s", err.Error()) - return err - } - } - } - } - } - - // Delete existing DynamicBindConfigurations - err = s.hfClientSet.HobbyfarmV1().DynamicBindConfigurations(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,environment=%s", util2.ScheduledEventLabel, se.Name, env.Name), - }) - if err != nil { - return err - } - - // create the dynamic bind configurations - dbcRand := fmt.Sprintf("%s-%08x", baseNameDynamicPrefix, rand.Uint32()) - dbcName := strings.Join([]string{"se", se.Name, "dbc", dbcRand}, "-") - - dbc := &hfv1.DynamicBindConfiguration{ - ObjectMeta: metav1.ObjectMeta{ - Name: dbcName, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "ScheduledEvent", - Name: se.Name, - UID: se.UID, - }, - }, - Labels: map[string]string{ - util2.EnvironmentLabel: env.Name, - util2.ScheduledEventLabel: se.Name, - }, - }, - Spec: hfv1.DynamicBindConfigurationSpec{ - Environment: envName, - BaseName: dbcRand, - BurstCountCapacity: vmtMap, - }, - } - - if se.Spec.RestrictedBind { - dbc.Spec.RestrictedBind = true - dbc.Spec.RestrictedBindValue = se.Spec.RestrictedBindValue - dbc.ObjectMeta.Labels["restrictedbind"] = "true" - dbc.ObjectMeta.Labels["restrictedbindvalue"] = se.Spec.RestrictedBindValue - } else { - dbc.ObjectMeta.Labels["restrictedbind"] = "false" - } - - _, err = s.hfClientSet.HobbyfarmV1().DynamicBindConfigurations(util2.GetReleaseNamespace()).Create(s.ctx, dbc, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating dynamic bind configuration %v", err) - } - } - - // Delete AccessCode if it exists - _, err := s.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).Get(s.ctx, se.Spec.AccessCode, metav1.GetOptions{}) - if err == nil { - err = s.deleteAccessCode(se) - if err != nil { - return err - } - } - - err = s.createAccessCode(se) - if err != nil { - return err - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - - seToUpdate, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, se.Name, metav1.GetOptions{}) - - if err != nil { - return err - } - - seToUpdate.Status.Provisioned = true - seToUpdate.Status.VirtualMachineSets = vmSets - seToUpdate.Status.Ready = false - seToUpdate.Status.Finished = false - - _, updateErr := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, seToUpdate, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for scheduled event") - - return updateErr - }) - if retryErr != nil { - return retryErr - } - - return nil -} - -func (s ScheduledEventController) createAccessCode(se *hfv1.ScheduledEvent) error { - ac := &hfv1.AccessCode{ - ObjectMeta: metav1.ObjectMeta{ - Name: se.Spec.AccessCode, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "ScheduledEvent", - Name: se.Name, - UID: se.UID, - }, - }, - Labels: map[string]string{ - util2.ScheduledEventLabel: se.Name, - util2.AccessCodeLabel: se.Spec.AccessCode, - }, - }, - Spec: hfv1.AccessCodeSpec{ - Code: se.Spec.AccessCode, - Description: "Generated by ScheduledEventController", - Scenarios: se.Spec.Scenarios, - Courses: se.Spec.Courses, - Expiration: se.Spec.EndTime, - }, - } - - if se.Spec.RestrictedBind { - ac.Spec.RestrictedBind = true - ac.Spec.RestrictedBindValue = se.Spec.RestrictedBindValue - } else { - ac.Spec.RestrictedBind = false - } - - if se.Spec.Printable { - ac.Spec.Printable = true - } else { - ac.Spec.Printable = false - } - - ac, err := s.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).Create(s.ctx, ac, metav1.CreateOptions{}) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventController) verifyScheduledEvent(se *hfv1.ScheduledEvent) error { - // check the state of the vmset and mark the sevent as ready if everything is OK - glog.V(6).Infof("ScheduledEvent %s is in provisioned status, checking status of VMSet Provisioning", se.Name) - vmsList, err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - for _, vms := range vmsList.Items { - if vms.Status.ProvisionedCount < vms.Spec.Count { - return fmt.Errorf("scheduled event is not ready yet") - } - } - - // Validate AccessCode existence and has label set - ac, err := s.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).Get(s.ctx, se.Spec.AccessCode, metav1.GetOptions{}) - if err != nil { - err = s.createAccessCode(se) - - if err != nil { - return err - } - - } else if ac.Labels[util2.AccessCodeLabel] != ac.Spec.Code { - err = s.deleteAccessCode(se) - if err != nil { - return err - } - - err = s.createAccessCode(se) - - if err != nil { - return err - } - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - - seToUpdate, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, se.Name, metav1.GetOptions{}) - - if err != nil { - return err - } - - if seToUpdate.Status.Provisioned == false || seToUpdate.Status.Finished == true { - return fmt.Errorf("scheduled event is not provisioned. Maybe changed recently") - } - - seToUpdate.Status.Provisioned = true - seToUpdate.Status.Ready = true - seToUpdate.Status.Finished = false - - _, updateErr := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, seToUpdate, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for scheduled event") - - return updateErr - }) - if retryErr != nil { - return retryErr - } - - return nil -} - -func (s *ScheduledEventController) reconcileScheduledEvent(seName string) error { - glog.V(4).Infof("reconciling scheduled event %s", seName) - - // fetch the scheduled event - se, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, seName, metav1.GetOptions{}) - if err != nil { - return err - } - - // fetch the list of virtual machine templates - templates, err := s.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - if err != nil { - return err - } - now := time.Now() - - beginTime, err := time.Parse(time.UnixDate, se.Spec.StartTime) - if err != nil { - return err - } - endTime, err := time.Parse(time.UnixDate, se.Spec.EndTime) - - if err != nil { - return err - } - - // this means that the scheduled event has ended (endtime.Before(now)), but the status of the event is not finished - // and it is still marked as active. this means we need to finish and deactivate the SE. - if endTime.Before(now) && !se.Status.Finished && se.Status.Active { - return s.completeScheduledEvent(se) - } - - // if this scheduled event has begun (beginTime.Before(now)), and we haven't already provisioned - // this SE, let's do so - if beginTime.Before(now) && !se.Status.Provisioned && se.Status.Active { - return s.provisionScheduledEvent(templates, se) - } - - // the SE is ongoing and we should just verify things are good - if beginTime.Before(now) && se.Status.Provisioned && !se.Status.Finished && se.Status.Active { - return s.verifyScheduledEvent(se) - } - - if endTime.Before(now) && se.Status.Finished { - // scheduled event is finished and nothing to do - setting, err := s.settingClient.GetSettingValue(s.ctx, &settingProto.Id{Name: string(settingUtil.ScheduledEventRetentionTime)}) - - if set, ok := setting.GetValue().(*settingProto.SettingValue_Int64Value); err != nil || !ok || setting == nil { - return fmt.Errorf("error retreiving retention Time setting") - } else { - retentionTime := endTime.Add(time.Hour * time.Duration(set.Int64Value)) - if retentionTime.Before(now) { - // Really finish the ScheduledEvent - return s.deleteScheduledEvent(se) - } - } - } - - // The ScheduledEvent is set to OnDemand but still has VMSets - if se.Spec.OnDemand && len(se.Status.VirtualMachineSets) > 0 { - vmSets := []string{} - se.Status.VirtualMachineSets = vmSets - _, updateErr := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, se, metav1.UpdateOptions{}) - s.deleteVMSetsFromScheduledEvent(se) - return updateErr - } - - return nil -} - -func calculateUsedCapacity(env *hfv1.Environment, vmsList *hfv1.VirtualMachineSetList, templates *hfv1.VirtualMachineTemplateList) map[string]int { - usedCount := map[string]int{} - for _, vms := range vmsList.Items { - for _, t := range templates.Items { - if t.Name == vms.Spec.VMTemplate { - usedCount[t.Name] = usedCount[t.Name] + vms.Spec.Count - } - } - } - return usedCount -} diff --git a/v3/pkg/controllers/session/sessioncontroller.go b/v3/pkg/controllers/session/sessioncontroller.go deleted file mode 100644 index 68c5acf5..00000000 --- a/v3/pkg/controllers/session/sessioncontroller.go +++ /dev/null @@ -1,332 +0,0 @@ -package session - -import ( - "context" - "fmt" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "time" - - "github.com/golang/glog" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "k8s.io/client-go/util/workqueue" -) - -const ( - SessionExpireTime = time.Hour * 3 -) - -type SessionController struct { - hfClientSet hfClientset.Interface - - //ssWorkqueue workqueue.RateLimitingInterface - ssWorkqueue workqueue.DelayingInterface - - vmLister v1.VirtualMachineLister - vmcLister v1.VirtualMachineClaimLister - ssLister v1.SessionLister - - vmSynced cache.InformerSynced - vmcSynced cache.InformerSynced - ssSynced cache.InformerSynced - ctx context.Context -} - -func NewSessionController(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*SessionController, error) { - ssController := SessionController{} - ssController.ctx = ctx - ssController.hfClientSet = hfClientSet - ssController.vmSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced - ssController.vmcSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer().HasSynced - ssController.ssSynced = hfInformerFactory.Hobbyfarm().V1().Sessions().Informer().HasSynced - - //ssController.ssWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Session") - ssController.ssWorkqueue = workqueue.NewNamedDelayingQueue("ssc-ss") - ssController.vmLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Lister() - ssController.vmcLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Lister() - ssController.ssLister = hfInformerFactory.Hobbyfarm().V1().Sessions().Lister() - - ssInformer := hfInformerFactory.Hobbyfarm().V1().Sessions().Informer() - - ssInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: ssController.enqueueSS, - UpdateFunc: func(old, new interface{}) { - ssController.enqueueSS(new) - }, - DeleteFunc: ssController.enqueueSS, - }, time.Minute*30) - - return &ssController, nil -} - -func (s *SessionController) enqueueSS(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - //utilruntime.HandleError(err) - return - } - glog.V(8).Infof("Enqueueing ss %s", key) - //s.ssWorkqueue.AddRateLimited(key) - s.ssWorkqueue.Add(key) -} - -func (s *SessionController) Run(stopCh <-chan struct{}) error { - defer s.ssWorkqueue.ShutDown() - - glog.V(4).Infof("Starting Session controller") - glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, s.vmSynced, s.vmcSynced, s.ssSynced); !ok { - return fmt.Errorf("failed to wait for vm, vmc, and ss caches to sync") - } - glog.Info("Starting ss controller workers") - go wait.Until(s.runSSWorker, time.Second, stopCh) - glog.Info("Started ss controller workers") - //if ok := cache.WaitForCacheSync(stopCh, ) - <-stopCh - return nil -} - -func (s *SessionController) runSSWorker() { - glog.V(6).Infof("Starting session worker") - for s.processNextSession() { - - } -} - -func (s *SessionController) processNextSession() bool { - obj, shutdown := s.ssWorkqueue.Get() - - if shutdown { - return false - } - - err := func() error { - defer s.ssWorkqueue.Done(obj) - glog.V(8).Infof("processing ss in ss controller: %v", obj) - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) - if err != nil { - glog.Errorf("error while splitting meta namespace key %v", err) - return nil - } - - err = s.reconcileSession(objName) - - if err != nil { - glog.Error(err) - } - //s.ssWorkqueue.Forget(obj) - glog.V(8).Infof("ss processed by session controller %v", objName) - - return nil - - }() - - if err != nil { - return true - } - - return true -} - -func (s *SessionController) reconcileSession(ssName string) error { - glog.V(4).Infof("reconciling session %s", ssName) - - ss, err := s.ssLister.Sessions(util2.GetReleaseNamespace()).Get(ssName) - - if err != nil { - return err - } - - now := time.Now() - - expires, err := time.Parse(time.UnixDate, ss.Status.ExpirationTime) - - if err != nil { - return err - } - - timeUntilExpires := expires.Sub(now) - - // clean up sessions if they are finished - if ss.Status.Finished { - glog.V(6).Infof("deleted finished session %s", ss.Name) - - // now that the vmclaims are deleted, go ahead and delete the session - err = s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Delete(s.ctx, ss.Name, metav1.DeleteOptions{}) - - if err != nil { - return fmt.Errorf("error deleting session %s: %s", ss.Name, err) - } - - glog.V(6).Infof("deleted old session %s", ss.Name) - - s.FinishProgress(ss.Name, ss.Spec.UserId) - - return nil - } - - if expires.Before(now) && !ss.Status.Finished { - // we need to set the session to finished and delete the vm's - if ss.Status.Active && ss.Status.Paused && ss.Status.PausedTime != "" { - pausedExpiration, err := time.Parse(time.UnixDate, ss.Status.PausedTime) - if err != nil { - glog.Error(err) - } - - if pausedExpiration.After(now) { - glog.V(4).Infof("Session %s was paused, and the pause expiration is after now, skipping clean up.", ss.Name) - return nil - } - - glog.V(4).Infof("Session %s was paused, but the pause expiration was before now, so cleaning up.", ss.Name) - } - for _, vmc := range ss.Spec.VmClaimSet { - vmcObj, err := s.vmcLister.VirtualMachineClaims(util2.GetReleaseNamespace()).Get(vmc) - - if err != nil { - break - } - - for _, vm := range vmcObj.Spec.VirtualMachines { - if len(vm.VirtualMachineId) == 0 { - // VM was not even provisioned / assigned yet. - continue - } - taintErr := s.taintVM(vm.VirtualMachineId) - if taintErr != nil { - glog.Error(taintErr) - } - } - - taintErr := s.taintVMC(vmcObj.Name) - if taintErr != nil { - glog.Error(taintErr) - } - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(s.ctx, ssName, metav1.GetOptions{}) - if getErr != nil { - return getErr - } - - result.Status.Finished = true - result.Status.Active = false - - result, updateErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - glog.V(4).Infof("updated result for ss") - - verifyErr := util2.VerifySession(s.ssLister, result) - - if verifyErr != nil { - return verifyErr - } - return nil - }) - if retryErr != nil { - return retryErr - } - } else if expires.Before(now) && ss.Status.Finished { - glog.V(8).Infof("session %s is finished and expired before now", ssName) - } else { - glog.V(8).Infof("adding session %s to workqueue after %s", ssName, timeUntilExpires.String()) - s.ssWorkqueue.AddAfter(ssName, timeUntilExpires) - glog.V(8).Infof("added session %s to workqueue", ssName) - } - - return nil -} - -func (s *SessionController) taintVM(vmName string) error { - glog.V(5).Infof("tainting VM %s", vmName) - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := s.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(s.ctx, vmName, metav1.GetOptions{}) - if getErr != nil { - return getErr - } - result.Status.Tainted = true - - result, updateErr := s.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - glog.V(4).Infof("updated result for vm") - - verifyErr := util2.VerifyVM(s.vmLister, result) - - if verifyErr != nil { - return verifyErr - } - return nil - }) - if retryErr != nil { - return retryErr - } - - return nil -} - -func (s *SessionController) taintVMC(vmcName string) error { - glog.V(5).Infof("tainting VMC %s", vmcName) - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := s.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Get(s.ctx, vmcName, metav1.GetOptions{}) - if getErr != nil { - return getErr - } - result.Status.Tainted = true - - result, updateErr := s.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - verifyErr := util2.VerifyVMClaim(s.vmcLister, result) - if verifyErr != nil { - return verifyErr - } - glog.V(4).Infof("updated result for vmc") - return nil - }) - if retryErr != nil { - return retryErr - } - - return nil -} - -func (s *SessionController) FinishProgress(sessionId string, userId string) { - now := time.Now() - - progress, err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,%s=%s,finished=false", util2.SessionLabel, sessionId, util2.UserLabel, userId)}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - return - } - - for _, p := range progress.Items { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - p.Labels["finished"] = "true" - p.Spec.LastUpdate = now.Format(time.UnixDate) - p.Spec.Finished = "true" - - _, updateErr := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).Update(s.ctx, &p, metav1.UpdateOptions{}) - glog.V(4).Infof("updated progress with ID %s", p.Name) - - return updateErr - }) - if retryErr != nil { - glog.Errorf("error finishing progress %v", err) - return - } - } -} diff --git a/v3/pkg/controllers/tfpcontroller/tfpcontroller.go b/v3/pkg/controllers/tfpcontroller/tfpcontroller.go deleted file mode 100644 index b035c6ba..00000000 --- a/v3/pkg/controllers/tfpcontroller/tfpcontroller.go +++ /dev/null @@ -1,537 +0,0 @@ -package tfpcontroller - -import ( - "context" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - tfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/terraformcontroller.cattle.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - v12 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" - "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/terraformcontroller.cattle.io/v1" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - "math/rand" - "reflect" - "strings" - "time" - - "github.com/golang/glog" - k8sv1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" - k8s "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "k8s.io/client-go/util/workqueue" -) - -type TerraformProvisionerController struct { - hfClientSet hfClientset.Interface - //vmWorkqueue workqueue.RateLimitingInterface - - vmWorkqueue workqueue.Interface - - k8sClientset k8s.Interface - - tfClientset hfClientset.Interface - - vmLister v12.VirtualMachineLister - envLister v12.EnvironmentLister - vmtLister v12.VirtualMachineTemplateLister - - tfsLister v1.StateLister - tfeLister v1.ExecutionLister - - vmSynced cache.InformerSynced - vmtSynced cache.InformerSynced - tfsSynced cache.InformerSynced - tfeSynced cache.InformerSynced - envSynced cache.InformerSynced - ctx context.Context -} - -func NewTerraformProvisionerController(k8sClientSet k8s.Interface, hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*TerraformProvisionerController, error) { - tfpController := TerraformProvisionerController{} - tfpController.hfClientSet = hfClientSet - - tfpController.tfClientset = hfClientSet - tfpController.k8sClientset = k8sClientSet - - //tfpController.vmWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "VM") - - tfpController.vmWorkqueue = workqueue.New() - - tfpController.vmLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Lister() - tfpController.vmSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced - - tfpController.envLister = hfInformerFactory.Hobbyfarm().V1().Environments().Lister() - tfpController.envSynced = hfInformerFactory.Hobbyfarm().V1().Environments().Informer().HasSynced - - tfpController.vmtLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Lister() - tfpController.vmtSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Informer().HasSynced - - tfpController.tfsLister = hfInformerFactory.Terraformcontroller().V1().States().Lister() - tfpController.tfsSynced = hfInformerFactory.Terraformcontroller().V1().States().Informer().HasSynced - - tfpController.tfeLister = hfInformerFactory.Terraformcontroller().V1().Executions().Lister() - tfpController.tfeSynced = hfInformerFactory.Terraformcontroller().V1().Executions().Informer().HasSynced - - vmInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() - - vmInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: tfpController.enqueueVM, - UpdateFunc: func(old, new interface{}) { - tfpController.enqueueVM(new) - }, - DeleteFunc: tfpController.enqueueVM, - }, time.Minute*30) - - tfpController.ctx = ctx - - return &tfpController, nil -} - -func (t *TerraformProvisionerController) enqueueVM(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - //utilruntime.HandleError(err) - return - } - glog.V(8).Infof("Enqueueing vm %s", key) - //t.vmWorkqueue.AddRateLimited(key) - t.vmWorkqueue.Add(key) -} - -func (t *TerraformProvisionerController) Run(stopCh <-chan struct{}) error { - defer t.vmWorkqueue.ShutDown() - - glog.V(4).Infof("Starting Terraform Provisioner controller") - glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, t.vmSynced, t.envSynced, t.vmtSynced, t.tfsSynced, t.tfeSynced); !ok { - return fmt.Errorf("failed to wait for caches to sync") - } - glog.Info("Starting TFP controller worker") - go wait.Until(t.runTFPWorker, time.Second, stopCh) - glog.Info("Started TFP controller worker") - <-stopCh - return nil -} - -func (t *TerraformProvisionerController) runTFPWorker() { - for t.processNextVM() { - - } -} - -func (t *TerraformProvisionerController) processNextVM() bool { - obj, shutdown := t.vmWorkqueue.Get() - - if shutdown { - return false - } - err := func() error { - defer t.vmWorkqueue.Done(obj) - //glog.V(8).Infof("processing vm in tfp controller: %v", obj) - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) // this is actually not necessary because VM's are not namespaced yet... - if err != nil { - glog.Errorf("error while splitting meta namespace key %v", err) - return nil - } - - vm, err := t.vmLister.VirtualMachines(util.GetReleaseNamespace()).Get(objName) - if err != nil { - glog.Errorf("error while retrieving virtual machine %s, likely deleted, forgetting in queue %v", objName, err) - //t.vmWorkqueue.Forget(obj) - return nil - } - - err, requeue := t.handleProvision(vm) - - if err != nil { - glog.Error(err) - } - - if requeue { - t.vmWorkqueue.Add(obj) - } - - //glog.V(4).Infof("vm processed by tfp controller %v", objName) - return nil - - }() - - if err != nil { - return true - } - - return true -} - -// returns an error and a boolean of requeue -func (t *TerraformProvisionerController) handleProvision(vm *hfv1.VirtualMachine) (error, bool) { - // VM shall not be provisioned by internal terraform controller - if !vm.Spec.Provision { - if prov, ok := vm.ObjectMeta.Labels["hobbyfarm.io/provisioner"]; ok && prov != "" { - glog.V(8).Infof("vm %s ignored by internal provisioner due to 3rd party provisioning label", vm.Name) - t.vmWorkqueue.Done(vm.Name) - } - glog.V(8).Infof("vm %s was not a provisioned vm", vm.Name) - return nil, false - } - - //glog.V(5).Infof("vm spec was to provision %s", vm.Name) - if vm.Status.Tainted && vm.DeletionTimestamp == nil { - util.EnsureVMNotReady(t.hfClientSet, t.vmLister, vm.Name, t.ctx) - deleteVMErr := t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).Delete(t.ctx, vm.Name, metav1.DeleteOptions{}) - if deleteVMErr != nil { - return fmt.Errorf("there was an error while deleting the virtual machine %s", vm.Name), true - } - t.vmWorkqueue.Add(vm.Name) - return nil, false - } - if vm.DeletionTimestamp != nil { - //glog.V(5).Infof("destroying virtual machine") - util.EnsureVMNotReady(t.hfClientSet, t.vmLister, vm.Name, t.ctx) - if vm.Status.TFState == "" { - // vm already deleted let's delete our finalizer - t.removeFinalizer(vm) - } - stateDel := t.tfClientset.TerraformcontrollerV1().States(util.GetReleaseNamespace()).Delete(t.ctx, vm.Status.TFState, metav1.DeleteOptions{}) - if stateDel != nil { - t.removeFinalizer(vm) - } else { - return nil, true // no error, but need to requeue - } - return nil, false - } - //Status is ReadyForProvisioning AND No Secret provided (Do not provision VM twice, happens due to vm.status being updated after vm.status) - if vm.Status.Status == hfv1.VmStatusRFP { - vmt, err := t.vmtLister.VirtualMachineTemplates(util.GetReleaseNamespace()).Get(vm.Spec.VirtualMachineTemplateId) - if err != nil { - glog.Errorf("error getting vmt %v", err) - return err, true - } - env, err := t.envLister.Environments(util.GetReleaseNamespace()).Get(vm.Status.EnvironmentId) - if err != nil { - glog.Errorf("error getting env %v", err) - return err, true - } - - _, exists := env.Spec.TemplateMapping[vmt.Name] - if !exists { - glog.Errorf("error pulling environment template info %v", err) - return fmt.Errorf("Error during RFP: environment %s does not support vmt %s.", env.Name, vmt.Name), true - } - - // let's provision the vm - pubKey, privKey, err := util.GenKeyPair() - if err != nil { - glog.Errorf("error generating keypair %v", err) - return err, true - } - config := util.GetVMConfig(env, vmt) - - config["name"] = vm.Name - config["public_key"] = pubKey - - image, exists := config["image"] - if !exists || image == "" { - return fmt.Errorf("image does not exist or is empty in vm config for vmt %s", vmt.Name), true - } - - moduleName, exists := config["module"] - if !exists || moduleName == "" { - return fmt.Errorf("module name does not exist or is empty in vm config for vmt %s", vmt.Name), true - } - - executorImage, exists := config["executor_image"] - if !exists || executorImage == "" { - return fmt.Errorf("executorimage does not exist or is empty in vm config for vmt %s", vmt.Name), true - } - - password, exists := config["password"] - if !exists { - password = "" - } - - r := fmt.Sprintf("%08x", rand.Uint32()) - cm := &k8sv1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: strings.Join([]string{vm.Name + "-cm", r}, "-"), - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "VirtualMachine", - Name: vm.Name, - UID: vm.UID, - }, - }, - }, - Data: config, - } - - cm, err = t.k8sClientset.CoreV1().ConfigMaps(util.GetReleaseNamespace()).Create(t.ctx, cm, metav1.CreateOptions{}) - - if err != nil { - glog.Errorf("error creating configmap %s: %v", cm.Name, err) - } - - keypair := &k8sv1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: strings.Join([]string{vm.Name + "-secret", r}, "-"), - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "VirtualMachine", - Name: vm.Name, - UID: vm.UID, - }, - }, - }, - Data: map[string][]byte{ - "private_key": []byte(privKey), - "public_key": []byte(pubKey), - "password": []byte(password), - }, - } - - keypair, err = t.k8sClientset.CoreV1().Secrets(util.GetReleaseNamespace()).Create(t.ctx, keypair, metav1.CreateOptions{}) - - if err != nil { - glog.Errorf("error creating secret %s: %v", keypair.Name, err) - } - - tfs := &tfv1.State{ - ObjectMeta: metav1.ObjectMeta{ - Name: strings.Join([]string{vm.Name + "-tfs", r}, "-"), - }, - Spec: tfv1.StateSpec{ - Variables: tfv1.Variables{ - ConfigNames: []string{cm.Name}, - }, - Image: executorImage, - AutoConfirm: true, - DestroyOnDelete: true, - ModuleName: moduleName, - }, - } - - credentialsSecret, exists := config["cred_secret"] - if !exists { - glog.Errorf("cred secret does not exist in env template") - } - if credentialsSecret != "" { - tfs.Spec.Variables.SecretNames = []string{credentialsSecret} - } - - tfs, err = t.tfClientset.TerraformcontrollerV1().States(util.GetReleaseNamespace()).Create(t.ctx, tfs, metav1.CreateOptions{}) - - if err != nil { - glog.Errorf("error creating tfs %v", err) - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - toUpdate, err := t.vmLister.VirtualMachines(util.GetReleaseNamespace()).Get(vm.Name) - if err != nil { - if apierrors.IsNotFound(err) { - return nil - } else { - glog.Errorf("unknown error encountered when setting terminating %v", err) - } - } - - toUpdate.Status.Status = hfv1.VmStatusProvisioned - toUpdate.Status.TFState = tfs.Name - - toUpdate, updateErr := t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).UpdateStatus(t.ctx, toUpdate, metav1.UpdateOptions{}) - - if updateErr != nil { - glog.Errorf("error while updating VirtualMachine status %s", toUpdate.Name) - return updateErr - } - - toUpdate.Spec.SecretName = keypair.Name - toUpdate.Labels["ready"] = "false" - toUpdate.Finalizers = []string{"tfp.controllers.hobbyfarm.io"} - - toUpdate, updateErr = t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).Update(t.ctx, toUpdate, metav1.UpdateOptions{}) - - if updateErr != nil { - glog.Errorf("error while updating VirtualMachine %s", toUpdate.Name) - return updateErr - } - - if err := util.VerifyVM(t.vmLister, toUpdate); err != nil { - glog.Errorf("error while verifying machine %s", toUpdate.Name) - } - return updateErr - }) - - if retryErr != nil { - return retryErr, true - } - glog.V(6).Infof("provisioned vm %s", vm.Name) - return nil, false - - } else if vm.Status.Status == hfv1.VmStatusProvisioned { - // let's check the status of our tf provision - /*tfState, err := t.tfsLister.States(util.GetReleaseNamespace()).Get(vm.Status.TFState) - if err != nil { - if apierrors.IsNotFound(err) { - return fmt.Errorf("execution not found") - } - return nil - } */ - // TEMPORARY WORKAROUND UNTIL WE FIGURE OUT A BETTER WAY TO DO THIS - - if vm.Status.TFState == "" { - return fmt.Errorf("tf state was blank in object"), true - } - - tfExecs, err := t.tfeLister.List(labels.Set{ - "state": string(vm.Status.TFState), - }.AsSelector()) - - if err != nil { - return err, true - } - - var newestTimestamp *metav1.Time - var tfExec *tfv1.Execution - if len(tfExecs) == 0 { - return fmt.Errorf("no executions found for terraform state"), true - } - - newestTimestamp = &tfExecs[0].CreationTimestamp - tfExec = tfExecs[0] - for _, e := range tfExecs { - if newestTimestamp.Before(&e.CreationTimestamp) { - newestTimestamp = &e.CreationTimestamp - tfExec = e - } - } - // END TEMPORARY WORKAROUND - - //executionName := tfState.Status.ExecutionName - /* - tfExec, err := t.tfeLister.Executions(util.GetReleaseNamespace()).Get(executionName) - if err != nil { - //glog.Error(err) - if apierrors.IsNotFound(err) { - return fmt.Errorf("execution not found") - } - return nil - } - */ - if tfExec.Status.Outputs == "" { - return nil, true - } - - var tfOutput map[string]map[string]string - - err = json.Unmarshal([]byte(tfExec.Status.Outputs), &tfOutput) - if err != nil { - glog.Error(err) - } - env, err := t.envLister.Environments(util.GetReleaseNamespace()).Get(vm.Status.EnvironmentId) - if err != nil { - glog.Error(err) - return fmt.Errorf("error getting environment"), true - } - glog.V(8).Infof("private ip is: %s", tfOutput["private_ip"]["value"]) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - toUpdate, err := t.vmLister.VirtualMachines(util.GetReleaseNamespace()).Get(vm.Name) - old := toUpdate.DeepCopy() - if err != nil { - if apierrors.IsNotFound(err) { - return nil - } else { - glog.Errorf("unknown error encountered when setting terminating %v", err) - } - } - - toUpdate.Labels["ready"] = "true" - - if reflect.DeepEqual(old.Status, toUpdate.Status) && reflect.DeepEqual(old.Labels, toUpdate.Labels) { - return nil - } - - toUpdate, updateErr := t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).Update(t.ctx, toUpdate, metav1.UpdateOptions{}) - - if updateErr != nil { - glog.Errorf("error while updating machine: %s", toUpdate.Name) - return updateErr - } - - toUpdate.Status.PrivateIP = tfOutput["private_ip"]["value"] - if _, exists := tfOutput["public_ip"]; exists { - toUpdate.Status.PublicIP = tfOutput["public_ip"]["value"] - } else { - toUpdate.Status.PublicIP = translatePrivToPub(env.Spec.IPTranslationMap, tfOutput["private_ip"]["value"]) - } - toUpdate.Status.Hostname = tfOutput["hostname"]["value"] - toUpdate.Status.Status = hfv1.VmStatusRunning - - _, updateErr = t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).UpdateStatus(t.ctx, toUpdate, metav1.UpdateOptions{}) - - if err := util.VerifyVM(t.vmLister, toUpdate); err != nil { - glog.Errorf("error while verifying machine!!! %s", toUpdate.Name) - } - return updateErr - }) - - if retryErr != nil { - return retryErr, true - } - - } - return nil, false -} - -func translatePrivToPub(translationMap map[string]string, priv string) string { - splitIp := strings.Split(priv, ".") - - origPrefix := splitIp[0] + "." + splitIp[1] + "." + splitIp[2] - - translation, ok := translationMap[origPrefix] - - if ok { - return translation + "." + splitIp[3] - } - return "" - -} - -func (t *TerraformProvisionerController) removeFinalizer(vm *hfv1.VirtualMachine) error { - glog.V(5).Infof("removing finalizer for vm %s", vm.Name) - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - toUpdate, err := t.vmLister.VirtualMachines(util.GetReleaseNamespace()).Get(vm.Name) - if err != nil { - if apierrors.IsNotFound(err) { - return nil - } else { - glog.Errorf("unknown error encountered when setting terminating %v", err) - } - } - if reflect.DeepEqual(toUpdate.Finalizers, []string{}) { - return nil - } - toUpdate.Finalizers = []string{} - glog.V(5).Infof("removing vm finalizer for %s", vm.Name) - toUpdate, updateErr := t.hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()).Update(t.ctx, toUpdate, metav1.UpdateOptions{}) - if err := util.VerifyVMDeleted(t.vmLister, toUpdate); err != nil { - glog.Errorf("error while verifying machine deleted!!! %s", toUpdate.Name) - } - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error while updating vm object while setting terminating %v", retryErr) - } - return retryErr -} diff --git a/v3/pkg/controllers/vmclaimcontroller/vmclaimcontroller.go b/v3/pkg/controllers/vmclaimcontroller/vmclaimcontroller.go deleted file mode 100644 index ee93910d..00000000 --- a/v3/pkg/controllers/vmclaimcontroller/vmclaimcontroller.go +++ /dev/null @@ -1,850 +0,0 @@ -package vmclaimcontroller - -import ( - "context" - "fmt" - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "math/rand" - "time" - - "github.com/golang/glog" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "k8s.io/client-go/util/workqueue" -) - -const ( - StaticBindAttemptThreshold int = 3 - DynamicBindAttemptThreshold int = 2 -) - -type VMClaimController struct { - hfClientSet hfClientset.Interface - - vmLister v1.VirtualMachineLister - vmClaimLister v1.VirtualMachineClaimLister - vmtLister v1.VirtualMachineTemplateLister - - vmClaimWorkqueue workqueue.Interface - - vmWorkqueue workqueue.Interface - - vmClaimHasSynced cache.InformerSynced - vmHasSynced cache.InformerSynced - ctx context.Context - - accessCodeClient *accesscode.AccessCodeClient -} - -func NewVMClaimController(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, acClient *accesscode.AccessCodeClient, ctx context.Context) (*VMClaimController, error) { - vmClaimController := VMClaimController{} - vmClaimController.hfClientSet = hfClientSet - vmClaimController.accessCodeClient = acClient - - vmClaimController.vmLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Lister() - vmClaimController.vmClaimLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Lister() - vmClaimController.vmtLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Lister() - - vmClaimController.vmClaimWorkqueue = workqueue.New() - vmClaimController.vmWorkqueue = workqueue.New() - - vmClaimInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer() - - vmClaimInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: vmClaimController.enqueueVMClaim, - UpdateFunc: func(old, new interface{}) { - vmClaimController.enqueueVMClaim(new) - }, - DeleteFunc: vmClaimController.enqueueVMClaim, - }, time.Minute*30) - - vmInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() - - vmInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: vmClaimController.enqueueVM, - UpdateFunc: func(old, new interface{}) { - vmClaimController.enqueueVM(new) - }, - DeleteFunc: vmClaimController.enqueueVM, - }, time.Minute*30) - - vmClaimController.vmClaimHasSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer().HasSynced - vmClaimController.vmHasSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced - vmClaimController.ctx = ctx - - return &vmClaimController, nil -} - -func (v *VMClaimController) enqueueVMClaim(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - //utilruntime.HandleError(err) - return - } - glog.V(8).Infof("Enqueueing vm claim %v", key) - v.vmClaimWorkqueue.Add(key) -} - -func (v *VMClaimController) enqueueVM(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - return - } - glog.V(8).Infof("enqueueing vm %v in vm claim controller to inform vmclaim if exists", key) - v.vmWorkqueue.Add(key) -} - -func (v *VMClaimController) Run(stopCh <-chan struct{}) error { - defer v.vmClaimWorkqueue.ShutDown() - - glog.V(4).Infof("Starting vm claim controller") - glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, v.vmClaimHasSynced, v.vmHasSynced); !ok { - return fmt.Errorf("failed to wait for caches to sync") - } - glog.Info("Starting vm claim worker") - - go wait.Until(v.runVMClaimWorker, time.Second, stopCh) - go wait.Until(v.runVMWorker, time.Second, stopCh) - //if ok := cache.WaitForCacheSync(stopCh, ) - <-stopCh - return nil -} - -func (v *VMClaimController) runVMClaimWorker() { - for v.processNextVMClaim() { - - } -} - -func (v *VMClaimController) runVMWorker() { - for v.processNextVM() { - - } -} - -func (v *VMClaimController) processNextVM() bool { - obj, shutdown := v.vmWorkqueue.Get() - glog.V(8).Infof("processing VM in vm claim controller for update") - - if shutdown { - return false - } - - err := func() error { - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) - if err != nil { - return err - } - vm, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, objName, metav1.GetOptions{}) - - if err != nil { - - // ideally should put logic here to determine if we need to retry and push this vm back onto the workqueue - if errors.IsNotFound(err) { - return nil - - } else { - glog.Errorf("error while retrieving vm %s: %v, will be requeued", objName, err) - return err - } - } - - // trigger reconcile on vmClaims only when associated VM is running - // this should avoid triggering unwanted reconciles of VMClaims until the VM's are running - if vm.Spec.VirtualMachineClaimId != "" && vm.Status.Status == hfv1.VmStatusRunning { - v.vmClaimWorkqueue.Add(vm.Spec.VirtualMachineClaimId) - } - return nil - }() - - if err != nil { - // return and requeue the object - //v.vmWorkqueue.Add(obj) - return true - } - //vm event has been processed successfully ignore it - v.vmWorkqueue.Done(obj) - return true -} - -func (v *VMClaimController) processNextVMClaim() bool { - obj, shutdown := v.vmClaimWorkqueue.Get() - - glog.V(8).Infof("processing VM Claim") - - if shutdown { - return false - } - - err := func() error { - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) - if err != nil { - glog.Errorf("error while splitting meta namespace key %v", err) - return err - } - - // fetch vmClaim - vmClaim, err := v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Get(v.ctx, objName, metav1.GetOptions{}) - if err != nil { - if errors.IsNotFound(err) { - glog.Infof("vmClaim %s not found on queue.. ignoring", objName) - return nil - } else { - glog.Errorf("error while retrieving vmclaim %s from queue with err %v", objName, err) - return err - } - } - - // ignore vm objects which are being deleted - if vmClaim.DeletionTimestamp.IsZero() { - return v.processVMClaim(vmClaim) - } - return nil - }() - - if err != nil { - // requeue object - //v.vmClaimWorkqueue.Add(obj) - return true - } - - v.vmClaimWorkqueue.Done(obj) - return true -} - -func (v *VMClaimController) updateVMClaimStatus(bound bool, ready bool, vmc *hfv1.VirtualMachineClaim) error { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - newestVmc, err := v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Get(v.ctx, vmc.Name, metav1.GetOptions{}) - newestVmc.Status.Bound = bound - newestVmc.Status.Ready = ready - newestVmc, err = v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, newestVmc, metav1.UpdateOptions{}) - if err != nil { - return err - } - glog.V(4).Infof("updated result for virtual machine claim") - - verifyErr := util2.VerifyVMClaim(v.vmClaimLister, newestVmc) - - if verifyErr != nil { - return verifyErr - } - return nil - }) - if retryErr != nil { - return fmt.Errorf("error updating Virtual Machine Claim: %s, %v", vmc.Name, retryErr) - } - return nil -} - -func (v *VMClaimController) processVMClaim(vmc *hfv1.VirtualMachineClaim) (err error) { - if vmc.Status.Tainted { - glog.Infof("vmclaim %v is tainted.. cleaning it up", vmc.Name) - return v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Delete(v.ctx, vmc.Name, metav1.DeleteOptions{}) - } - - if !vmc.Status.Bound && !vmc.Status.Ready { - // submit VM requests // - // update status - if vmc.Status.BindMode == "dynamic" { - err = v.submitVirtualMachines(vmc) - if err != nil { - // VirtualMachines could not be submitted. Delete Session - glog.Errorf("error processing vmc %s, taint session: %v", vmc.Name, err) - return v.taintSession(vmc.Labels[util2.SessionLabel]) - } - } else if vmc.Status.BindMode == "static" { - err = v.findVirtualMachines(vmc) - if err != nil { - // VirtualMachines could not be bound. Delete Session - glog.Errorf("error processing vmc %s, taint session: %v", vmc.Name, err) - return v.taintSession(vmc.Labels[util2.SessionLabel]) - } - } else { - glog.Errorf("vmc bind mode needs to be either dynamic or static.. ignoring this object %s", vmc.Name) - return nil - } - - return v.updateVMClaimStatus(true, false, vmc) - } - - if vmc.Status.Bound && !vmc.Status.Ready { - // reconcile triggered by VM being ready - // lets check the VM's - ready, err := v.checkVMStatus(vmc) - if err != nil { - glog.Errorf("error checking vmStatus for vmc: %s %v", vmc.Name, err) - return err - } - // update status - glog.V(4).Infof("vm's have been requested for vmclaim: %s", vmc.Name) - return v.updateVMClaimStatus(true, ready, vmc) - } - - if vmc.Status.Bound && vmc.Status.Ready { - // nothing else needs to be done.. ignore and move along - glog.V(4).Infof("vmclaim %s is ready", vmc.Name) - } - - return nil -} - -func (v *VMClaimController) taintSession(session string) (err error) { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := v.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(v.ctx, session, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", session, getErr) - } - - // Change the expiration time to now, the sessionController will clean up the session - result.Status.ExpirationTime = time.Now().Format(time.UnixDate) - result.Status.Active = false - - _, updateErr := v.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for environment") - - return updateErr - }) - - if retryErr != nil { - return retryErr - } - - // Remove outstanding Progresses as there was an error with this session - err = v.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).DeleteCollection(v.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,finished=false", util2.SessionLabel, session)}) - - return err -} - -type VMEnvironment struct { - Environment hfv1.Environment - DynamicBindConfiguration hfv1.DynamicBindConfiguration -} - -func (v *VMClaimController) submitVirtualMachines(vmc *hfv1.VirtualMachineClaim) (err error) { - accessCode, ok := vmc.Labels[util2.AccessCodeLabel] - if !ok { - glog.Error("accessCode label not set on vmc, aborting") - return fmt.Errorf("accessCode label not set on vmc, aborting") - } - - environments, seName, dbcList, err := v.findEnvironmentsForVM(accessCode, vmc) - if err != nil { - glog.Errorf("error fetching environment for access code %s %v", accessCode, err) - return err - } - - // Calculate required VMs per template - requiredTemplateCount := make(map[string]int) - for _, vmDetails := range vmc.Spec.VirtualMachines { - if count, found := requiredTemplateCount[vmDetails.Template]; found { - requiredTemplateCount[vmDetails.Template] = count + 1 - } else { - requiredTemplateCount[vmDetails.Template] = 1 - } - } - - environmentMap := make(map[string]VMEnvironment) // Maps node to the environment it should use - bestDBC, err := v.findBestDBCForVMs(dbcList, requiredTemplateCount, vmc.Labels[util2.ScheduledEventLabel]) // Try to find if one environment can provision all VMs - - if err != nil { - // We can not provision all VirtualMachines in one environment. Figure out which environments we want to use - - reservedCapacity := make(map[string]map[string]int) // EnvironmentID -> TemplateID -> Count - // Initialize reservedCapacity with 0 for all environments + associated templates - for _, environment := range environments { - reserved := make(map[string]int) - for template, _ := range environment.Spec.TemplateMapping { - reserved[template] = 0 - } - reservedCapacity[environment.Name] = reserved - } - for vmName, vmDetails := range vmc.Spec.VirtualMachines { - env, dbc, err := v.findSuitableEnvironmentForVMTemplate(environments, dbcList, vmDetails.Template, reservedCapacity, vmc.Labels[util2.ScheduledEventLabel]) - if err != nil { - glog.Errorf("no suitable environment for %s (%s): %v", vmName, vmDetails.Template, err) - return err - } - environmentMap[vmName] = VMEnvironment{env, dbc} - reservedCapacity[env.Name][vmDetails.Template] += 1 - } - } else { - // One DBC for them all - enviroment := hfv1.Environment{} - for _, e := range environments { - if e.Name == bestDBC.Spec.Environment { - enviroment = e - break - } - } - for vmName, _ := range vmc.Spec.VirtualMachines { - environmentMap[vmName] = VMEnvironment{enviroment, bestDBC} - } - } - - vmMap := make(map[string]hfv1.VirtualMachineClaimVM) - for vmName, vmDetails := range vmc.Spec.VirtualMachines { - genName := fmt.Sprintf("%s-%08x", vmc.Spec.BaseName, rand.Uint32()) - environment := environmentMap[vmName].Environment - dbc := environmentMap[vmName].DynamicBindConfiguration - vm := &hfv1.VirtualMachine{ - ObjectMeta: metav1.ObjectMeta{ - Name: genName, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "VirtualMachineClaim", - Name: vmc.Name, - UID: vmc.UID, - }, - }, - Labels: map[string]string{ - "dynamic": "true", - "vmc": vmc.Name, - util2.EnvironmentLabel: environment.Name, - "bound": "true", - "ready": "false", - util2.VirtualMachineTemplate: vmDetails.Template, - util2.ScheduledEventLabel: seName, - }, - }, - Spec: hfv1.VirtualMachineSpec{ - VirtualMachineTemplateId: vmDetails.Template, - SecretName: "", - Protocol: "ssh", //default protocol is ssh - VirtualMachineClaimId: vmc.Name, - UserId: vmc.Spec.UserId, - Provision: true, - VirtualMachineSetId: "", - }, - } - // used to later repopulate the info back // - vmMap[vmName] = hfv1.VirtualMachineClaimVM{ - Template: vmDetails.Template, - VirtualMachineId: genName, - } - - vmt, err := v.vmtLister.VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(vmDetails.Template) - if err != nil { - glog.Errorf("error getting vmt %v", err) - return err - } - - config := util2.GetVMConfig(&environment, vmt) - - protocol, exists := config["protocol"] - if exists { - vm.Spec.Protocol = protocol - } - - sshUser, exists := config["ssh_username"] - if exists { - vm.Spec.SshUsername = sshUser - } - - // extra label to indicate external provisioning so tfpcontroller ignores this request // - if provisionMethod, ok := environment.Annotations["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { - vm.Labels["hobbyfarm.io/provisioner"] = provisionMethod - vm.Spec.Provision = false - } - - if dbc.Spec.RestrictedBind { - vm.ObjectMeta.Labels["restrictedbind"] = "true" - vm.ObjectMeta.Labels["restrictedbindvalue"] = dbc.Spec.RestrictedBindValue - } else { - vm.ObjectMeta.Labels["restrictedbind"] = "false" - } - - createdVM, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Create(v.ctx, vm, metav1.CreateOptions{}) - if err != nil { - return err - } - - vmStatus := hfv1.VirtualMachineStatus{ - Status: hfv1.VmStatusRFP, - Allocated: true, - Tainted: false, - WsEndpoint: environment.Spec.WsEndpoint, - EnvironmentId: environment.Name, - PublicIP: "", - PrivateIP: "", - } - - // retry loop here - retryErr := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - createdVM, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, createdVM.Name, metav1.GetOptions{}) - if err != nil { - return err - } - - createdVM.Status = vmStatus - - _, err = v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, createdVM, metav1.UpdateOptions{}) - if err != nil { - return err - } - - return nil - }) - - if retryErr != nil { - return retryErr - } - } - - vmc.Spec.VirtualMachines = vmMap - - _, err = v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Update(v.ctx, vmc, metav1.UpdateOptions{}) - if err != nil { - return err - } - - return nil -} - -// Based on the given VirtualMachineClaim and ScheduledEvent find all suitable Environments (e.g. environment provides required VMTeplate & ScheduledEvents allows this environment and VMTemplate configuration etc.) -func (v *VMClaimController) findEnvironmentsForVM(accessCode string, vmc *hfv1.VirtualMachineClaim) (environments []hfv1.Environment, seName string, dbc []hfv1.DynamicBindConfiguration, err error) { - seName, _, err = v.findScheduledEvent(accessCode) - if err != nil { - return environments, seName, dbc, err - } - - dbcList, err := v.hfClientSet.HobbyfarmV1().DynamicBindConfigurations(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, seName), - }) - - if err != nil { - glog.Errorf("error listing dbc %v", err) - return environments, seName, dbc, err - } - - for _, dbc := range dbcList.Items { - env, err := v.hfClientSet.HobbyfarmV1().Environments(util2.GetReleaseNamespace()).Get(v.ctx, dbc.Spec.Environment, metav1.GetOptions{}) - - if err != nil { - glog.Errorf("error fetching environment %v", err) - return environments, seName, dbcList.Items, err - } - environments = append(environments, *env) - } - - if len(dbcList.Items) < 1 { - return environments, seName, dbc, fmt.Errorf("incorrect number of dbc matching sessionName found") - } - - return environments, seName, dbcList.Items, err -} - -// Can one DBC provide all VMs when considering the limits? Return the DBC if there exists one -func (v *VMClaimController) findBestDBCForVMs(dbcList []hfv1.DynamicBindConfiguration, requiredTemplateCount map[string]int, scheduledEvent string) (hfv1.DynamicBindConfiguration, error) { - // Try to find best possible environment / DBC = All required VMs can be provisioned here - for _, dbc := range dbcList { - satisfiedDBC := true - env, err := v.hfClientSet.HobbyfarmV1().Environments(util2.GetReleaseNamespace()).Get(v.ctx, dbc.Spec.Environment, metav1.GetOptions{}) - if err != nil { - return hfv1.DynamicBindConfiguration{}, fmt.Errorf("error fetching environment") - } - for requiredTemplate, requiredCount := range requiredTemplateCount { - dbcCapacity, foundDBC := dbc.Spec.BurstCountCapacity[requiredTemplate] - envCapacity, foundEnv := env.Spec.CountCapacity[requiredTemplate] - if foundDBC && foundEnv { - // Does the DBC satisfy this amount? - count, err := util2.CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(v.vmLister, requiredTemplate, dbc.Spec.Environment, scheduledEvent) - if err != nil { - satisfiedDBC = false - break - } - if requiredCount >= (dbcCapacity - count) { - satisfiedDBC = false - break - } - - // Does the environment satisfy this amount? - count, err = util2.CountMachinesPerTemplateAndEnvironment(v.vmLister, requiredTemplate, dbc.Spec.Environment) - if err != nil { - satisfiedDBC = false - break - } - if requiredCount >= (envCapacity - count) { - satisfiedDBC = false - break - } - - } else { - satisfiedDBC = false - break - } - } - - if satisfiedDBC { - // This DBC works for all templates and has the required Counts available! - glog.V(4).Infof("found best environment suitable for all VMs: %s", dbc.Spec.Environment) - return dbc, nil - } - } - return hfv1.DynamicBindConfiguration{}, fmt.Errorf("there is no best environment") -} - -func (v *VMClaimController) findSuitableEnvironmentForVMTemplate(environments []hfv1.Environment, dbcList []hfv1.DynamicBindConfiguration, template string, reservedCapacity map[string]map[string]int, scheduledEvent string) (hfv1.Environment, hfv1.DynamicBindConfiguration, error) { - for _, environment := range environments { - countEnv, err := util2.CountMachinesPerTemplateAndEnvironment(v.vmLister, template, environment.Name) - if err != nil { - continue - } - // We have also reserved capacity for other VMs - countEnv += reservedCapacity[environment.Name][template] - - if countEnv >= environment.Spec.CountCapacity[template] { - // Environment is at limit - continue - } - - countDBC, err := util2.CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(v.vmLister, template, environment.Name, scheduledEvent) - if err != nil { - continue - } - // We have also reserved capacity for other VMs - countDBC += reservedCapacity[environment.Name][template] - - // found environment that satisfies capacity for this template - for _, dbc := range dbcList { - if dbc.Spec.Environment == environment.Name { - if capacity, found := dbc.Spec.BurstCountCapacity[template]; found { - if countDBC < capacity { - // Capacity also satisfied for environment + scheduledEvent via DBC - return environment, dbc, nil - } - } - break - } - } - - } - - return hfv1.Environment{}, hfv1.DynamicBindConfiguration{}, fmt.Errorf("no suitable environment found. capacity reached") -} - -func (v *VMClaimController) checkVMStatus(vmc *hfv1.VirtualMachineClaim) (ready bool, err error) { - ready = true - for _, vmTemplate := range vmc.Spec.VirtualMachines { - vm, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, vmTemplate.VirtualMachineId, metav1.GetOptions{}) - if err != nil { - return ready, err - } - if vm.Status.Status == hfv1.VmStatusRunning { - ready = ready && true - } else { - ready = ready && false - } - } - - return ready, err -} - -func (v *VMClaimController) findScheduledEvent(accessCode string) (schedEvent string, environments map[string]map[string]int, err error) { - ac, err := v.accessCodeClient.GetAccessCodeWithOTACs(accessCode) - if err != nil { - return schedEvent, environments, err - } - - se, err := v.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(v.ctx, ac.Labels[util2.ScheduledEventLabel], metav1.GetOptions{}) - if err != nil { - return schedEvent, environments, err - } - - schedEvent = se.Name - environments = se.Spec.RequiredVirtualMachines - return schedEvent, environments, nil -} - -func (v *VMClaimController) findVirtualMachines(vmc *hfv1.VirtualMachineClaim) (err error) { - accessCode, ok := vmc.Labels[util2.AccessCodeLabel] - if !ok { - glog.Error("accessCode label not set on vmc, aborting") - return fmt.Errorf("accessCode label not set on vmc, aborting") - } - _, environments, err := v.findScheduledEvent(accessCode) - - if err != nil { - glog.Error("error finding scheduledevent during static bind") - return err - } - - vmMap := make(map[string]hfv1.VirtualMachineClaimVM) - for name, vmStruct := range vmc.Spec.VirtualMachines { - if vmStruct.VirtualMachineId == "" { - glog.Info("assigning a vm") - vmID, err := v.assignNextFreeVM(vmc.Name, vmc.Spec.UserId, environments, vmStruct.Template, vmc.Spec.RestrictedBind, vmc.Spec.RestrictedBindValue) - if err != nil { - // If we run into any issue assigning a VM we need to unassign the previously assigned VMs - for _, vm := range vmMap { - v.unassignVM(vm.VirtualMachineId) - } - return err - } - vmMap[name] = hfv1.VirtualMachineClaimVM{ - Template: vmStruct.Template, - VirtualMachineId: vmID, - } - } - } - vmc.Spec.VirtualMachines = vmMap - - _, err = v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Update(v.ctx, vmc, metav1.UpdateOptions{}) - if err != nil { - return err - } - - return nil -} - -func (v *VMClaimController) assignVM(vmClaimId string, user string, vmId string) error { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, vmId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of Virtual Machine %s: %v", vmId, getErr) - } - - result.Labels["bound"] = "true" - result.Spec.VirtualMachineClaimId = vmClaimId - result.Spec.UserId = user - - vm, updateErr := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Update(v.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - - vm.Status.Allocated = true - - _, updateErr = v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, vm, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - - glog.V(4).Infof("updated result for virtual machine") - - verifyErr := util2.VerifyVM(v.vmLister, vm) - - if verifyErr != nil { - return verifyErr - } - return nil - }) - if retryErr != nil { - return fmt.Errorf("error updating Virtual Machine: %s, %v", vmId, retryErr) - } - - return nil -} - -func (v *VMClaimController) unassignVM(vmId string) (string, error) { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, vmId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of Virtual Machine %s: %v", vmId, getErr) - } - - result.Labels["bound"] = "false" - result.Spec.VirtualMachineClaimId = "" - result.Spec.UserId = "" - - vm, updateErr := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Update(v.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - - vm.Status.Allocated = false - - _, updateErr = v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, vm, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - - verifyErr := util2.VerifyVM(v.vmLister, vm) - - if verifyErr != nil { - return verifyErr - } - return nil - }) - if retryErr != nil { - return "", fmt.Errorf("error updating Virtual Machine: %s, %v", vmId, retryErr) - } - - return vmId, nil -} - -func (v *VMClaimController) assignNextFreeVM(vmClaimId string, user string, environments map[string]map[string]int, template string, restrictedBind bool, restrictedBindValue string) (string, error) { - vmLabels := labels.Set{ - "bound": "false", - util2.VirtualMachineTemplate: template, - } - - if restrictedBind { - vmLabels["restrictedbind"] = "true" - vmLabels["restrictedbindvalue"] = restrictedBindValue - } else { - vmLabels["restrictedbind"] = "false" - } - - vms, err := v.vmLister.List(vmLabels.AsSelector()) - glog.V(4).Infof("found %d vm's matching this requirement", len(vms)) - if err != nil { - return "", fmt.Errorf("error while listing all vms %v", err) - } - - if len(vms) == 0 { - return "", fmt.Errorf("No static VMs matching template: %s. All static VMs are in use.", template) - } - - assigned := false - vmId := "" - for _, vm := range vms { - // Check for Supported environment - if vmts, found := environments[vm.Labels[util2.EnvironmentLabel]]; found { - // This virtualmachine is one of the supported environments - if _, foundVMT := vmts[vm.Spec.VirtualMachineTemplateId]; !foundVMT { - // ... but this environment does not support this virtualmachinetemplate - continue - } - } else { - // This virtualmachine is in a non supported environment - continue - } - if !vm.Status.Allocated && !vm.Status.Tainted { - // we can assign this vm - assigned = true - vmId = vm.Name - - // Prefer running machines - if vm.Status.Status == hfv1.VmStatusRunning { - break - } - } - } - - if assigned { - err = v.assignVM(vmClaimId, user, vmId) - - if err != nil { - return "", err - } - - return vmId, nil - } - - return vmId, fmt.Errorf("unknown error while assigning next free vm") - -} diff --git a/v3/pkg/controllers/vmsetcontroller/vmsetcontroller.go b/v3/pkg/controllers/vmsetcontroller/vmsetcontroller.go deleted file mode 100644 index 5e005eac..00000000 --- a/v3/pkg/controllers/vmsetcontroller/vmsetcontroller.go +++ /dev/null @@ -1,478 +0,0 @@ -package vmsetcontroller - -import ( - "context" - "fmt" - "math/rand" - "strings" - "time" - - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - v1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/golang/glog" - "k8s.io/apimachinery/pkg/api/errors" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "k8s.io/client-go/util/workqueue" -) - -type VirtualMachineSetController struct { - hfClientSet hfClientset.Interface - //vmSetWorkqueue workqueue.RateLimitingInterface - vmWorkqueue workqueue.RateLimitingInterface - vmSetWorkqueue workqueue.Interface - vmSetLister v1.VirtualMachineSetLister - vmLister v1.VirtualMachineLister - envLister v1.EnvironmentLister - vmTemplateLister v1.VirtualMachineTemplateLister - - vmSetSynced cache.InformerSynced - vmSynced cache.InformerSynced - envSynced cache.InformerSynced - vmTemplateSynced cache.InformerSynced - ctx context.Context -} - -const ( - vmEnvironmentIndex = "vm.vmclaim.controllers.hobbyfarm.io/environment-index" - vmSetFinalizer = "finalizer.hobbyfarm.io/vmset" -) - -func NewVirtualMachineSetController(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*VirtualMachineSetController, error) { - vmSetController := VirtualMachineSetController{} - vmSetController.hfClientSet = hfClientSet - - vmSetController.vmSetSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Informer().HasSynced - vmSetController.vmSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced - vmSetController.envSynced = hfInformerFactory.Hobbyfarm().V1().Environments().Informer().HasSynced - vmSetController.vmTemplateSynced = hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Informer().HasSynced - - //vmSetController.vmSetWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "VMSet") - vmSetController.vmWorkqueue = workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "VM") - vmSetController.vmSetWorkqueue = workqueue.NewNamed("vmsc-vms") - - //vmClaimController.hfInformerFactory = hfInformerFactory - - vmSetController.vmSetLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Lister() - vmSetController.vmLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Lister() - vmSetController.envLister = hfInformerFactory.Hobbyfarm().V1().Environments().Lister() - vmSetController.vmTemplateLister = hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Lister() - - vmSetInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Informer() - - vmSetInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: vmSetController.enqueueVMSet, - UpdateFunc: func(old, new interface{}) { - vmSetController.enqueueVMSet(new) - }, - DeleteFunc: vmSetController.enqueueVMSet, - }, time.Minute*30) - - vmInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() - - vmInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - AddFunc: vmSetController.handleVM, - UpdateFunc: func(old, new interface{}) { - vmSetController.handleVM(new) - }, - DeleteFunc: vmSetController.handleVM, - }, time.Minute*30) - vmSetController.ctx = ctx - - return &vmSetController, nil -} - -func (v *VirtualMachineSetController) handleVM(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - return - } - glog.V(8).Infof("enqueueing vm %v to check associated vmsets in vmsetcontroller", key) - v.vmWorkqueue.Add(key) -} - -func (v *VirtualMachineSetController) enqueueVMSet(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - //utilruntime.HandleError(err) - return - } - glog.V(8).Infof("Enqueueing vm set %s", key) - //v.vmSetWorkqueue.AddRateLimited(key) - v.vmSetWorkqueue.Add(key) -} - -func (v *VirtualMachineSetController) Run(stopCh <-chan struct{}) error { - defer v.vmSetWorkqueue.ShutDown() - - glog.V(4).Infof("Starting vm set") - glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, v.vmSynced, v.vmSetSynced, v.vmTemplateSynced, v.envSynced); !ok { - return fmt.Errorf("failed to wait for caches to sync") - } - glog.Info("Starting vm set controller worker") - go wait.Until(v.runVMSetWorker, time.Second, stopCh) - go wait.Until(v.runVMWorker, time.Second, stopCh) - glog.Info("Started vm set controller worker") - //if ok := cache.WaitForCacheSync(stopCh, ) - <-stopCh - return nil -} - -func (v *VirtualMachineSetController) runVMSetWorker() { - for v.processNextVMSet() { - - } -} - -func (v *VirtualMachineSetController) runVMWorker() { - for v.processNextVM() { - - } -} - -func (v *VirtualMachineSetController) processNextVM() bool { - obj, shutdown := v.vmWorkqueue.Get() - glog.V(8).Infof("processing VM in vmsetcontroller controller for update") - - if shutdown { - return false - } - - err := func() error { - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) - if err != nil { - return err - } - vm, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Get(v.ctx, objName, metav1.GetOptions{}) - - if err != nil { - - // ideally should put logic here to determine if we need to retry and push this vm back onto the workqueue - if errors.IsNotFound(err) { - return nil - - } else { - glog.Errorf("error while retrieving vm %s: %v, will be requeued", objName, err) - return err - } - } - - // trigger reconcile on vmClaims only when associated VM is running - // this should avoid triggering unwanted reconciles of VMClaims until the VM's are running - if !vm.DeletionTimestamp.IsZero() { - glog.V(4).Infof("requeuing vmset %s to account for tainted vm %s", vm.Spec.VirtualMachineSetId, vm.Name) - err = v.removeVMFinalizer(vm) - if err != nil { - glog.Errorf("error removing vm finalizer on vm %s", vm.Name) - return err - } - defer v.vmSetWorkqueue.Add(vm.Spec.VirtualMachineSetId) - } - - return nil - }() - - if err != nil { - // return and requeue the object - //v.vmWorkqueue.Add(obj) - return true - } - //vm event has been processed successfully ignore it - v.vmWorkqueue.Done(obj) - return true -} -func (v *VirtualMachineSetController) processNextVMSet() bool { - obj, shutdown := v.vmSetWorkqueue.Get() - - glog.V(8).Infof("processing VMSet") - - if shutdown { - return false - } - err := func() error { - defer v.vmSetWorkqueue.Done(obj) - glog.V(4).Infof("processing vms in vmset controller: %v", obj) - _, objName, err := cache.SplitMetaNamespaceKey(obj.(string)) // this is actually not necessary because VM's are not namespaced yet... - if err != nil { - glog.Errorf("error while splitting meta namespace key %v", err) - //e.vmWorkqueue.AddRateLimited(obj) - return nil - } - - vmSet, err := v.vmSetLister.VirtualMachineSets(util2.GetReleaseNamespace()).Get(objName) - if err != nil { - glog.Errorf("error while retrieving virtual machine set %s, likely deleted %v", objName, err) - //v.vmSetWorkqueue.Forget(obj) - return nil - } - - err = v.reconcileVirtualMachineSet(vmSet) - if err != nil { - glog.Error(err) - } - //v.vmSetWorkqueue.Forget(obj) - glog.V(4).Infof("vm set processed by vmset controller %v", objName) - return nil - - }() - - if err != nil { - return true - } - - // successfully reconcilled, mark object as done - v.vmSetWorkqueue.Done(obj) - return true -} - -func (v *VirtualMachineSetController) reconcileVirtualMachineSet(vmset *hfv1.VirtualMachineSet) error { - - currentVMs, err := v.vmLister.List(labels.Set{ - "vmset": vmset.Name, - }.AsSelector()) - - if err != nil { - glog.Errorf("error listing vms in vmset controller") - return err - } - - if len(currentVMs) < vmset.Spec.Count { // if desired count is greater than the current provisioned - // 1. let's check the environment to see if there is available capacity - // 2. if available capacity is available let's create new VM's - glog.V(4).Infof("vmset %s needs %d vm's but current vm count is %d", vmset.Name, vmset.Spec.Count, len(currentVMs)) - env, err := v.envLister.Environments(util2.GetReleaseNamespace()).Get(vmset.Spec.Environment) - var provision bool - provision = true - if provisionMethod, ok := env.Annotations["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { - provision = false - } - if err != nil { - if apierrors.IsNotFound(err) { - glog.Errorf("environment invalid") - } - return err - } - - vmt, err := v.vmTemplateLister.VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(vmset.Spec.VMTemplate) - if err != nil { - return fmt.Errorf("error while retrieving virtual machine template %s %v", vmset.Spec.VMTemplate, err) - } - needed := vmset.Spec.Count - len(currentVMs) - - glog.V(5).Infof("provisioning %d vms", needed) - // this code is so... verbose... - for i := 0; i < needed; i++ { - vmName := strings.Join([]string{vmset.Spec.BaseName, fmt.Sprintf("%08x", rand.Uint32())}, "-") - vm := &hfv1.VirtualMachine{ - ObjectMeta: metav1.ObjectMeta{ - Name: vmName, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "VirtualMachineSet", - Name: vmset.Name, - UID: vmset.UID, - }, - }, - Labels: map[string]string{ - "dynamic": "false", - "vmset": vmset.Name, - util2.VirtualMachineTemplate: vmt.Name, - util2.EnvironmentLabel: env.Name, - "bound": "false", - "ready": "false", - util2.ScheduledEventLabel: vmset.ObjectMeta.Labels[util2.ScheduledEventLabel], - }, - }, - Spec: hfv1.VirtualMachineSpec{ - VirtualMachineTemplateId: vmt.Name, - SecretName: "", - Protocol: "ssh", - VirtualMachineClaimId: "", - UserId: "", - Provision: provision, - VirtualMachineSetId: vmset.Name, - }, - } - - config := util2.GetVMConfig(env, vmt) - - sshUser, exists := config["ssh_username"] - if exists { - vm.Spec.SshUsername = sshUser - } - protocol, exists := config["protocol"] - if exists { - vm.Spec.Protocol = protocol - } - if vmset.Spec.RestrictedBind { - vm.ObjectMeta.Labels["restrictedbind"] = "true" - vm.ObjectMeta.Labels["restrictedbindvalue"] = vmset.Spec.RestrictedBindValue - } else { - vm.ObjectMeta.Labels["restrictedbind"] = "false" - } - - if provisionMethod, ok := env.Annotations["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { - vm.ObjectMeta.Labels["hobbyfarm.io/provisioner"] = provisionMethod - } - - // adding a custom finalizer for reconcile of vmsets - vm.SetFinalizers([]string{vmSetFinalizer}) - vm, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Create(v.ctx, vm, metav1.CreateOptions{}) - - if err != nil { - glog.Error(err) - } - - vm.Status = hfv1.VirtualMachineStatus{ - Status: hfv1.VmStatusRFP, - Allocated: false, - Tainted: false, - WsEndpoint: env.Spec.WsEndpoint, - PublicIP: "", - PrivateIP: "", - EnvironmentId: env.Name, - Hostname: "", - } - - _, err = v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, vm, metav1.UpdateOptions{}) - - if err != nil { - glog.Error(err) - } - - err = util2.VerifyVM(v.vmLister, vm) - if err != nil { - glog.Error(err) - } - } - } - - // handle case of scaling down VMSets - if len(currentVMs) > vmset.Spec.Count { - // We first calculate how many VMs already have been deleted to avoid deleting more than we need - currentlyDeleting := 0 - for _, x := range currentVMs { - if x.DeletionTimestamp != nil { - currentlyDeleting++ - } - } - - // We need to delete all over the spec.count minus the VMs that are already being deleted right now. - needed_delete := len(currentVMs) - vmset.Spec.Count - currentlyDeleting - glog.V(4).Infof("vmset %s needs to delete %d vm's and %d are already flagged as deleted", vmset.Name, needed_delete, currentlyDeleting) - for _, cur_vm := range currentVMs { - if needed_delete == 0 { - break - } - - if !cur_vm.Status.Allocated && cur_vm.DeletionTimestamp == nil { - v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Delete(v.ctx, cur_vm.Name, metav1.DeleteOptions{}) - needed_delete-- - } - } - if needed_delete > 0 { - glog.V(4).Infof("vmset %d could not delete %d VMs due to some VMs being in use.", vmset.Name, needed_delete) - } - } - - vms, err := v.vmLister.List(labels.Set{ - "vmset": string(vmset.Name), - }.AsSelector()) - - if err != nil { - glog.Errorf("error while retrieving vms owned by vmset %s", vmset.Name) - } - - provisionedCount := 0 - activeCount := 0 - for _, x := range vms { - if x.DeletionTimestamp == nil && !x.Status.Tainted { - activeCount++ - } - provisionedCount++ - } - - if activeCount < vmset.Spec.Count { - glog.V(4).Infof("requeing VMset as there are not enough VMs ready") - v.enqueueVMSet(vmset) - } - - err = v.updateVMSetCount(vmset.Name, activeCount, provisionedCount) - - return err -} - -func (v *VirtualMachineSetController) updateVMSetCount(vmSetName string, active int, prov int) error { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := v.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).Get(v.ctx, vmSetName, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of Virtual Machine Set %s: %v", vmSetName, getErr) - } - - result.Status.ProvisionedCount = prov - result.Status.AvailableCount = active - - vms, updateErr := v.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).UpdateStatus(v.ctx, result, metav1.UpdateOptions{}) - if updateErr != nil { - glog.Error(updateErr) - return updateErr - } - - err := util2.VerifyVMSet(v.vmSetLister, vms) - if err != nil { - glog.Error(err) - } - glog.V(4).Infof("updated result for virtual machine set") - return nil - }) - if retryErr != nil { - return fmt.Errorf("error updating Virtual Machine Set: %s, %v", vmSetName, retryErr) - } - - return nil -} - -func (v *VirtualMachineSetController) removeVMFinalizer(vm *hfv1.VirtualMachine) (err error) { - if ContainsFinalizer(vm, vmSetFinalizer) { - RemoveFinalizer(vm, vmSetFinalizer) - _, err = v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).Update(v.ctx, vm, metav1.UpdateOptions{}) - } - return err -} - -// From ControllerUtil to save dep issues - -// RemoveFinalizer accepts an Object and removes the provided finalizer if present. -func RemoveFinalizer(vm *hfv1.VirtualMachine, finalizer string) { - f := vm.GetFinalizers() - for i := 0; i < len(f); i++ { - if f[i] == finalizer { - f = append(f[:i], f[i+1:]...) - i-- - } - } - vm.SetFinalizers(f) -} - -// ContainsFinalizer checks an Object that the provided finalizer is present. -func ContainsFinalizer(vm *hfv1.VirtualMachine, finalizer string) bool { - f := vm.GetFinalizers() - for _, e := range f { - if e == finalizer { - return true - } - } - return false -} diff --git a/v3/pkg/courseclient/courseclient.go b/v3/pkg/courseclient/courseclient.go deleted file mode 100644 index f0c51a6e..00000000 --- a/v3/pkg/courseclient/courseclient.go +++ /dev/null @@ -1,33 +0,0 @@ -package courseclient - -import ( - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - "github.com/hobbyfarm/gargantua/v3/pkg/courseserver" -) - -type CourseClient struct { - cServer *courseserver.CourseServer -} - -func NewCourseClient(cServer *courseserver.CourseServer) (*CourseClient, error) { - a := CourseClient{} - - a.cServer = cServer - return &a, nil -} - -func (cc CourseClient) GetCourseById(id string) (hfv1.Course, error) { - - cResult, err := cc.cServer.GetCourseById(id) - - if err != nil { - return hfv1.Course{}, err - } - - return cResult, nil -} - -func (cc CourseClient) AppendDynamicScenariosByCategories(scenariosList []string, categories []string) []string { - - return cc.cServer.AppendDynamicScenariosByCategories(scenariosList, categories) -} diff --git a/v3/pkg/courseserver/courseserver.go b/v3/pkg/courseserver/courseserver.go deleted file mode 100644 index 4d85e2bf..00000000 --- a/v3/pkg/courseserver/courseserver.go +++ /dev/null @@ -1,671 +0,0 @@ -package courseserver - -import ( - "context" - "encoding/json" - "fmt" - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - hfListers "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - "strconv" - "strings" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" -) - -const ( - idIndex = "courseserver.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralCourse -) - -type CourseServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - acClient *accesscode.AccessCodeClient - courseIndexer cache.Indexer - ctx context.Context - cenariosLister hfListers.ScenarioLister - scenariosLister hfListers.ScenarioLister -} - -type PreparedCourse struct { - Id string `json:"id"` - hfv1.CourseSpec -} - -func NewCourseServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, acClient *accesscode.AccessCodeClient, hfClientset hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*CourseServer, error) { - course := CourseServer{} - - course.authnClient = authnClient - course.authrClient = authrClient - course.hfClientSet = hfClientset - course.acClient = acClient - inf := hfInformerFactory.Hobbyfarm().V1().Courses().Informer() - indexers := map[string]cache.IndexFunc{idIndex: idIndexer} - - err := inf.AddIndexers(indexers) - if err != nil { - glog.Errorf("error adding indexer %s for courses", idIndex) - } - course.courseIndexer = inf.GetIndexer() - course.scenariosLister = hfInformerFactory.Hobbyfarm().V1().Scenarios().Lister() - course.ctx = ctx - - return &course, nil -} - -func (c CourseServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/course/list/{access_code}", c.ListCoursesForAccesscode).Methods("GET") - r.HandleFunc("/course/{course_id}", c.GetCourse).Methods("GET") - r.HandleFunc("/a/course/list", c.ListFunc).Methods("GET") - r.HandleFunc("/a/course/new", c.CreateFunc).Methods("POST") - r.HandleFunc("/a/course/{course_id}", c.GetCourse).Methods("GET") - r.HandleFunc("/a/course/{id}", c.UpdateFunc).Methods("PUT") - r.HandleFunc("/a/course/{id}", c.DeleteFunc).Methods("DELETE") - r.HandleFunc("/a/course/previewDynamicScenarios", c.previewDynamicScenarios).Methods("POST") -} - -func (c CourseServer) getPreparedCourseById(id string) (PreparedCourse, error) { - course, err := c.GetCourseById(id) - - if err != nil { - return PreparedCourse{}, fmt.Errorf("error while retrieving course %v", err) - } - - preparedCourse := PreparedCourse{course.Name, course.Spec} - - return preparedCourse, nil -} - -func (c CourseServer) ListFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - glog.Infof("Authr error: %s", err.Error()) - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list courses") - return - } - - tempCourses, err := c.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).List(c.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error listing courses: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing courses") - return - } - - var courses []PreparedCourse - for _, c := range tempCourses.Items { - courses = append(courses, PreparedCourse{c.Name, c.Spec}) - } - - encodedCourses, err := json.Marshal(courses) - if err != nil { - glog.Errorf("error marshalling prepared courses: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing courses") - return - } - - util.ReturnHTTPContent(w, r, 200, "success", encodedCourses) - - glog.V(4).Infof("listed courses") -} - -func (c CourseServer) GetCourse(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to courses") - return - } - - vars := mux.Vars(r) - - course, err := c.getPreparedCourseById(vars["course_id"]) - if err != nil { - util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("error retrieving course: %v", err)) - return - } - - encodedCourse, err := json.Marshal(course) - if err != nil { - glog.Error(err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error preparing course") - return - } - - util.ReturnHTTPContent(w, r, 200, "success", encodedCourse) -} - -func (c CourseServer) CreateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create courses") - return - } - - name := r.PostFormValue("name") - if name == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") - return - } - - description := r.PostFormValue("description") - if description == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") - return - } - - keepaliveDuration := r.PostFormValue("keepalive_duration") - // keepaliveDuration is optional - - scenarios := r.PostFormValue("scenarios") - scenarioSlice := make([]string, 0) - if scenarios != "" { - err = json.Unmarshal([]byte(scenarios), &scenarioSlice) - if err != nil { - glog.Errorf("error while unmarshalling scenarios %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - categories := r.PostFormValue("categories") - categoriesSlice := make([]string, 0) - if categories != "" { - err = json.Unmarshal([]byte(categories), &categoriesSlice) - if err != nil { - glog.Errorf("error while unmarshalling categories %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - rawVirtualMachines := r.PostFormValue("virtualmachines") - virtualmachines := []map[string]string{} // must be declared this way so as to JSON marshal into [] instead of null - if rawVirtualMachines != "" { - err = json.Unmarshal([]byte(rawVirtualMachines), &virtualmachines) - if err != nil { - glog.Errorf("error while unmarshaling VMs %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - pauseableRaw := r.PostFormValue("pauseable") - pauseable, err := strconv.ParseBool(pauseableRaw) - if err != nil { - glog.Errorf("error while parsing bool %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - pauseDuration := r.PostFormValue("pause_duration") - - keepVMRaw := r.PostFormValue("keep_vm") - keepVM, err := strconv.ParseBool(keepVMRaw) - if err != nil { - glog.Errorf("error while parsing bool: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - course := &hfv1.Course{} - - generatedName := util.GenerateResourceName("c", name, 10) - - course.Name = generatedName - - course.Spec.Name = name - course.Spec.Description = description - course.Spec.VirtualMachines = virtualmachines - course.Spec.Scenarios = scenarioSlice - course.Spec.Categories = categoriesSlice - if keepaliveDuration != "" { - course.Spec.KeepAliveDuration = keepaliveDuration - } - course.Spec.Pauseable = pauseable - if pauseDuration != "" { - course.Spec.PauseDuration = pauseDuration - } - course.Spec.KeepVM = keepVM - - course, err = c.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).Create(c.ctx, course, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating course %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating course") - return - } - - util.ReturnHTTPMessage(w, r, 201, "created", course.Name) - glog.V(4).Infof("Created course %s", course.Name) - return -} - -func (c CourseServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update courses") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") - return - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - course, err := c.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).Get(c.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "badrequest", "no course found with given ID") - return fmt.Errorf("bad") - } - // name, description, scenarios, virtualmachines, keepaliveduration, pauseduration, pauseable - - name := r.PostFormValue("name") - description := r.PostFormValue("description") - scenarios := r.PostFormValue("scenarios") - categories := r.PostFormValue("categories") - virtualMachinesRaw := r.PostFormValue("virtualmachines") - keepaliveDuration := r.PostFormValue("keepalive_duration") - pauseDuration := r.PostFormValue("pause_duration") - pauseableRaw := r.PostFormValue("pauseable") - keepVMRaw := r.PostFormValue("keep_vm") - - if name != "" { - course.Spec.Name = name - } - - if description != "" { - course.Spec.Description = description - } - - if scenarios != "" { - scenarioSlice := make([]string, 0) - err = json.Unmarshal([]byte(scenarios), &scenarioSlice) - if err != nil { - glog.Errorf("error while unmarshalling scenarios %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - - course.Spec.Scenarios = scenarioSlice - } - - if categories != "" { - categoriesSlice := make([]string, 0) - err = json.Unmarshal([]byte(categories), &categoriesSlice) - if err != nil { - glog.Errorf("error while unmarshalling categories %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - course.Spec.Categories = categoriesSlice - } - - if virtualMachinesRaw != "" { - virtualmachines := []map[string]string{} // must be declared this way so as to JSON marshal into [] instead of null - err = json.Unmarshal([]byte(virtualMachinesRaw), &virtualmachines) - if err != nil { - glog.Errorf("error while unmarshaling VMs %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - - course.Spec.VirtualMachines = virtualmachines - } - - if keepaliveDuration != "" { - course.Spec.KeepAliveDuration = keepaliveDuration - } - - if pauseDuration != "" { - course.Spec.PauseDuration = pauseDuration - } - - if pauseableRaw != "" { - pauseable, err := strconv.ParseBool(pauseableRaw) - if err != nil { - glog.Errorf("error while parsing bool: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - - course.Spec.Pauseable = pauseable - } - - if keepVMRaw != "" { - keepVM, err := strconv.ParseBool(keepVMRaw) - if err != nil { - glog.Errorf("error while parsing bool: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - - course.Spec.KeepVM = keepVM - } - - _, updateErr := c.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).Update(c.ctx, course, metav1.UpdateOptions{}) - return updateErr - }) - - if retryErr != nil { - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error attempting to update") - return - } - - util.ReturnHTTPMessage(w, r, 200, "updated", "") - glog.V(4).Infof("Updated course %s", id) - return -} - -func (c CourseServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbDelete)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to to delete courses") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") - return - } - - // when can we safely toDelete c course? - // 1. when there are no active scheduled events using the course - // 2. when there are no sessions using the course - - seList, err := c.hfClientSet.HobbyfarmV1().ScheduledEvents(util.GetReleaseNamespace()).List(c.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error retrieving scheduledevent list: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") - return - } - - seInUse := filterScheduledEvents(id, seList) - - sessList, err := c.hfClientSet.HobbyfarmV1().Sessions(util.GetReleaseNamespace()).List(c.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error retrieving session list: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") - return - } - - sessInUse := filterSessions(id, sessList) - - var msg = "" - toDelete := true - - if len(*seInUse) > 0 { - // cannot toDelete, in use. alert the user - msg += "In use by scheduled events:" - for _, se := range *seInUse { - msg += " " + se.Name - } - toDelete = false - } - - if len(*sessInUse) > 0 { - msg += "In use by sessions:" - for _, sess := range *sessInUse { - msg += " " + sess.Name - } - toDelete = false - } - - if !toDelete { - util.ReturnHTTPMessage(w, r, 403, "badrequest", msg) - return - } - - err = c.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).Delete(c.ctx, id, metav1.DeleteOptions{}) - if err != nil { - glog.Errorf("error deleting course: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") - return - } - - util.ReturnHTTPMessage(w, r, 204, "deleted", "deleted successfully") - glog.V(4).Infof("deleted course: %v", id) -} - -func (c CourseServer) ListCoursesForAccesscode(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - vars := mux.Vars(r) - accessCode := vars["access_code"] - - if accessCode == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "access_code is missing") - return - } - - contains := false - for _, acc := range user.AccessCodes { - if acc == accessCode { - contains = true - break - } - } - - if !contains { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios for this AccessCode") - return - } - - var courseIds []string - tempCourseIds, err := c.acClient.GetCourseIds(accessCode) - if err != nil { - glog.Errorf("error retrieving course ids for access code: %s %v", accessCode, err) - } else { - courseIds = append(courseIds, tempCourseIds...) - } - - courseIds = util.UniqueStringSlice(courseIds) - - var courses []PreparedCourse - for _, courseId := range courseIds { - course, err := c.GetCourseById(courseId) - if err != nil { - glog.Errorf("error retrieving course %v", err) - } else { - course.Spec.Scenarios = c.AppendDynamicScenariosByCategories(course.Spec.Scenarios, course.Spec.Categories) - - pCourse := PreparedCourse{course.Name, course.Spec} - courses = append(courses, pCourse) - } - } - - encodedCourses, err := json.Marshal(courses) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedCourses) -} - -func (c CourseServer) previewDynamicScenarios(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, c.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(rbac2.ResourcePluralScenario, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to preview dynamic scenarios") - return - } - - categories := r.PostFormValue("categories") - categoriesSlice := make([]string, 0) - if categories != "" { - err = json.Unmarshal([]byte(categories), &categoriesSlice) - if err != nil { - glog.Errorf("error while unmarshalling categories %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - scenarios := []string{} - - scenarios = c.AppendDynamicScenariosByCategories(scenarios, categoriesSlice) - - encodedScenarios, err := json.Marshal(scenarios) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) -} - -func (c CourseServer) AppendDynamicScenariosByCategories(scenariosList []string, categories []string) []string { - for _, categoryQuery := range categories { - categorySelectors := []string{} - categoryQueryParts := strings.Split(categoryQuery, "&") - for _, categoryQueryPart := range categoryQueryParts { - operator := "in" - if strings.HasPrefix(categoryQueryPart, "!") { - operator = "notin" - categoryQueryPart = categoryQueryPart[1:] - } - categorySelectors = append(categorySelectors, fmt.Sprintf("category-%s %s (true)", categoryQueryPart, operator)) - } - categorySelectorString := strings.Join(categorySelectors, ",") - - selector, err := labels.Parse(categorySelectorString) - if err != nil { - glog.Errorf("error while parsing label selector %s: %v", categorySelectorString, err) - continue - } - - scenarios, err := c.scenariosLister.Scenarios(util.GetReleaseNamespace()).List(selector) - - if err != nil { - glog.Errorf("error while retrieving scenarios %v", err) - continue - } - for _, scenario := range scenarios { - scenariosList = append(scenariosList, scenario.Name) - } - } - - scenariosList = util.UniqueStringSlice(scenariosList) - return scenariosList -} - -func (c CourseServer) GetCourseById(id string) (hfv1.Course, error) { - if len(id) == 0 { - return hfv1.Course{}, fmt.Errorf("course id passed in was blank") - } - obj, err := c.courseIndexer.ByIndex(idIndex, id) - - if err != nil { - return hfv1.Course{}, fmt.Errorf("error while retrieving course by ID %s %v", id, err) - } - - if len(obj) < 1 { - return hfv1.Course{}, fmt.Errorf("error while retrieving course by ID %s", id) - } - - course, ok := obj[0].(*hfv1.Course) - - if !ok { - return hfv1.Course{}, fmt.Errorf("error while retrieving course by ID %s %v", id, ok) - } - - return *course, nil -} - -// Filter a ScheduledEventList to find SEs that are a) active and b) using the course specified -func filterScheduledEvents(course string, seList *hfv1.ScheduledEventList) *[]hfv1.ScheduledEvent { - outList := make([]hfv1.ScheduledEvent, 0) - for _, se := range seList.Items { - if se.Status.Finished == true { - continue - } - - for _, c := range se.Spec.Courses { - if c == course { - outList = append(outList, se) - break - } - } - } - - return &outList -} - -func filterSessions(course string, list *hfv1.SessionList) *[]hfv1.Session { - outList := make([]hfv1.Session, 0) - for _, sess := range list.Items { - if sess.Spec.CourseId == course { - outList = append(outList, sess) - } - } - - return &outList -} - -func idIndexer(obj interface{}) ([]string, error) { - course, ok := obj.(*hfv1.Course) - if !ok { - return []string{}, nil - } - return []string{course.Name}, nil -} diff --git a/v3/pkg/crd/crd.go b/v3/pkg/crd/crd.go index 27090c73..1096b521 100644 --- a/v3/pkg/crd/crd.go +++ b/v3/pkg/crd/crd.go @@ -1,105 +1,26 @@ package crd import ( + "os" + "github.com/ebauman/crder" + "github.com/golang/glog" v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - terraformv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/terraformcontroller.cattle.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "k8s.io/client-go/rest" ) +// A service managing a resource always needs to implement one of the following CRDInstaller interfaces +type CrdInstaller interface { + GenerateCRDs() []crder.CRD +} +type CrdInstallerWithServiceReference interface { + GenerateCRDs(ca string, serviceReference ServiceReference) []crder.CRD +} + func GenerateCRDs() []crder.CRD { return []crder.CRD{ - hobbyfarmCRD(&v1.VirtualMachine{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.VirtualMachine{}, func(cv *crder.Version) { - cv. - WithColumn("Status", ".status.status"). - WithColumn("Allocated", ".status.allocated"). - WithColumn("PublicIP", ".status.public_ip"). - WithColumn("PrivateIP", ".status.private_ip"). - WithStatus() - }) - }), - hobbyfarmCRD(&v1.VirtualMachineClaim{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.VirtualMachineClaim{}, func(cv *crder.Version) { - cv. - WithColumn("BindMode", ".status.bind_mode"). - WithColumn("Bound", ".status.bound"). - WithColumn("Ready", ".status.ready"). - WithStatus() - }) - }), - hobbyfarmCRD(&v1.VirtualMachineTemplate{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.VirtualMachineTemplate{}, nil) - }), - hobbyfarmCRD(&v1.Environment{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.Environment{}, nil) - }), - hobbyfarmCRD(&v1.VirtualMachineSet{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.VirtualMachineSet{}, func(cv *crder.Version) { - cv. - WithColumn("Available", ".status.available"). - WithColumn("Provisioned", ".status.provisioned"). - WithStatus() - }) - }), - hobbyfarmCRD(&v1.Course{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.Course{}, nil) - }), - hobbyfarmCRD(&v1.Scenario{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.Scenario{}, nil) - }), - hobbyfarmCRD(&v1.Session{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.Session{}, func(cv *crder.Version) { - cv. - WithColumn("Paused", ".status.paused"). - WithColumn("Active", ".status.active"). - WithColumn("Finished", ".status.finished"). - WithColumn("StartTime", ".status.start_time"). - WithColumn("ExpirationTime", ".status.end_time"). - WithStatus() - }) - }), - hobbyfarmCRD(&v1.Progress{}, func(c *crder.CRD) { - c. - WithNames("progress", "progresses"). - IsNamespaced(true). - AddVersion("v1", &v1.Progress{}, func(cv *crder.Version) { - cv. - WithColumn("CurrentStep", ".spec.current_step"). - WithColumn("Course", ".spec.course"). - WithColumn("Scenario", ".spec.scenario"). - WithColumn("User", ".spec.user"). - WithColumn("Started", ".spec.started"). - WithColumn("LastUpdate", ".spec.last_update") - }) - }), - hobbyfarmCRD(&v1.ScheduledEvent{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.ScheduledEvent{}, func(cv *crder.Version) { - cv. - WithColumn("AccessCode", ".spec.access_code"). - WithColumn("Active", ".status.active"). - WithColumn("Finished", ".status.finished"). - WithStatus() - }) - }), - hobbyfarmCRD(&v1.PredefinedService{}, func(c *crder.CRD) { + HobbyfarmCRD(&v1.PredefinedService{}, func(c *crder.CRD) { c. IsNamespaced(true). AddVersion("v1", &v1.PredefinedService{}, func(cv *crder.Version) { @@ -108,45 +29,36 @@ func GenerateCRDs() []crder.CRD { WithColumn("Port", ".spec.port") }) }), - hobbyfarmCRD(&v1.DynamicBindConfiguration{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &v1.DynamicBindConfiguration{}, nil) - }), - terraformCRD(&terraformv1.Module{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &terraformv1.Module{}, func(cv *crder.Version) { - cv. - WithColumn("CheckTime", ".status.time") - }) - }), - terraformCRD(&terraformv1.State{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &terraformv1.State{}, func(cv *crder.Version) { - cv. - WithColumn("LastRunHash", ".status.lasRunHash"). - WithColumn("ExecutionName", ".status.executionName"). - WithColumn("StatePlanName", ".status.executionPlanName") - }) - }), - terraformCRD(&terraformv1.Execution{}, func(c *crder.CRD) { - c. - IsNamespaced(true). - AddVersion("v1", &terraformv1.Execution{}, func(cv *crder.Version) { - cv. - WithColumn("JobName", ".status.jobName"). - WithColumn("PlanConfirmed", ".status.planConfirmed") - }) - }), } } -func hobbyfarmCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { +func HobbyfarmCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { return *crder.NewCRD(obj, "hobbyfarm.io", customize) } -func terraformCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { - return *crder.NewCRD(obj, "terraformcontroller.cattle.io", customize) +func InstallCrds[T CrdInstaller](crdInstaller T, cfg *rest.Config, resourceName string) { + crds := crdInstaller.GenerateCRDs() + installCRDsFunc(cfg, resourceName, crds) +} +func InstallCrdsWithServiceReference[T CrdInstallerWithServiceReference](crdInstaller T, cfg *rest.Config, resourceName string, webhookTlsCa string) { + ca, err := os.ReadFile(webhookTlsCa) + if err != nil { + glog.Fatalf("error reading ca certificate: %s", err.Error()) + } + + crds := crdInstaller.GenerateCRDs(string(ca), ServiceReference{ + Namespace: util.GetReleaseNamespace(), + Name: "hobbyfarm-webhook", + }) + + installCRDsFunc(cfg, resourceName, crds) +} + +func installCRDsFunc(cfg *rest.Config, resourceName string, crds []crder.CRD) { + glog.Infof("installing/updating %s CRDs", resourceName) + err := crder.InstallUpdateCRDs(cfg, crds...) + if err != nil { + glog.Fatalf("failed installing/updating %s CRDs: %s", resourceName, err.Error()) + } + glog.Infof("finished installing/updating %s CRDs", resourceName) } diff --git a/v3/pkg/environmentserver/environmentserver.go b/v3/pkg/environmentserver/environmentserver.go deleted file mode 100644 index 0c002f0b..00000000 --- a/v3/pkg/environmentserver/environmentserver.go +++ /dev/null @@ -1,451 +0,0 @@ -package environmentserver - -import ( - "context" - "crypto/sha256" - "encoding/base32" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - "strings" - "time" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/util/retry" -) - -const ( - resourcePlural = rbac2.ResourcePluralEnvironment -) - -type EnvironmentServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context -} - -func NewEnvironmentServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*EnvironmentServer, error) { - es := EnvironmentServer{} - - es.hfClientSet = hfClientset - es.authnClient = authnClient - es.authrClient = authrClient - es.ctx = ctx - - return &es, nil -} - -func (e EnvironmentServer) getEnvironment(id string) (hfv1.Environment, error) { - - empty := hfv1.Environment{} - - if len(id) == 0 { - return empty, fmt.Errorf("vm claim id passed in was empty") - } - - obj, err := e.hfClientSet.HobbyfarmV1().Environments(util.GetReleaseNamespace()).Get(e.ctx, id, metav1.GetOptions{}) - if err != nil { - return empty, fmt.Errorf("error while retrieving Environment by id: %s with error: %v", id, err) - } - - return *obj, nil - -} - -func (e EnvironmentServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/a/environment/list", e.ListFunc).Methods("GET") - r.HandleFunc("/a/environment/{id}", e.GetFunc).Methods("GET") - r.HandleFunc("/a/environment/create", e.CreateFunc).Methods("POST") - r.HandleFunc("/a/environment/{id}/update", e.UpdateFunc).Methods("PUT") - r.HandleFunc("/a/environment/{environment_id}/available", e.PostEnvironmentAvailableFunc).Methods("POST") - glog.V(2).Infof("set up routes for environment server") -} - -type PreparedEnvironment struct { - Name string `json:"name"` - hfv1.EnvironmentSpec -} - -type PreparedListEnvironment struct { - Name string `json:"name"` - DisplayName string `json:"display_name"` - Provider string `json:"provider"` - TemplateMapping map[string]map[string]string `json:"template_mapping"` -} - -func (e EnvironmentServer) GetFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, e.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get environment") - return - } - - vars := mux.Vars(r) - - environmentId := vars["id"] - - if len(environmentId) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no environment id passed in") - return - } - - environment, err := e.getEnvironment(environmentId) - - if err != nil { - glog.Errorf("error while retrieving environment %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no environment found") - return - } - - preparedEnvironment := PreparedEnvironment{environment.Name, environment.Spec} - - encodedEnvironment, err := json.Marshal(preparedEnvironment) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironment) - - glog.V(2).Infof("retrieved environment %s", environment.Name) -} - -func (e EnvironmentServer) ListFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, e.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list environments") - return - } - - environments, err := e.hfClientSet.HobbyfarmV1().Environments(util.GetReleaseNamespace()).List(e.ctx, metav1.ListOptions{}) - - if err != nil { - glog.Errorf("error while listing all environments %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "error listing all environments") - return - } - - preparedEnvironments := []PreparedListEnvironment{} // must be declared this way so as to JSON marshal into [] instead of null - - for _, e := range environments.Items { - keys := make(map[string]map[string]string) - for k, _ := range e.Spec.TemplateMapping { - keys[k] = map[string]string{} - } - preparedEnvironments = append(preparedEnvironments, PreparedListEnvironment{e.Name, e.Spec.DisplayName, e.Spec.Provider, keys}) - } - - encodedEnvironments, err := json.Marshal(preparedEnvironments) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironments) - - glog.V(2).Infof("retrieved list of all environments") -} - -func (e EnvironmentServer) CreateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, e.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create environments") - return - } - - displayName := r.PostFormValue("display_name") - if displayName == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no display_name passed in") - return - } - - dnssuffix := r.PostFormValue("dnssuffix") - // dnssuffix optional so no validation performed - - provider := r.PostFormValue("provider") - if provider == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no provider passed in") - return - } - - templateMapping := r.PostFormValue("template_mapping") - if templateMapping == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no template_mapping passed in") - return - } - - environmentSpecifics := r.PostFormValue("environment_specifics") - if environmentSpecifics == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no environment_specifics passed in") - return - } - - countCapacity := r.PostFormValue("count_capacity") - if environmentSpecifics == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no count_capacity passed in") - return - } - - ipTranslationMap := r.PostFormValue("ip_translation_map") - if ipTranslationMap == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ip_translation_map passed in") - return - } - - wsEndpoint := r.PostFormValue("ws_endpoint") - if wsEndpoint == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ws_endpoint passed in") - return - } - - templateMappingUnmarshaled := map[string]map[string]string{} // lol - err = json.Unmarshal([]byte(templateMapping), &templateMappingUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling template_mapping (create environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - countCapacityUnmarshaled := map[string]int{} - err = json.Unmarshal([]byte(countCapacity), &countCapacityUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling count_capacity (create environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - environmentSpecificsUnmarshaled := map[string]string{} - err = json.Unmarshal([]byte(environmentSpecifics), &environmentSpecificsUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling environment_specifics (create environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - ipTranslationUnmarshaled := map[string]string{} - err = json.Unmarshal([]byte(ipTranslationMap), &ipTranslationUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling ip_translation_map (create environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - environment := &hfv1.Environment{} - hasher := sha256.New() - hasher.Write([]byte(time.Now().String())) // generate random name - sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] - environment.Name = "env-" + strings.ToLower(sha) - - environment.Spec.DisplayName = displayName - environment.Spec.DNSSuffix = dnssuffix - environment.Spec.Provider = provider - environment.Spec.TemplateMapping = templateMappingUnmarshaled - environment.Spec.EnvironmentSpecifics = environmentSpecificsUnmarshaled - environment.Spec.IPTranslationMap = ipTranslationUnmarshaled - environment.Spec.WsEndpoint = wsEndpoint - environment.Spec.CountCapacity = countCapacityUnmarshaled - - environment, err = e.hfClientSet.HobbyfarmV1().Environments(util.GetReleaseNamespace()).Create(e.ctx, environment, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating environment %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating environment") - return - } - - util.ReturnHTTPMessage(w, r, 201, "created", environment.Name) - return -} - -func (e EnvironmentServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, e.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update environment") - return - } - - vars := mux.Vars(r) - - environmentId := vars["id"] - if len(environmentId) == 0 { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no environment id passed in") - return - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - environment, err := e.getEnvironment(environmentId) - if err != nil { - glog.Errorf("error while retrieving environment %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no environment found") - return fmt.Errorf("bad") - } - - displayName := r.PostFormValue("display_name") - dnssuffix := r.PostFormValue("dnssuffix") - provider := r.PostFormValue("provider") - templateMapping := r.PostFormValue("template_mapping") - environmentSpecifics := r.PostFormValue("environment_specifics") - ipTranslationMap := r.PostFormValue("ip_translation_map") - wsEndpoint := r.PostFormValue("ws_endpoint") - countCapacity := r.PostFormValue("count_capacity") - - if len(displayName) > 0 { - environment.Spec.DisplayName = displayName - } - - // empty string is e valid dnssuffix value (because it is optional), so not - // performing string length check here - environment.Spec.DNSSuffix = dnssuffix - - if len(provider) > 0 { - environment.Spec.Provider = provider - } - - if len(templateMapping) > 0 { - templateMappingUnmarshaled := map[string]map[string]string{} // lol - err = json.Unmarshal([]byte(templateMapping), &templateMappingUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling template_mapping (update environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - environment.Spec.TemplateMapping = templateMappingUnmarshaled - } - - if len(environmentSpecifics) > 0 { - environmentSpecificsUnmarshaled := map[string]string{} - err = json.Unmarshal([]byte(environmentSpecifics), &environmentSpecificsUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling environment_specifics (update environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - environment.Spec.EnvironmentSpecifics = environmentSpecificsUnmarshaled - } - - if len(countCapacity) > 0 { - countCapacityUnmarshaled := map[string]int{} - err = json.Unmarshal([]byte(countCapacity), &countCapacityUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling count_capacity (update environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - environment.Spec.CountCapacity = countCapacityUnmarshaled - } - - if len(ipTranslationMap) > 0 { - ipTranslationUnmarshaled := map[string]string{} - err = json.Unmarshal([]byte(ipTranslationMap), &ipTranslationUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling ip_translation_map (update environment) %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - environment.Spec.IPTranslationMap = ipTranslationUnmarshaled - } - - if len(wsEndpoint) > 0 { - environment.Spec.WsEndpoint = wsEndpoint - } - - _, updateErr := e.hfClientSet.HobbyfarmV1().Environments(util.GetReleaseNamespace()).Update(e.ctx, &environment, metav1.UpdateOptions{}) - return updateErr - }) - - if retryErr != nil { - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error attempting to update") - return - } - - util.ReturnHTTPMessage(w, r, 200, "updated", "") - return -} - -func (e EnvironmentServer) PostEnvironmentAvailableFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, e.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.Authorize(r, e.authrClient, impersonatedUserId, []*authr.Permission{ - rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList), - rbac2.HobbyfarmPermission(rbac2.ResourcePluralVMTemplate, rbac2.VerbList), - }, rbac2.OperatorAND) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list environments") - return - } - - vars := mux.Vars(r) - - start := r.PostFormValue("start") - end := r.PostFormValue("end") - if start == "" || end == "" { - util.ReturnHTTPMessage(w, r, 400, "bad request", "start or end time not provided") - return - } - - environmentId := vars["environment_id"] - - if len(environmentId) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no environment id passed in") - return - } - - environment, err := e.getEnvironment(environmentId) - - if err != nil { - glog.Errorf("error while retrieving environment %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no environment found") - return - } - max, err := util.MaxAvailableDuringPeriod(e.hfClientSet, environmentId, start, end, e.ctx) - if err != nil { - glog.Errorf("error while getting max available %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "error getting max available vms for environment") - return - } - - encodedEnvironment, err := json.Marshal(max) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironment) - - glog.V(2).Infof("retrieved max available in environment %s", environment.Name) -} diff --git a/v3/pkg/errors/errors.go b/v3/pkg/errors/errors.go index 9b7cc473..4bc60cf5 100644 --- a/v3/pkg/errors/errors.go +++ b/v3/pkg/errors/errors.go @@ -1,5 +1,22 @@ package errors +import ( + "fmt" + "strings" + + "github.com/golang/protobuf/proto" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// IdGetterProtoMessage is an interface that combines the GetId() function and the proto.Message interface. +// general.GetRequest and general.ResourceId do implement this interface +type IdGetterProtoMessage interface { + proto.Message + GetId() string +} + type HobbyfarmError struct { Code int Message string @@ -26,3 +43,95 @@ func IsAlreadyExists(err error) bool { return he.Code == 409 } + +// generic function which returns a standard gRPC status error +// @c: The gRPC error code which specifies the kind of our error +// @format: The formatted error message to return +// @details: A proto message +// @a: The arguments for the formatted error message +func GrpcError[T proto.Message](c codes.Code, format string, details T, a ...any) error { + err := status.Newf( + c, + format, + a..., + ) + err, wde := err.WithDetails(details) + if wde != nil { + return wde + } + return err.Err() +} + +func GrpcBadRequestError[T proto.Message](protoMessage T, propName string, propValue string) error { + return GrpcError[proto.Message](codes.InvalidArgument, "invalid value \"%s\" for property %s", protoMessage, propValue, propName) +} + +func GrpcNotSpecifiedError[T proto.Message](protoMessage T, propName string) error { + return GrpcError[proto.Message](codes.InvalidArgument, "missing %s", protoMessage, propName) +} + +func GrpcIdNotSpecifiedError[T proto.Message](protoMessage T) error { + return GrpcError[proto.Message](codes.InvalidArgument, "no id specified", protoMessage) +} + +func GrpcNotFoundError[T IdGetterProtoMessage](resourceId T, resourceName string) error { + id := resourceId.GetId() + return GrpcError[T](codes.NotFound, "could not find %s for id %s", resourceId, resourceName, id) +} + +func IsGrpcNotFound(err error) bool { + return status.Code(err) == codes.NotFound +} +func IsGrpcParsingError(err error) bool { + statusErr := status.Convert(err) + return statusErr.Code() == codes.Internal && strings.HasPrefix(statusErr.Message(), "error parsing") +} + +func GrpcGetError(req *generalpb.GetRequest, resourceName string, err error) error { + return GrpcError[*generalpb.GetRequest]( + codes.Internal, + "error while retreiving %s by id %s with error: %v", + req, + resourceName, + req.GetId(), + err, + ) +} + +func GrpcListError(listOptions *generalpb.ListOptions, resourceName string) error { + return GrpcError[*generalpb.ListOptions](codes.Internal, "error retreiving %s", listOptions, resourceName) +} + +func GrpcCacheError[T proto.Message](protoMessage T, resourceName string) error { + return GrpcError[proto.Message](codes.Unavailable, "error while retreiving %s: cache is not properly synced yet", protoMessage, resourceName) +} + +func GrpcParsingError[T proto.Message](protoMessage T, propName string) error { + return GrpcError[proto.Message](codes.Internal, "error parsing %s", protoMessage, propName) +} + +func GetErrorMessage(err error) string { + if err == nil { + return "" + } + st, ok := status.FromError(err) + if !ok { + // not a gRPC error + return err.Error() + } + return st.Message() +} + +// Generic function to handle different types of details +func ExtractDetail[T proto.Message](s *status.Status) (T, error) { + var zeroValue T + + if len(s.Details()) > 0 { + for _, detail := range s.Details() { + if details, ok := detail.(T); ok { + return details, nil + } + } + } + return zeroValue, fmt.Errorf("no details of the expected type found in the error status") +} diff --git a/v3/pkg/labels/labels.go b/v3/pkg/labels/labels.go index d313be36..44874ff6 100644 --- a/v3/pkg/labels/labels.go +++ b/v3/pkg/labels/labels.go @@ -1,13 +1,33 @@ package labels -import "strings" +import ( + "strings" +) const ( - SettingScope = "hobbyfarm.io/setting-scope" - SettingWeight = "hobbyfarm.io/setting-weight" - SettingGroup = "hobbyfarm.io/setting-group" + SettingScope = "hobbyfarm.io/setting-scope" + SettingWeight = "hobbyfarm.io/setting-weight" + SettingGroup = "hobbyfarm.io/setting-group" + AccessCodeLabel = "hobbyfarm.io/accesscode" + OneTimeAccessCodeLabel = "hobbyfarm.io/otac" + ScheduledEventLabel = "hobbyfarm.io/scheduledevent" + SessionLabel = "hobbyfarm.io/session" + UserLabel = "hobbyfarm.io/user" + RBACManagedLabel = "rbac.hobbyfarm.io/managed" + EnvironmentLabel = "hobbyfarm.io/environment" + VirtualMachineTemplate = "hobbyfarm.io/virtualmachinetemplate" ) func DotEscapeLabel(label string) string { return strings.ReplaceAll(label, ".", "\\.") } + +func UpdateCategoryLabels(labels map[string]string, oldCategories []string, newCategories []string) map[string]string { + for _, category := range oldCategories { + labels["category-"+category] = "false" + } + for _, category := range newCategories { + labels["category-"+category] = "true" + } + return labels +} diff --git a/v3/pkg/microservices/controller/controller.go b/v3/pkg/microservices/controller/controller.go index 55d09143..168b53c0 100644 --- a/v3/pkg/microservices/controller/controller.go +++ b/v3/pkg/microservices/controller/controller.go @@ -126,7 +126,7 @@ func (c *BaseController) enqueue(obj interface{}) { var key string var err error if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - glog.V(4).Infof("Error enquing %s: %v", key, err) + glog.V(4).Infof("Error enqueueing %s: %v", key, err) return } glog.V(4).Infof("Enqueueing: %s", key) diff --git a/v3/pkg/microservices/controller/delayingWorkqueueController.go b/v3/pkg/microservices/controller/delayingWorkqueueController.go index 39e5e367..eb8dc11a 100644 --- a/v3/pkg/microservices/controller/delayingWorkqueueController.go +++ b/v3/pkg/microservices/controller/delayingWorkqueueController.go @@ -14,12 +14,15 @@ type DelayingWorkqueueController struct { ShardedController } -func NewDelayingWorkqueueController(ctx context.Context, informer cache.SharedIndexInformer, kubeClient *kubernetes.Clientset, name string, resyncPeriod time.Duration) *DelayingWorkqueueController { +func NewDelayingWorkqueueController(ctx context.Context, informer cache.SharedIndexInformer, kubeClient *kubernetes.Clientset, name string, resyncPeriod time.Duration, queue workqueue.DelayingInterface) *DelayingWorkqueueController { dwqc := &DelayingWorkqueueController{ *NewShardedController(ctx, informer, kubeClient, name, resyncPeriod), } - - dwqc.SetWorkqueue(workqueue.NewDelayingQueueWithConfig(workqueue.DelayingQueueConfig{Name: name})) + if queue != nil { + dwqc.SetWorkqueue(queue) + } else { + dwqc.SetWorkqueue(workqueue.NewDelayingQueueWithConfig(workqueue.DelayingQueueConfig{Name: name})) + } return dwqc } @@ -27,7 +30,7 @@ func NewDelayingWorkqueueController(ctx context.Context, informer cache.SharedIn func (dwq *DelayingWorkqueueController) GetDelayingWorkqueue() (workqueue.DelayingInterface, error) { delayingQueue, ok := dwq.GetWorkqueue().(workqueue.DelayingInterface) if !ok { - return nil, fmt.Errorf("Workqueue is not a DelayingQueue") + return nil, fmt.Errorf("workqueue is not a DelayingQueue") } return delayingQueue, nil } diff --git a/v3/pkg/microservices/controller/rateLimitingWorkqueueController.go b/v3/pkg/microservices/controller/rateLimitingWorkqueueController.go index 078fa630..c738ea9c 100644 --- a/v3/pkg/microservices/controller/rateLimitingWorkqueueController.go +++ b/v3/pkg/microservices/controller/rateLimitingWorkqueueController.go @@ -14,7 +14,7 @@ type RateLimitingWorkqueueController struct { ShardedController } -func NewRateLimitingWorkqueueController(ctx context.Context, informer cache.SharedIndexInformer, kubeClient *kubernetes.Clientset, reconcileFunc func(objName string) error, name string, resyncPeriod time.Duration, rateLimiter workqueue.RateLimiter) *RateLimitingWorkqueueController { +func NewRateLimitingWorkqueueController(ctx context.Context, informer cache.SharedIndexInformer, kubeClient *kubernetes.Clientset, name string, resyncPeriod time.Duration, rateLimiter workqueue.RateLimiter) *RateLimitingWorkqueueController { rlwq := &RateLimitingWorkqueueController{ *NewShardedController(ctx, informer, kubeClient, name, resyncPeriod), } @@ -27,7 +27,7 @@ func NewRateLimitingWorkqueueController(ctx context.Context, informer cache.Shar func (rlwq *RateLimitingWorkqueueController) GetRateLimitingWorkqueue() (workqueue.RateLimitingInterface, error) { rateLimitingQueue, ok := rlwq.GetWorkqueue().(workqueue.RateLimitingInterface) if !ok { - return nil, fmt.Errorf("Workqueue is not a DelayingQueue") + return nil, fmt.Errorf("Workqueue is not a RateLimitingQueue") } return rateLimitingQueue, nil } diff --git a/v3/pkg/microservices/controller/shardedController.go b/v3/pkg/microservices/controller/shardedController.go index ed576185..179d6058 100644 --- a/v3/pkg/microservices/controller/shardedController.go +++ b/v3/pkg/microservices/controller/shardedController.go @@ -2,7 +2,6 @@ package microservices import ( "context" - "encoding/binary" "fmt" "hash/fnv" "io" @@ -12,6 +11,7 @@ import ( "time" "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" "github.com/hobbyfarm/gargantua/v3/pkg/util" v1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/fields" @@ -76,24 +76,16 @@ func (c *ShardedController) getShardPlacement(obj interface{}) (int, error) { panic(err) } - //store the has as bytearray - hash := hasher.Sum(nil) - - // convert the hash into an integer by truncating it - truncatedHash := int(binary.BigEndian.Uint32(hash[:4])) - - if truncatedHash < 0 { - //Ensure only positive values are taken - truncatedHash = -truncatedHash - } + //store the has as 32-bit unsigned int + hash := hasher.Sum32() // return the hash modulo the total replica count, this creates an almost equally distributed placement - return truncatedHash % c.replica_count, nil + return int(hash) % c.replica_count, nil } // RunSharded will start a sharded controller that watches the parent StatefulSet and applies sharding based on the total replica count -func (c *ShardedController) RunSharded(stopCh <-chan struct{}, statefulSetName string) error { - c.statefulset_name = statefulSetName +func (c *ShardedController) RunSharded(stopCh <-chan struct{}, statefulSetName microservices.MicroService) error { + c.statefulset_name = string(statefulSetName) podIdentityName, err := os.Hostname() if err != nil { return fmt.Errorf("Error in getting Hostname") diff --git a/v3/pkg/microservices/microservices.go b/v3/pkg/microservices/microservices.go index aba028fb..eaea4194 100644 --- a/v3/pkg/microservices/microservices.go +++ b/v3/pkg/microservices/microservices.go @@ -52,12 +52,24 @@ type ServiceConfig struct { } const ( - AuthN MicroService = "authn-service" - AuthR MicroService = "authr-service" - User MicroService = "user-service" - Rbac MicroService = "rbac-service" - AccessCode MicroService = "accesscode-service" - Setting MicroService = "setting-service" + AccessCode MicroService = "accesscode-service" + AuthN MicroService = "authn-service" + AuthR MicroService = "authr-service" + Course MicroService = "course-service" + DBConfig MicroService = "dbconfig-service" + Environment MicroService = "environment-service" + Progress MicroService = "progress-service" + Rbac MicroService = "rbac-service" + Scenario MicroService = "scenario-service" + ScheduledEvent MicroService = "scheduledevent-service" + Session MicroService = "session-service" + Setting MicroService = "setting-service" + Terraform MicroService = "terraform-service" + User MicroService = "user-service" + VMClaim MicroService = "vmclaim-service" + VMSet MicroService = "vmset-service" + VM MicroService = "vm-service" + VMTemplate MicroService = "vmtemplate-service" ) const ( @@ -361,8 +373,6 @@ func GetWorkerThreadCount() int { i, err := strconv.Atoi(workerThreadCountString) if err != nil { glog.Infof("Error parsing env var CONTROLLER_THREAD_COUNT, using default thread count %d", workerThreads) - } else { - } workerThreads = i } diff --git a/v3/pkg/predefinedserviceserver/predefinedserviceserver.go b/v3/pkg/predefinedserviceserver/predefinedserviceserver.go index f89369d6..83aa5864 100644 --- a/v3/pkg/predefinedserviceserver/predefinedserviceserver.go +++ b/v3/pkg/predefinedserviceserver/predefinedserviceserver.go @@ -3,16 +3,17 @@ package predefinedservicesserver import ( "context" "encoding/json" + "net/http" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" "github.com/golang/glog" "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -22,13 +23,13 @@ type AdminPreparedPredefinedService struct { } type PredefinedServiceServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient hfClientSet hfClientset.Interface ctx context.Context } -func NewPredefinedServiceServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*PredefinedServiceServer, error) { +func NewPredefinedServiceServer(authnClient authnpb.AuthNClient, authrClient authrpb.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*PredefinedServiceServer, error) { pss := PredefinedServiceServer{} pss.hfClientSet = hfClientset diff --git a/v3/pkg/progressserver/progressserver.go b/v3/pkg/progressserver/progressserver.go deleted file mode 100644 index cb1fba5d..00000000 --- a/v3/pkg/progressserver/progressserver.go +++ /dev/null @@ -1,382 +0,0 @@ -package progressserver - -import ( - "context" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - "strconv" - "time" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/util/retry" -) - -const ( - idIndex = "progressserver.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralProgress -) - -type ProgressServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context -} - -type AdminPreparedProgress struct { - ID string `json:"id"` - Session string `json:"session"` - hfv1.ProgressSpec -} - -type AdminPreparedProgressWithScheduledEvent struct { - ID string `json:"id"` - Session string `json:"session"` - hfv1.ProgressSpec - ScheduledEvent string `json:"scheduled_event"` -} - -type ScheduledEventProgressCount struct { - CountMap map[string]int `json:"count_map"` -} - -func NewProgressServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*ProgressServer, error) { - progress := ProgressServer{} - - progress.hfClientSet = hfClientset - progress.authnClient = authnClient - progress.authrClient = authrClient - progress.ctx = ctx - return &progress, nil -} - -func (s ProgressServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/a/progress/scheduledevent/{id}", s.ListByScheduledEventFunc).Methods("GET") - r.HandleFunc("/a/progress/user/{id}", s.ListByUserFunc).Methods("GET") - r.HandleFunc("/a/progress/count", s.CountByScheduledEvent).Methods("GET") - r.HandleFunc("/a/progress/range", s.ListByRangeFunc).Methods("GET") - r.HandleFunc("/progress/update/{id}", s.Update).Methods("POST") - r.HandleFunc("/progress/list", s.ListForUserFunc).Methods("GET") - glog.V(2).Infof("set up routes for ProgressServer") -} - -/* -List Progress by Scheduled Event - - Vars: - - id : The scheduled event id -*/ -func (s ProgressServer) ListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - includeFinished := false - includeFinishedParam := r.URL.Query().Get("includeFinished") - if includeFinishedParam != "" && includeFinishedParam != "false" { - includeFinished = true - } - - s.ListByLabel(w, r, util2.ScheduledEventLabel, id, includeFinished) - - glog.V(2).Infof("listed progress for scheduledevent %s", id) -} - -func (s ProgressServer) ListByRangeFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") - return - } - - fromString := r.URL.Query().Get("from") - if fromString == "" { - util2.ReturnHTTPMessage(w, r, 500, "error", "no start of range passed in") - return - } - - start, err := time.Parse(time.UnixDate, fromString) - - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "error", "error parsing start time") - return - } - - toString := r.URL.Query().Get("to") - if toString == "" { - util2.ReturnHTTPMessage(w, r, 500, "error", "no end of range passed in") - return - } - - end, err := time.Parse(time.UnixDate, toString) - - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "error", "error parsing end time") - return - } - - s.ListByRange(w, r, start, end, true) - - glog.V(2).Info("listed progress for time range") -} - -/* -List Progress for the authenticated user -*/ -func (s ProgressServer) ListForUserFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") - return - } - - s.ListByLabel(w, r, util2.UserLabel, user.GetId(), true) -} - -/* -List Progress by User - - Vars: - - id : The user id -*/ -func (s ProgressServer) ListByUserFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - s.ListByLabel(w, r, util2.UserLabel, id, true) - - glog.V(2).Infof("listed progress for user %s", id) -} - -func (s ProgressServer) CountByScheduledEvent(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") - return - } - - progress, err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", "finished", "false")}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no progress found") - return - } - countMap := map[string]int{} - for _, p := range progress.Items { - se := p.Labels[util2.ScheduledEventLabel] - if _, ok := countMap[se]; ok { - countMap[se] = countMap[se] + 1 - } else { - countMap[se] = 1 - } - } - - encodedMap, err := json.Marshal(countMap) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedMap) -} - -func (s ProgressServer) ListByRange(w http.ResponseWriter, r *http.Request, start time.Time, end time.Time, includeFinished bool) { - includeFinishedFilter := "finished=false" // Default is to only include active (finished=false) progress - if includeFinished { - includeFinishedFilter = "" - } - progress, err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s", includeFinishedFilter)}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no progress found") - return - } - - v1TimeStart := metav1.NewTime(start) - v1TimeEnd := metav1.NewTime(end) - - preparedProgress := []AdminPreparedProgressWithScheduledEvent{} - for _, p := range progress.Items { - //CreationTimestamp of progress is out of range - if p.CreationTimestamp.Before(&v1TimeStart) || v1TimeEnd.Before(&p.CreationTimestamp) { - continue - } - pProgressWithScenarioName := AdminPreparedProgressWithScheduledEvent{p.Name, p.Labels[util2.SessionLabel], p.Spec, p.Labels[util2.ScheduledEventLabel]} - preparedProgress = append(preparedProgress, pProgressWithScenarioName) - } - - encodedProgress, err := json.Marshal(preparedProgress) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedProgress) -} - -func (s ProgressServer) ListByLabel(w http.ResponseWriter, r *http.Request, label string, value string, includeFinished bool) { - includeFinishedFilter := ",finished=false" // Default is to only include active (finished=false) progress - if includeFinished { - includeFinishedFilter = "" - } - progress, err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s%s", label, value, includeFinishedFilter)}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no progress found") - return - } - - preparedProgress := []AdminPreparedProgress{} - for _, p := range progress.Items { - pProgress := AdminPreparedProgress{p.Name, p.Labels[util2.SessionLabel], p.Spec} - preparedProgress = append(preparedProgress, pProgress) - } - - encodedProgress, err := json.Marshal(preparedProgress) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedProgress) -} - -/* -Update Progress - - Vars: - - id : Session linked to the progress resource -*/ -func (s ProgressServer) Update(w http.ResponseWriter, r *http.Request) { - now := time.Now() - - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update progress") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - stepRaw := r.PostFormValue("step") - if stepRaw == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no step was passed in") - return - } - - step, err := strconv.Atoi(stepRaw) - if err != nil { - glog.Errorf("error while converting step %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "provided step was invalid") - return - } - - progress, err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,%s=%s,finished=false", util2.SessionLabel, id, util2.UserLabel, user.GetId())}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no active progress for this session found") - return - } - - if len(progress.Items) < 1 { - util2.ReturnHTTPMessage(w, r, 404, "error", "no active progress for this session found") - return - } - - for _, p := range progress.Items { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - if step > p.Spec.MaxStep { - p.Spec.MaxStep = step - } - p.Spec.CurrentStep = step - p.Spec.LastUpdate = now.Format(time.UnixDate) - - steps := p.Spec.Steps - newStep := hfv1.ProgressStep{Step: step, Timestamp: now.Format(time.UnixDate)} - steps = append(steps, newStep) - p.Spec.Steps = steps - - _, updateErr := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).Update(s.ctx, &p, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for environment") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error updating progress %s: %v", p.Name, err) - util2.ReturnHTTPMessage(w, r, 500, "error", "progress could not be updated") - return - } - } - - util2.ReturnHTTPMessage(w, r, 200, "success", "Progress was updated") -} diff --git a/v3/pkg/rbac/auth.go b/v3/pkg/rbac/auth.go index 34ce26be..1c64a37b 100644 --- a/v3/pkg/rbac/auth.go +++ b/v3/pkg/rbac/auth.go @@ -3,51 +3,51 @@ package rbac import ( "net/http" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" ) -func AuthenticateRequest(r *http.Request, authnClient authn.AuthNClient) (*userProto.User, error) { +func AuthenticateRequest(r *http.Request, authnClient authnpb.AuthNClient) (*userpb.User, error) { token := r.Header.Get("Authorization") - return authnClient.AuthN(r.Context(), &authn.AuthNRequest{Token: token}) + return authnClient.AuthN(r.Context(), &authnpb.AuthNRequest{Token: token}) } -func AuthenticateWS(r *http.Request, authnClient authn.AuthNClient) (*userProto.User, error) { +func AuthenticateWS(r *http.Request, authnClient authnpb.AuthNClient) (*userpb.User, error) { token := "Bearer " + r.URL.Query().Get("auth") - return authnClient.AuthN(r.Context(), &authn.AuthNRequest{Token: token}) + return authnClient.AuthN(r.Context(), &authnpb.AuthNRequest{Token: token}) } -func AuthorizeSimple(r *http.Request, authrClient authr.AuthRClient, username string, permission *authr.Permission) (*authr.AuthRResponse, error) { - rbacPermissions := []*authr.Permission{ +func AuthorizeSimple(r *http.Request, authrClient authrpb.AuthRClient, username string, permission *authrpb.Permission) (*authrpb.AuthRResponse, error) { + rbacPermissions := []*authrpb.Permission{ permission, } - rbacRq := &authr.RbacRequest{ + rbacRq := &authrpb.RbacRequest{ Permissions: rbacPermissions, } - return authrClient.AuthR(r.Context(), &authr.AuthRRequest{UserName: username, Request: rbacRq}) + return authrClient.AuthR(r.Context(), &authrpb.AuthRRequest{UserName: username, Request: rbacRq}) } -func Authorize(r *http.Request, authrClient authr.AuthRClient, username string, permissions []*authr.Permission, operator string) (*authr.AuthRResponse, error) { - rbacRq := &authr.RbacRequest{ +func Authorize(r *http.Request, authrClient authrpb.AuthRClient, username string, permissions []*authrpb.Permission, operator string) (*authrpb.AuthRResponse, error) { + rbacRq := &authrpb.RbacRequest{ Operator: operator, Permissions: permissions, } - return authrClient.AuthR(r.Context(), &authr.AuthRRequest{UserName: username, Request: rbacRq}) + return authrClient.AuthR(r.Context(), &authrpb.AuthRRequest{UserName: username, Request: rbacRq}) } -func Permission(apiGroup string, resource string, verb string) *authr.Permission { - return &authr.Permission{ +func Permission(apiGroup string, resource string, verb string) *authrpb.Permission { + return &authrpb.Permission{ ApiGroup: apiGroup, Resource: resource, Verb: verb, } } -func HobbyfarmPermission(resource string, verb string) *authr.Permission { +func HobbyfarmPermission(resource string, verb string) *authrpb.Permission { return Permission(HobbyfarmGroup, resource, verb) } -func RbacPermission(resource string, verb string) *authr.Permission { +func RbacPermission(resource string, verb string) *authrpb.Permission { return Permission(RbacGroup, resource, verb) } diff --git a/v3/pkg/scenarioclient/scenarioclient.go b/v3/pkg/scenarioclient/scenarioclient.go deleted file mode 100644 index dd578188..00000000 --- a/v3/pkg/scenarioclient/scenarioclient.go +++ /dev/null @@ -1,28 +0,0 @@ -package scenarioclient - -import ( - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - "github.com/hobbyfarm/gargantua/v3/pkg/scenarioserver" -) - -type ScenarioClient struct { - sServer *scenarioserver.ScenarioServer -} - -func NewScenarioClient(sServer *scenarioserver.ScenarioServer) (*ScenarioClient, error) { - a := ScenarioClient{} - - a.sServer = sServer - return &a, nil -} - -func (sc ScenarioClient) GetScenarioById(id string) (hfv1.Scenario, error) { - - sResult, err := sc.sServer.GetScenarioById(id) - - if err != nil { - return hfv1.Scenario{}, err - } - - return sResult, nil -} diff --git a/v3/pkg/scenarioserver/scenarioserver.go b/v3/pkg/scenarioserver/scenarioserver.go deleted file mode 100644 index ba3ad0f2..00000000 --- a/v3/pkg/scenarioserver/scenarioserver.go +++ /dev/null @@ -1,1107 +0,0 @@ -package scenarioserver - -import ( - "context" - "crypto/sha256" - "encoding/base32" - "encoding/base64" - "encoding/json" - "fmt" - "net/http" - "slices" - "strconv" - "strings" - - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/pkg/courseclient" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - - "github.com/golang/glog" - "github.com/gorilla/mux" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" -) - -const ( - idIndex = "scenarioserver.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralScenario -) - -type ScenarioServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - acClient *accesscode.AccessCodeClient - scenarioIndexer cache.Indexer - ctx context.Context - courseClient *courseclient.CourseClient -} - -type PreparedScenarioStep struct { - Title string `json:"title"` - Content string `json:"content"` -} - -type PreparedScenario struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - StepCount int `json:"stepcount"` - VirtualMachines []map[string]string `json:"virtualmachines"` - Pauseable bool `json:"pauseable"` - Printable bool `json:"printable"` - Tasks []hfv1.VirtualMachineTasks `json:"vm_tasks"` -} - -type AdminPreparedScenario struct { - ID string `json:"id"` - hfv1.ScenarioSpec -} - -func NewScenarioServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, acClient *accesscode.AccessCodeClient, hfClientset hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context, courseClient *courseclient.CourseClient) (*ScenarioServer, error) { - scenario := ScenarioServer{} - - scenario.authnClient = authnClient - scenario.authrClient = authrClient - - scenario.hfClientSet = hfClientset - scenario.acClient = acClient - scenario.courseClient = courseClient - inf := hfInformerFactory.Hobbyfarm().V1().Scenarios().Informer() - indexers := map[string]cache.IndexFunc{idIndex: idIndexer} - err := inf.AddIndexers(indexers) - if err != nil { - glog.Errorf("error adding scenario indexer %s", idIndex) - } - scenario.scenarioIndexer = inf.GetIndexer() - scenario.ctx = ctx - return &scenario, nil -} - -func (s ScenarioServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/scenario/list/{access_code}", s.ListScenariosForAccessCode).Methods("GET") - r.HandleFunc("/a/scenario/categories", s.ListCategories).Methods("GET") - r.HandleFunc("/a/scenario/list/{category}", s.ListByCategoryFunc).Methods("GET") - r.HandleFunc("/a/scenario/list", s.ListAllFunc).Methods("GET") - r.HandleFunc("/a/scenario/{id}", s.AdminGetFunc).Methods("GET") - r.HandleFunc("/a/scenario/{id}", s.AdminDeleteFunc).Methods("DELETE") - r.HandleFunc("/scenario/{scenario_id}", s.GetScenarioFunc).Methods("GET") - r.HandleFunc("/scenario/{id}/printable", s.PrintFunc).Methods("GET") - r.HandleFunc("/a/scenario/{id}/printable", s.AdminPrintFunc).Methods("GET") - r.HandleFunc("/a/scenario/new", s.CreateFunc).Methods("POST") - r.HandleFunc("/a/scenario/copy/{id}", s.CopyFunc).Methods("POST") - r.HandleFunc("/a/scenario/{id}", s.UpdateFunc).Methods("PUT") - r.HandleFunc("/scenario/{scenario_id}/step/{step_id:[0-9]+}", s.GetScenarioStepFunc).Methods("GET") - glog.V(2).Infof("set up route") -} - -func (s ScenarioServer) prepareScenario(scenario hfv1.Scenario, printable bool) (PreparedScenario, error) { - ps := PreparedScenario{} - - ps.Id = scenario.Name - ps.Name = scenario.Spec.Name - ps.Description = scenario.Spec.Description - ps.VirtualMachines = scenario.Spec.VirtualMachines - ps.Pauseable = scenario.Spec.Pauseable - ps.Printable = printable - ps.StepCount = len(scenario.Spec.Steps) - ps.Tasks = scenario.Spec.Tasks - return ps, nil -} - -func (s ScenarioServer) getPreparedScenarioStepById(id string, step int) (PreparedScenarioStep, error) { - scenario, err := s.GetScenarioById(id) - if err != nil { - return PreparedScenarioStep{}, fmt.Errorf("error while retrieving scenario step") - } - - if step >= 0 && len(scenario.Spec.Steps) > step { - stepContent := scenario.Spec.Steps[step] - return PreparedScenarioStep{stepContent.Title, stepContent.Content}, nil - } - - return PreparedScenarioStep{}, fmt.Errorf("error while retrieving scenario step, most likely doesn't exist in index") -} - -func (s ScenarioServer) getPrintableScenarioIds(accessCodes []string) []string { - var printableScenarioIds []string - var printableCourseIds []string - accessCodeObjs, err := s.acClient.GetAccessCodesWithOTACs(accessCodes) - if err != nil { - glog.Errorf("error retrieving access codes %v", err) - return []string{} - } - for _, accessCode := range accessCodeObjs { - if !accessCode.Spec.Printable { - continue - } - printableScenarioIds = append(printableScenarioIds, accessCode.Spec.Scenarios...) - printableCourseIds = append(printableCourseIds, accessCode.Spec.Courses...) - } - printableCourseIds = util.UniqueStringSlice(printableCourseIds) - - for _, courseId := range printableCourseIds { - course, err := s.courseClient.GetCourseById(courseId) - if err != nil { - glog.Errorf("error retrieving course %v", err) - continue - } - printableScenarioIds = append(printableScenarioIds, s.courseClient.AppendDynamicScenariosByCategories(course.Spec.Scenarios, course.Spec.Categories)...) - } - - printableScenarioIds = util.UniqueStringSlice(printableScenarioIds) - return printableScenarioIds -} - -func (s ScenarioServer) getPreparedScenarioById(id string, accessCodes []string) (PreparedScenario, error) { - scenario, err := s.GetScenarioById(id) - - if err != nil { - return PreparedScenario{}, fmt.Errorf("error while retrieving scenario %v", err) - } - - printableScenarioIds := s.getPrintableScenarioIds(accessCodes) - printable := slices.Contains(printableScenarioIds, scenario.Name) - - preparedScenario, err := s.prepareScenario(scenario, printable) - - if err != nil { - return PreparedScenario{}, fmt.Errorf("error while preparing scenario %v", err) - } - - return preparedScenario, nil -} - -func (s ScenarioServer) GetScenarioFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scenarios") - return - } - - vars := mux.Vars(r) - - scenario_id := vars["scenario_id"] - - if len(scenario_id) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no scenario id passed in") - return - } - - scenario, err := s.getPreparedScenarioById(scenario_id, user.AccessCodes) - if err != nil { - util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s not found", vars["scenario_id"])) - return - } - encodedScenario, err := json.Marshal(scenario) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedScenario) -} - -func (s ScenarioServer) AdminGetFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - scenario, err := s.GetScenarioById(id) - - if err != nil { - glog.Errorf("error while retrieving scenario %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") - return - } - - preparedScenario := AdminPreparedScenario{scenario.Name, scenario.Spec} - - encodedScenario, err := json.Marshal(preparedScenario) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedScenario) - - glog.V(2).Infof("retrieved scenario %s", scenario.Name) -} - -func (s ScenarioServer) AdminDeleteFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbDelete)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete Scenario") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util.ReturnHTTPMessage(w, r, 400, "error", "no id passed in") - return - } - - // when can we safely a scenario? - // 1. when there are no active scheduled events using the scenario - // 2. when there are no sessions using the scenario - // 3. when there is no course using the scenario - - seList, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error retrieving scheduledevent list: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") - return - } - - seInUse := filterScheduledEvents(id, seList) - - sessList, err := s.hfClientSet.HobbyfarmV1().Sessions(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error retrieving session list: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") - return - } - - sessInUse := filterSessions(id, sessList) - - courseList, err := s.hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error retrieving course list: %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") - return - } - - coursesInUse := filterCourses(id, courseList) - - var msg = "" - toDelete := true - - if len(*seInUse) > 0 { - // cannot toDelete, in use. alert the user - msg += "In use by scheduled events:" - for _, se := range *seInUse { - msg += " " + se.Name - } - toDelete = false - } - - if len(*sessInUse) > 0 { - msg += "In use by sessions:" - for _, sess := range *sessInUse { - msg += " " + sess.Name - } - toDelete = false - } - - if len(*coursesInUse) > 0 { - msg += "In use by courses:" - for _, course := range *coursesInUse { - msg += " " + course.Name - } - toDelete = false - } - - if !toDelete { - util.ReturnHTTPMessage(w, r, 403, "badrequest", msg) - return - } - - err = s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Delete(s.ctx, id, metav1.DeleteOptions{}) - - if err != nil { - glog.Errorf("error while deleting scenario %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "scenario could not be deleted") - return - } - util.ReturnHTTPMessage(w, r, 200, "success", "scenario deleted") - glog.V(2).Infof("deleted scenario %s", id) -} - -func (s ScenarioServer) GetScenarioStepFunc(w http.ResponseWriter, r *http.Request) { - _, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scenario steps") - return - } - - vars := mux.Vars(r) - - stepId, err := strconv.Atoi(vars["step_id"]) - if err != nil { - util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s step %s not found", vars["scenario_id"], vars["step_id"])) - return - } - step, err := s.getPreparedScenarioStepById(vars["scenario_id"], stepId) - if err != nil { - util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s not found", vars["scenario_id"])) - return - } - encodedStep, err := json.Marshal(step) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedStep) - -} - -func (s ScenarioServer) ListScenariosForAccessCode(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios") - return - } - - vars := mux.Vars(r) - accessCode := vars["access_code"] - - if accessCode == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "access_code is missing") - return - } - - if !slices.Contains(user.AccessCodes, accessCode) { - - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios for this AccessCode") - return - } - - // store a list of scenarios linked to courses for filtering - //var courseScenarios []string - var scenarioIds []string - ac, err := s.acClient.GetAccessCodeWithOTACs(accessCode) - if err != nil { - glog.Errorf("error retrieving access code: %s %v", accessCode, err) - } - scenarioIds = append(scenarioIds, ac.Spec.Scenarios...) - - var scenarios []PreparedScenario - for _, scenarioId := range scenarioIds { - scenario, err := s.GetScenarioById(scenarioId) - if err != nil { - glog.Errorf("error retrieving scenario %v", err) - continue - } - pScenario, err := s.prepareScenario(scenario, ac.Spec.Printable) - if err != nil { - glog.Errorf("error preparing scenario %v", err) - continue - } - scenarios = append(scenarios, pScenario) - } - - encodedScenarios, err := json.Marshal(scenarios) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) -} - -func (s ScenarioServer) ListAllFunc(w http.ResponseWriter, r *http.Request) { - s.ListFunc(w, r, "") -} - -func (s ScenarioServer) ListByCategoryFunc(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - category := vars["category"] - - if len(category) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no category passed in") - return - } - - s.ListFunc(w, r, category) -} - -func (s ScenarioServer) ListFunc(w http.ResponseWriter, r *http.Request, category string) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios") - return - } - - categorySelector := metav1.ListOptions{} - if category != "" { - categorySelector = metav1.ListOptions{ - LabelSelector: fmt.Sprintf("category-%s=true", category), - } - } - - scenarios, err := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).List(s.ctx, categorySelector) - - if err != nil { - glog.Errorf("error while retrieving scenarios %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no scenarios found") - return - } - - preparedScenarios := []AdminPreparedScenario{} - for _, s := range scenarios.Items { - pScenario := AdminPreparedScenario{s.Name, s.Spec} - pScenario.Steps = nil - preparedScenarios = append(preparedScenarios, pScenario) - } - - encodedScenarios, err := json.Marshal(preparedScenarios) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) - - glog.V(2).Infof("listed scenarios") -} - -func (s ScenarioServer) ListCategories(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list categories") - return - } - - scenarios, err := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - - if err != nil { - glog.Errorf("error while retrieving scenarios %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no scenarios found") - return - } - - categories := []string{} - - for _, s := range scenarios.Items { - if len(s.Spec.Categories) != 0 { - categories = append(categories, s.Spec.Categories...) - } - } - - // Sort + Compact creates a unique sorted slice - slices.Sort(categories) - slices.Compact(categories) - - encodedCategories, err := json.Marshal(categories) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedCategories) - - glog.V(2).Infof("listed categories") -} - -func (s ScenarioServer) AdminPrintFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - scenario, err := s.GetScenarioById(id) - - if err != nil { - glog.Errorf("error while retrieving scenario %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") - return - } - - var content string - - name, err := base64.StdEncoding.DecodeString(scenario.Spec.Name) - if err != nil { - glog.Errorf("Error decoding title of scenario: %s %v", scenario.Name, err) - } - description, err := base64.StdEncoding.DecodeString(scenario.Spec.Description) - if err != nil { - glog.Errorf("Error decoding description of scenario: %s %v", scenario.Name, err) - } - - content = fmt.Sprintf("# %s\n%s\n\n", name, description) - - for i, s := range scenario.Spec.Steps { - - title, err := base64.StdEncoding.DecodeString(s.Title) - if err != nil { - glog.Errorf("Error decoding title of scenario: %s step %d: %v", scenario.Name, i, err) - } - - content = content + fmt.Sprintf("## Step %d: %s\n", i+1, string(title)) - - stepContent, err := base64.StdEncoding.DecodeString(s.Content) - if err != nil { - glog.Errorf("Error decoding content of scenario: %s step %d: %v", scenario.Name, i, err) - } - - content = content + fmt.Sprintf("%s\n", string(stepContent)) - } - - util.ReturnHTTPRaw(w, r, content) - - glog.V(2).Infof("retrieved scenario and rendered for printability %s", scenario.Name) -} - -func (s ScenarioServer) PrintFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - printableScenarioIds := s.getPrintableScenarioIds(user.AccessCodes) - - if !slices.Contains(printableScenarioIds, id) { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get this Scenario") - return - } - - scenario, err := s.GetScenarioById(id) - - if err != nil { - glog.Errorf("error while retrieving scenario %v", err) - util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") - return - } - - var content string - - name, err := base64.StdEncoding.DecodeString(scenario.Spec.Name) - if err != nil { - glog.Errorf("Error decoding title of scenario: %s %v", scenario.Name, err) - } - description, err := base64.StdEncoding.DecodeString(scenario.Spec.Description) - if err != nil { - glog.Errorf("Error decoding description of scenario: %s %v", scenario.Name, err) - } - - content = fmt.Sprintf("# %s\n%s\n\n", name, description) - - for i, s := range scenario.Spec.Steps { - - title, err := base64.StdEncoding.DecodeString(s.Title) - if err != nil { - glog.Errorf("Error decoding title of scenario: %s step %d: %v", scenario.Name, i, err) - } - - content = content + fmt.Sprintf("\n## Step %d: %s\n", i+1, string(title)) - - stepContent, err := base64.StdEncoding.DecodeString(s.Content) - if err != nil { - glog.Errorf("Error decoding content of scenario: %s step %d: %v", scenario.Name, i, err) - } - - content = content + fmt.Sprintf("%s\n", string(stepContent)) - } - - util.ReturnHTTPRaw(w, r, content) - - glog.V(2).Infof("retrieved scenario and rendered for printability %s", scenario.Name) -} - -func (s ScenarioServer) CopyFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.Authorize(r, s.authrClient, impersonatedUserId, []*authr.Permission{ - rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate), - rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet), - }, rbac2.OperatorAND) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scenarios") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - - if len(id) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - scenario, err := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "badrequest", "no scenario found with given ID") - return fmt.Errorf("bad") - } - - name, err := base64.StdEncoding.DecodeString(scenario.Spec.Name) - if err != nil { - glog.Errorf("Error decoding title of scenario to copy: %s %v", scenario.Name, err) - } - copyName := string(name) + " - Copy" - copyName = base64.StdEncoding.EncodeToString([]byte(copyName)) - hasher := sha256.New() - hasher.Write([]byte(copyName)) - sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] - - scenario.Spec.Name = copyName - scenario.Name = "s-" + strings.ToLower(sha) - - _, updateErr := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Create(s.ctx, scenario, metav1.CreateOptions{}) - return updateErr - }) - - if retryErr != nil { - util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to copy") - return - } - - util.ReturnHTTPMessage(w, r, 200, "copied scenario", "") - return -} - -func VerifyTaskContent(vm_tasks []hfv1.VirtualMachineTasks) error { - //Verify that name, description, command must not empty - for _, vm_task := range vm_tasks { - if vm_task.VMName == "" { - glog.Errorf("error while vm_name empty") - return fmt.Errorf("bad") - } - for _, task := range vm_task.Tasks { - if task.Name == "" { - glog.Errorf("error while Name of task empty") - return fmt.Errorf("bad") - } - if task.Description == "" { - glog.Errorf("error while Description of task empty") - return fmt.Errorf("bad") - } - if task.Command == "" || task.Command == "[]" { - glog.Errorf("error while Command of task empty") - return fmt.Errorf("bad") - } - } - } - return nil -} - -func (s ScenarioServer) CreateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scenarios") - return - } - - name := r.PostFormValue("name") - if name == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") - return - } - description := r.PostFormValue("description") - if description == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") - return - } - - keepaliveDuration := r.PostFormValue("keepalive_duration") - // we won't error if no keep alive duration is passed in or if it's blank because we'll default elsewhere - - steps := []hfv1.ScenarioStep{} - virtualmachines := []map[string]string{} - categories := []string{} - tags := []string{} - - rawSteps := r.PostFormValue("steps") - if rawSteps != "" { - err = json.Unmarshal([]byte(rawSteps), &steps) - if err != nil { - glog.Errorf("error while unmarshaling steps %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - rawCategories := r.PostFormValue("categories") - if rawCategories != "" { - err = json.Unmarshal([]byte(rawCategories), &categories) - if err != nil { - glog.Errorf("error while unmarshaling categories %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - rawTags := r.PostFormValue("tags") - if rawTags != "" { - err = json.Unmarshal([]byte(rawTags), &tags) - if err != nil { - glog.Errorf("error while unmarshaling tags %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - rawVirtualMachines := r.PostFormValue("virtualmachines") - if rawVirtualMachines != "" { - err = json.Unmarshal([]byte(rawVirtualMachines), &virtualmachines) - if err != nil { - glog.Errorf("error while unmarshaling VMs %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - pauseable := r.PostFormValue("pauseable") - pauseDuration := r.PostFormValue("pause_duration") - - scenario := &hfv1.Scenario{} - - hasher := sha256.New() - hasher.Write([]byte(name)) - sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] - scenario.Name = "s-" + strings.ToLower(sha) - - scenario.Spec.Name = name - scenario.Spec.Description = description - scenario.Spec.VirtualMachines = virtualmachines - scenario.Spec.Steps = steps - scenario.Spec.Categories = categories - scenario.Spec.Tags = tags - scenario.Spec.KeepAliveDuration = keepaliveDuration - rawVMTasks := r.PostFormValue("vm_tasks") - if rawVMTasks != "" { - vm_tasks := []hfv1.VirtualMachineTasks{} - - err = json.Unmarshal([]byte(rawVMTasks), &vm_tasks) - if err != nil { - glog.Errorf("error while unmarshaling tasks %v", err) - return - } - err = VerifyTaskContent(vm_tasks) - if err != nil { - glog.Errorf("error tasks content %v", err) - return - } - scenario.Spec.Tasks = vm_tasks - } - - scenario.Spec.Pauseable = false - if pauseable != "" { - if strings.ToLower(pauseable) == "true" { - scenario.Spec.Pauseable = true - } - } - - if pauseDuration != "" { - scenario.Spec.PauseDuration = pauseDuration - } - - scenario, err = s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Create(s.ctx, scenario, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating scenario %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scenario") - return - } - - util.ReturnHTTPMessage(w, r, 201, "created", scenario.Name) - return -} - -func (s ScenarioServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scenarios") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - scenario, err := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "badrequest", "no scenario found with given ID") - return fmt.Errorf("bad") - } - - name := r.PostFormValue("name") - description := r.PostFormValue("description") - rawSteps := r.PostFormValue("steps") - pauseable := r.PostFormValue("pauseable") - pauseDuration := r.PostFormValue("pause_duration") - keepaliveDuration := r.PostFormValue("keepalive_duration") - rawVirtualMachines := r.PostFormValue("virtualmachines") - rawCategories := r.PostFormValue("categories") - rawTags := r.PostFormValue("tags") - rawVMTasks := r.PostFormValue("vm_tasks") - - if name != "" { - scenario.Spec.Name = name - } - if description != "" { - scenario.Spec.Description = description - } - if keepaliveDuration != "" { - scenario.Spec.KeepAliveDuration = keepaliveDuration - } - - if pauseable != "" { - if strings.ToLower(pauseable) == "true" { - scenario.Spec.Pauseable = true - } else { - scenario.Spec.Pauseable = false - } - } - - if pauseDuration != "" { - scenario.Spec.PauseDuration = pauseDuration - } - - if rawSteps != "" { - steps := []hfv1.ScenarioStep{} - - err = json.Unmarshal([]byte(rawSteps), &steps) - if err != nil { - glog.Errorf("error while unmarshaling steps %v", err) - return fmt.Errorf("bad") - } - scenario.Spec.Steps = steps - } - - if rawVirtualMachines != "" { - virtualmachines := []map[string]string{} - err = json.Unmarshal([]byte(rawVirtualMachines), &virtualmachines) - if err != nil { - glog.Errorf("error while unmarshaling VMs %v", err) - return fmt.Errorf("bad") - } - scenario.Spec.VirtualMachines = virtualmachines - } - - if rawCategories != "" { - oldCategories := []string{} - if len(scenario.Spec.Categories) != 0 { - oldCategories = scenario.Spec.Categories - } - - if scenario.ObjectMeta.Labels == nil { - scenario.ObjectMeta.Labels = make(map[string]string) - } - - for _, category := range oldCategories { - scenario.ObjectMeta.Labels["category-"+category] = "false" - } - newCategoriesSlice := make([]string, 0) - err = json.Unmarshal([]byte(rawCategories), &newCategoriesSlice) - if err != nil { - glog.Errorf("error while unmarshaling categories %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - for _, category := range newCategoriesSlice { - scenario.ObjectMeta.Labels["category-"+category] = "true" - } - scenario.Spec.Categories = newCategoriesSlice - } - - if rawTags != "" { - tagsSlice := make([]string, 0) - err = json.Unmarshal([]byte(rawTags), &tagsSlice) - if err != nil { - glog.Errorf("error while unmarshaling tags %v", err) - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return fmt.Errorf("bad") - } - scenario.Spec.Tags = tagsSlice - } - - if rawVMTasks != "" { - vm_tasks := []hfv1.VirtualMachineTasks{} - - err = json.Unmarshal([]byte(rawVMTasks), &vm_tasks) - if err != nil { - glog.Errorf("error while unmarshaling tasks %v", err) - return fmt.Errorf("bad") - } - - err = VerifyTaskContent(vm_tasks) - if err != nil { - glog.Errorf("error tasks content %v", err) - return err - } - scenario.Spec.Tasks = vm_tasks - } - - _, updateErr := s.hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()).Update(s.ctx, scenario, metav1.UpdateOptions{}) - return updateErr - }) - - if retryErr != nil { - util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") - return - } - - util.ReturnHTTPMessage(w, r, 200, "updated", "") - return -} - -func (s ScenarioServer) GetScenarioById(id string) (hfv1.Scenario, error) { - if len(id) == 0 { - return hfv1.Scenario{}, fmt.Errorf("scenario id passed in was blank") - } - obj, err := s.scenarioIndexer.ByIndex(idIndex, id) - - if err != nil { - return hfv1.Scenario{}, fmt.Errorf("error while retrieving scenario by ID %s %v", id, err) - } - - if len(obj) < 1 { - return hfv1.Scenario{}, fmt.Errorf("error while retrieving scenario by ID %s", id) - } - - scenario, ok := obj[0].(*hfv1.Scenario) - - if !ok { - return hfv1.Scenario{}, fmt.Errorf("error while retrieving scenario by ID %s %v", id, ok) - } - - return *scenario, nil - -} - -// Filter a ScheduledEventList to find SEs that are a) active and b) using the course specified -func filterScheduledEvents(scenario string, seList *hfv1.ScheduledEventList) *[]hfv1.ScheduledEvent { - outList := make([]hfv1.ScheduledEvent, 0) - for _, se := range seList.Items { - if se.Status.Finished == true { - continue - } - - for _, s := range se.Spec.Scenarios { - if s == scenario { - outList = append(outList, se) - break - } - } - } - - return &outList -} - -func filterSessions(scenario string, list *hfv1.SessionList) *[]hfv1.Session { - outList := make([]hfv1.Session, 0) - for _, sess := range list.Items { - if sess.Spec.ScenarioId == scenario { - outList = append(outList, sess) - } - } - - return &outList -} - -func filterCourses(scenario string, list *hfv1.CourseList) *[]hfv1.Course { - outList := make([]hfv1.Course, 0) - for _, course := range list.Items { - for _, s := range course.Spec.Scenarios { - if s == scenario { - outList = append(outList, course) - break - } - } - } - - return &outList -} - -func idIndexer(obj interface{}) ([]string, error) { - scenario, ok := obj.(*hfv1.Scenario) - if !ok { - return []string{}, nil - } - return []string{scenario.Name}, nil -} diff --git a/v3/pkg/scheduledeventserver/scheduledevent.go b/v3/pkg/scheduledeventserver/scheduledevent.go deleted file mode 100644 index 61a8c404..00000000 --- a/v3/pkg/scheduledeventserver/scheduledevent.go +++ /dev/null @@ -1,842 +0,0 @@ -package scheduledeventserver - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "strconv" - "strings" - "time" - - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - - "github.com/golang/glog" - "github.com/gorilla/mux" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/util/retry" -) - -const ( - resourcePlural = rbac2.ResourcePluralEvent -) - -type ScheduledEventServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context -} - -func NewScheduledEventServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*ScheduledEventServer, error) { - es := ScheduledEventServer{} - - es.authnClient = authnClient - es.authrClient = authrClient - es.hfClientSet = hfClientset - es.ctx = ctx - - return &es, nil -} - -func (s ScheduledEventServer) getScheduledEvent(id string) (hfv1.ScheduledEvent, error) { - - empty := hfv1.ScheduledEvent{} - - if len(id) == 0 { - return empty, fmt.Errorf("scheduledevent passed in was empty") - } - - obj, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - return empty, fmt.Errorf("error while retrieving ScheduledEvent by id: %s with error: %v", id, err) - } - - return *obj, nil - -} - -func (s ScheduledEventServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/a/scheduledevent/list", s.ListFunc).Methods("GET") - r.HandleFunc("/a/scheduledevent/new", s.CreateFunc).Methods("POST") - r.HandleFunc("/a/scheduledevent/{id}", s.GetFunc).Methods("GET") - r.HandleFunc("/a/scheduledevent/{id}", s.UpdateFunc).Methods("PUT") - r.HandleFunc("/a/scheduledevent/{id}/otacs/add/{count}", s.GenerateOTACsFunc).Methods("POST") - r.HandleFunc("/a/scheduledevent/{id}/otacs/delete/{otac}", s.DeleteOTACFunc).Methods("GET") - r.HandleFunc("/a/scheduledevent/{id}/otacs/list", s.GetOTACsFunc).Methods("GET") - r.HandleFunc("/a/scheduledevent/delete/{id}", s.DeleteFunc).Methods("DELETE") - glog.V(2).Infof("set up routes for admin scheduledevent server") -} - -type PreparedScheduledEvent struct { - ID string `json:"id"` - hfv1.ScheduledEventSpec - hfv1.ScheduledEventStatus -} - -type PreparedOTAC struct { - Name string `json:"name"` - hfv1.OneTimeAccessCodeSpec -} - -func (s ScheduledEventServer) GetFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scheduledEvent") - return - } - - vars := mux.Vars(r) - - scheduledEventId := vars["id"] - - if len(scheduledEventId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no scheduledEvent id passed in") - return - } - - scheduledEvent, err := s.getScheduledEvent(scheduledEventId) - - if err != nil { - glog.Errorf("error while retrieving scheduledEvent %v", err) - util2.ReturnHTTPMessage(w, r, http.StatusNotFound, "error", "no scheduledEvent with given ID found") - return - } - - preparedScheduledEvent := PreparedScheduledEvent{scheduledEvent.Name, scheduledEvent.Spec, scheduledEvent.Status} - - encodedScheduledEvent, err := json.Marshal(preparedScheduledEvent) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedScheduledEvent) - - glog.V(2).Infof("retrieved scheduledEvent %s", scheduledEvent.Name) -} - -func (s ScheduledEventServer) ListFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scheduledEvents") - return - } - - scheduledEvents, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) - - if err != nil { - glog.Errorf("error while retrieving scheduledevents %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no scheduledevents found") - return - } - - preparedScheduledEvents := []PreparedScheduledEvent{} // must be declared this way so as to JSON marshal into [] instead of null - for _, s := range scheduledEvents.Items { - preparedScheduledEvents = append(preparedScheduledEvents, PreparedScheduledEvent{s.Name, s.Spec, s.Status}) - } - - encodedScheduledEvents, err := json.Marshal(preparedScheduledEvents) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedScheduledEvents) - - glog.V(2).Infof("listed scheduled events") -} - -func (s ScheduledEventServer) CreateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scheduledevents") - return - } - - name := r.PostFormValue("name") - if name == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") - return - } - description := r.PostFormValue("description") - if description == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") - return - } - startTime := r.PostFormValue("start_time") - if startTime == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no start time passed in") - return - } - endTime := r.PostFormValue("end_time") - if endTime == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no end time passed in") - return - } - requiredVM := r.PostFormValue("required_vms") - if requiredVM == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no required vm map passed in") - return - } - accessCode := r.PostFormValue("access_code") - if accessCode == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no access code passed in") - return - } - var onDemand bool - onDemandRaw := r.PostFormValue("on_demand") - if onDemandRaw == "" { - glog.Warning("scheduled event without use of on_demand flag is deprecated. please upgrade your client") - onDemand = false - } else { - onDemand, err = strconv.ParseBool(onDemandRaw) - if err != nil { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for on_demand") - return - } - } - - var printable bool - printableRaw := r.PostFormValue("printable") - if printableRaw == "" { - glog.Warning("scheduled event without use of printable flag is deprecated. please upgrade your client") - printable = false - } else { - printable, err = strconv.ParseBool(printableRaw) - if err != nil { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for printable") - return - } - } - - scenariosRaw := r.PostFormValue("scenarios") - coursesRaw := r.PostFormValue("courses") - if scenariosRaw == "" && coursesRaw == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no scenarios or courses passed in") - return - } - - restrictionDisabled := false - restrictionDisabledRaw := r.PostFormValue("disable_restriction") - if restrictionDisabledRaw == "" { - restrictionDisabled = false - } else { - if strings.ToLower(restrictionDisabledRaw) == "false" { - restrictionDisabled = false - } else { - restrictionDisabled = true - } - } - - requiredVMUnmarshaled := map[string]map[string]int{} - - err = json.Unmarshal([]byte(requiredVM), &requiredVMUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshalling required VM's %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - - scenarios := []string{} // must be declared this way so as to JSON marshal into [] instead of null - if scenariosRaw != "" { - err = json.Unmarshal([]byte(scenariosRaw), &scenarios) - if err != nil { - glog.Errorf("error while unmarshalling scenarios %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - courses := []string{} // must be declared this way so as to JSON marshal into [] instead of null - if coursesRaw != "" { - err = json.Unmarshal([]byte(coursesRaw), &courses) - if err != nil { - glog.Errorf("error while unmarshalling courses %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") - return - } - } - - scheduledEvent := &hfv1.ScheduledEvent{} - random := util2.RandStringRunes(16) - scheduledEvent.Name = "se-" + util2.GenerateResourceName("se", random, 10) - - scheduledEvent.Spec.Name = name - scheduledEvent.Spec.Description = description - scheduledEvent.Spec.Creator = user.GetId() - scheduledEvent.Spec.StartTime = startTime - scheduledEvent.Spec.EndTime = endTime - scheduledEvent.Spec.OnDemand = onDemand - scheduledEvent.Spec.Printable = printable - scheduledEvent.Spec.RequiredVirtualMachines = requiredVMUnmarshaled - scheduledEvent.Spec.AccessCode = accessCode - - if scenariosRaw != "" { - scheduledEvent.Spec.Scenarios = scenarios - } - - if coursesRaw != "" { - scheduledEvent.Spec.Courses = courses - } - - if restrictionDisabled { - scheduledEvent.Spec.RestrictedBind = false - } else { - scheduledEvent.Spec.RestrictedBind = true - scheduledEvent.Spec.RestrictedBindValue = scheduledEvent.Name - } - - scheduledEvent, err = s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Create(s.ctx, scheduledEvent, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating scheduled event %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scheduled event") - return - } - - scheduledEvent.Status.Active = true - scheduledEvent.Status.Finished = false - scheduledEvent.Status.Ready = false - scheduledEvent.Status.Provisioned = false - scheduledEvent.Status.VirtualMachineSets = []string{} - - _, err = s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, scheduledEvent, metav1.UpdateOptions{}) - - if err != nil { - glog.Errorf("error updating status subresource for scheduled event %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scheduled event") - return - } - - util2.ReturnHTTPMessage(w, r, 201, "created", scheduledEvent.Name) - return -} - -func (s ScheduledEventServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - scheduledEvent, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 404, "badrequest", "no scheduledEvent found with given ID") - return fmt.Errorf("bad") - } - - name := r.PostFormValue("name") - description := r.PostFormValue("description") - startTime := r.PostFormValue("start_time") - endTime := r.PostFormValue("end_time") - requiredVM := r.PostFormValue("required_vms") - accessCode := r.PostFormValue("access_code") - scenariosRaw := r.PostFormValue("scenarios") - coursesRaw := r.PostFormValue("courses") - onDemandRaw := r.PostFormValue("on_demand") - restrictionDisabledRaw := r.PostFormValue("disable_restriction") - printableRaw := r.PostFormValue("printable") - - if name != "" { - scheduledEvent.Spec.Name = name - } - if description != "" { - scheduledEvent.Spec.Description = description - } - if startTime != "" { - scheduledEvent.Spec.StartTime = startTime - } - if endTime != "" { - scheduledEvent.Spec.EndTime = endTime - } - - if accessCode != "" { - scheduledEvent.Spec.AccessCode = accessCode - } - - if requiredVM != "" { - requiredVMUnmarshaled := map[string]map[string]int{} - - err = json.Unmarshal([]byte(requiredVM), &requiredVMUnmarshaled) - if err != nil { - glog.Errorf("error while unmarshaling required VM's %v", err) - return fmt.Errorf("bad") - } - scheduledEvent.Spec.RequiredVirtualMachines = requiredVMUnmarshaled - } - - if coursesRaw != "" { - courses := []string{} // must be declared this way so as to JSON marshal into [] instead of null - err = json.Unmarshal([]byte(coursesRaw), &courses) - if err != nil { - glog.Errorf("error while unmarshaling courses %v", err) - return fmt.Errorf("bad") - } - scheduledEvent.Spec.Courses = courses - } - - if scenariosRaw != "" { - scenarios := []string{} // must be declared this way so as to JSON marshal into [] instead of null - err = json.Unmarshal([]byte(scenariosRaw), &scenarios) - if err != nil { - glog.Errorf("error while unmarshaling scenarios %v", err) - return fmt.Errorf("bad") - } - scheduledEvent.Spec.Scenarios = scenarios - } - - restrictionDisabled := scheduledEvent.Spec.RestrictedBind - - if restrictionDisabledRaw != "" { - if strings.ToLower(restrictionDisabledRaw) == "false" { - restrictionDisabled = false - } else { - restrictionDisabled = true - } - } - if restrictionDisabled { - scheduledEvent.Spec.RestrictedBind = false - scheduledEvent.Spec.RestrictedBindValue = "" - } else { - scheduledEvent.Spec.RestrictedBind = true - scheduledEvent.Spec.RestrictedBindValue = scheduledEvent.Name - } - - onDemand := scheduledEvent.Spec.OnDemand - onDemandBeforeUpdate := onDemand - - if onDemandRaw != "" { - onDemand, err = strconv.ParseBool(onDemandRaw) - if err != nil { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for on_demand") - return err - } - if onDemand && !scheduledEvent.Spec.OnDemand { - glog.Errorf("ScheduledEvent %s changed to onDemand, deleting corresponding VMSets.", scheduledEvent.Name) - err = s.deleteVMSetsFromScheduledEvent(scheduledEvent) - if err != nil { - glog.Errorf("Deleting vmset failed: %v", err) - } - } - } - scheduledEvent.Spec.OnDemand = onDemand - - var printable bool - if printableRaw != "" { - printable, err = strconv.ParseBool(printableRaw) - if err != nil { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for on_demand") - return err - } else { - scheduledEvent.Spec.Printable = printable - } - } - - // if our event is already provisioned, we need to undo that and delete the corresponding access code(s) and DBC(s) - // our scheduledeventcontroller will then provision our scheduledevent with the updated values - if scheduledEvent.Status.Provisioned { - now := time.Now() - - beginTime, err := time.Parse(time.UnixDate, scheduledEvent.Spec.StartTime) - if err != nil { - return err - } - - // the SE's begin time has been rescheduled to the future but was already provisioned - // OR the on demand setting has been removed completely. - if (now.Before(beginTime) && scheduledEvent.Status.Active) || (!onDemandBeforeUpdate && onDemand) { - err = s.deleteVMSetsFromScheduledEvent(scheduledEvent) - if err != nil { - return err - } - } - - err = s.deleteScheduledEventConfig(scheduledEvent) - if err != nil { - return err - } - } - - updateSE, updateErr := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Update(s.ctx, scheduledEvent, metav1.UpdateOptions{}) - if updateErr != nil { - return updateErr - } - - updateSE.Status.Provisioned = false - updateSE.Status.Ready = false - updateSE.Status.Finished = false - - _, updateErr = s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, updateSE, metav1.UpdateOptions{}) - return updateErr - }) - - if retryErr != nil { - glog.Error(retryErr) - util2.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "updated", "") - return -} - -func (s ScheduledEventServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbDelete)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete scheduledevents") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - scheduledEvent, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 404, "badrequest", "no scheduledEvent found with given ID") - return - } - - err = s.deleteVMSetsFromScheduledEvent(scheduledEvent) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's VMSets") - return - } - - err = s.finishSessions(scheduledEvent) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", err.Error()) - return - } - - err = s.deleteProgressFromScheduledEvent(scheduledEvent) - - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", err.Error()) - return - } - - err = s.deleteScheduledEventConfig(scheduledEvent) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's access code(s) and DBC(s)") - return - } - - err = s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Delete(s.ctx, scheduledEvent.Name, metav1.DeleteOptions{}) - - if err != nil { - glog.Errorf("error deleting scheduled event %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "deleted", "Deleted: "+scheduledEvent.Name) - return -} - -func (s ScheduledEventServer) GetOTACsFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scheduledevents") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - otacList, err := s.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, id), - }) - - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error retreiving OTACs") - return - } - - var otacs []PreparedOTAC - for _, otac := range otacList.Items { - otacs = append(otacs, PreparedOTAC{otac.Name, otac.Spec}) - } - - encoded, err := json.Marshal(otacs) - if err != nil { - glog.Errorf("error marshalling prepared otacs: %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing otacs") - return - } - - util2.ReturnHTTPContent(w, r, 200, "success", encoded) - - glog.V(4).Infof("listed OTACs for SE %s", id) -} - -func (s ScheduledEventServer) DeleteOTACFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") - return - } - - vars := mux.Vars(r) - - otac := vars["otac"] - if otac == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - err = s.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util2.GetReleaseNamespace()).Delete(s.ctx, otac, metav1.DeleteOptions{}) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting OTACs") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "success", "deleted OTAC") -} - -func (s ScheduledEventServer) GenerateOTACsFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, s.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - - countFormValue := vars["count"] - if countFormValue == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no count passed in") - return - } - count, err := strconv.Atoi(countFormValue) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 404, "badrequest", "invalid count given") - return - } - - maxDurationValue := r.PostFormValue("max_duration") - - scheduledEvent, err := s.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(s.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 404, "badrequest", "no scheduledEvent found with given ID") - return - } - - var otacs []PreparedOTAC - - for i := 0; i < count; i++ { - // Generate an access code that can not be guessed - genName := "" - for genParts := 0; genParts < 3; genParts++ { - genName += util2.GenerateResourceName("", util2.RandStringRunes(16), 4) - } - genName = genName[1:] - otac := &hfv1.OneTimeAccessCode{ - ObjectMeta: metav1.ObjectMeta{ - Name: genName, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "hobbyfarm.io/v1", - Kind: "ScheduledEvent", - Name: scheduledEvent.Name, - UID: scheduledEvent.UID, - }, - }, - Labels: map[string]string{ - util2.UserLabel: "", - util2.ScheduledEventLabel: scheduledEvent.Name, - util2.OneTimeAccessCodeLabel: genName, - }, - }, - Spec: hfv1.OneTimeAccessCodeSpec{ - User: "", - RedeemedTimestamp: "", - MaxDuration: maxDurationValue, - }, - } - otac, err = s.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util2.GetReleaseNamespace()).Create(s.ctx, otac, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating one time access code %v", err) - continue - } - otacs = append(otacs, PreparedOTAC{otac.Name, otac.Spec}) - } - - encoded, err := json.Marshal(otacs) - if err != nil { - glog.Errorf("error marshalling prepared otacs: %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing generated otacs") - return - } - - util2.ReturnHTTPContent(w, r, 200, "success", encoded) - - glog.V(4).Infof("generated %d new OTACs for SE %s", count, id) -} - -func (s ScheduledEventServer) deleteScheduledEventConfig(se *hfv1.ScheduledEvent) error { - glog.V(6).Infof("ScheduledEvent %s is updated or deleted, deleting corresponding access code(s) and DBC(s)", se.Name) - - // delete all DBCs corresponding to this scheduled event - err := s.hfClientSet.HobbyfarmV1().DynamicBindConfigurations(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - // for each access code that belongs to this edited/deleted scheduled event, delete that access code - err = s.hfClientSet.HobbyfarmV1().AccessCodes(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil // break (return) here because we're done with this SE. -} - -func (s ScheduledEventServer) deleteProgressFromScheduledEvent(se *hfv1.ScheduledEvent) error { - // for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset - err := s.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventServer) deleteVMSetsFromScheduledEvent(se *hfv1.ScheduledEvent) error { - // delete all vmsets corresponding to this scheduled event - err := s.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).DeleteCollection(s.ctx, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, se.Name), - }) - if err != nil { - return err - } - - return nil -} - -func (s ScheduledEventServer) finishSessions(se *hfv1.ScheduledEvent) error { - // get a list of sessions for the user - sessionList, err := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.AccessCodeLabel, se.Spec.AccessCode), - }) - - now := time.Now().Format(time.UnixDate) - - for _, session := range sessionList.Items { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(s.ctx, session.Name, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", session.Name, getErr) - } - - result.Status.ExpirationTime = now - result.Status.Active = false - result.Status.Finished = false - - _, updateErr := s.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(s.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for session") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error updating session %v", err) - return fmt.Errorf("error attempting to update") - } - } - return nil -} diff --git a/v3/pkg/sessionserver/sessionserver.go b/v3/pkg/sessionserver/sessionserver.go deleted file mode 100644 index 989f96a8..00000000 --- a/v3/pkg/sessionserver/sessionserver.go +++ /dev/null @@ -1,824 +0,0 @@ -package sessionserver - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "os" - "time" - - "github.com/hobbyfarm/gargantua/v3/pkg/accesscode" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/pkg/courseclient" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - "github.com/hobbyfarm/gargantua/v3/pkg/scenarioclient" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - - "github.com/golang/glog" - "github.com/gorilla/mux" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" -) - -const ( - ssIndex = "sss.hobbyfarm.io/session-id-index" - newSSTimeout = "5m" - keepaliveSSTimeout = "5m" - pauseSSTimeout = "2h" - resourcePlural = rbac2.ResourcePluralSession -) - -type SessionServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - courseClient *courseclient.CourseClient - scenarioClient *scenarioclient.ScenarioClient - accessCodeClient *accesscode.AccessCodeClient - ssIndexer cache.Indexer - ctx context.Context -} - -type preparedSession struct { - ID string `json:"id"` - hfv1.SessionSpec -} - -func NewSessionServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, accessCodeClient *accesscode.AccessCodeClient, scenarioClient *scenarioclient.ScenarioClient, courseClient *courseclient.CourseClient, hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*SessionServer, error) { - a := SessionServer{} - a.authnClient = authnClient - a.authrClient = authrClient - a.hfClientSet = hfClientSet - a.courseClient = courseClient - a.scenarioClient = scenarioClient - a.accessCodeClient = accessCodeClient - inf := hfInformerFactory.Hobbyfarm().V1().Sessions().Informer() - indexers := map[string]cache.IndexFunc{ssIndex: ssIdIndexer} - inf.AddIndexers(indexers) - a.ssIndexer = inf.GetIndexer() - a.ctx = ctx - - return &a, nil -} - -func (sss SessionServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/session/new", sss.NewSessionFunc).Methods("POST") - r.HandleFunc("/session/{session_id}", sss.GetSessionFunc).Methods("GET") - r.HandleFunc("/session/{session_id}/finished", sss.FinishedSessionFunc).Methods("PUT") - r.HandleFunc("/session/{session_id}/keepalive", sss.KeepAliveSessionFunc).Methods("PUT") - r.HandleFunc("/session/{session_id}/pause", sss.PauseSessionFunc).Methods("PUT") - r.HandleFunc("/session/{session_id}/resume", sss.ResumeSessionFunc).Methods("PUT") - glog.V(2).Infof("set up routes for session server") -} - -func (sss SessionServer) NewSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create sessions") - return - } - - courseid := r.PostFormValue("course") - scenarioid := r.PostFormValue("scenario") - - if courseid == "" && scenarioid == "" { - util2.ReturnHTTPMessage(w, r, 500, "error", "no course/scenario id passed in") - return - } - - accessCode := r.PostFormValue("access_code") - - restrictedBind := false - restrictedBindVal := "" - - if accessCode == "" { - util2.ReturnHTTPMessage(w, r, 400, "error", "An accesscode has to be given in order so start a sesion") - return - } - - // we should validate the user can use this access code - // let's figure out the restricted bind value - accessCodeObj, err := sss.accessCodeClient.GetAccessCodeWithOTACs(accessCode) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "error", "could not retrieve access code") - return - } - if accessCodeObj.Spec.RestrictedBind { - restrictedBind = accessCodeObj.Spec.RestrictedBind - restrictedBindVal = accessCodeObj.Spec.RestrictedBindValue - } - - random := util2.RandStringRunes(10) - var course hfv1.Course - var scenario hfv1.Scenario - - // get the course and/or scenario objects - if courseid != "" { - course, err = sss.courseClient.GetCourseById(courseid) - if err != nil { - glog.Errorf("course not found %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no course found") - return - } - } - if scenarioid != "" { - scenario, err = sss.scenarioClient.GetScenarioById(scenarioid) - if err != nil { - glog.Errorf("scenario not found %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") - return - } - } - - // now we should check for existing sessions for the user - sessions, err := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).List(sss.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util2.UserLabel, user.GetId()), - }) - - if err != nil { - glog.Error(err) - } - now := time.Now() - - // should we check the sessions list for the restricted bind value and match if one is passed in? probably... - for _, v := range sessions.Items { - expires, err := time.Parse(time.UnixDate, v.Status.ExpirationTime) - if err != nil { - continue - } - if v.Spec.UserId == user.GetId() && - (v.Spec.CourseId == course.Name || v.Spec.ScenarioId == scenario.Name) && - !v.Status.Finished && - v.Status.Active && expires.After(now) { - // we should just return this session... - - // if this is a course, return the same scenario id that was given to us - // i.e., reuse the course id and give them the scenario they asked for - if v.Spec.CourseId != "" { - v.Spec.ScenarioId = scenarioid - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(sss.ctx, v.Name, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", v.Name, getErr) - } - - result.Spec.ScenarioId = scenarioid - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Update(sss.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated session for new scenario") - - //finish old progress & create new progress for the new scenario - sss.FinishProgress(result.Name, user.GetId()) - sss.CreateProgress(result.Name, accessCodeObj.Labels[util2.ScheduledEventLabel], scenario.Name, course.Name, user.GetId(), len(scenario.Spec.Steps)) - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error updating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - } - - preparedSession := preparedSession{v.Name, v.Spec} - encodedSS, err := json.Marshal(preparedSession) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "exists", encodedSS) - return - } - - } - - sessionName := util2.GenerateResourceName("ss", random, 10) - session := hfv1.Session{} - - session.Name = sessionName - session.Spec.CourseId = course.Name - session.Spec.ScenarioId = scenario.Name - session.Spec.UserId = user.GetId() - session.Spec.KeepCourseVM = course.Spec.KeepVM - session.Spec.AccessCode = accessCode // accessCode can be an OTAC or a normal AccessCode - labels := make(map[string]string) - labels[util2.AccessCodeLabel] = accessCodeObj.Name // map accesscode to session, this has to be the SE AccessCode in order for session cleanup to work upon SE deletion - labels[util2.UserLabel] = user.GetId() // map user to session - session.Labels = labels - var vms []map[string]string - if course.Spec.VirtualMachines != nil { - vms = course.Spec.VirtualMachines - } else { - vms = scenario.Spec.VirtualMachines - } - - // find bindMode by quering the scheduledEvent - owners := accessCodeObj.GetOwnerReferences() - if len(owners) != 1 { - util2.ReturnHTTPMessage(w, r, 500, "error", "access code has multiple owners.. invalid request") - return - } - - schedEvent, err := sss.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).Get(sss.ctx, owners[0].Name, metav1.GetOptions{}) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "error", "unable to find scheduledEvent") - return - } - - var bindMode string - var baseName string - if schedEvent.Spec.OnDemand { - bindMode = "dynamic" - bndp := os.Getenv("HF_BASENAME_DYNAMIC_PREFIX") - if bndp == "" { - baseName = "vmc" - } else { - baseName = bndp - } - } else { - bindMode = "static" - bnsp := os.Getenv("HF_BASENAME_SCHEDULED_PREFIX") - if bnsp == "" { - baseName = "scheduled" - } else { - baseName = bnsp - } - } - - session.Spec.VmClaimSet = make([]string, len(vms)) - for index, vmset := range vms { - virtualMachineClaim := hfv1.VirtualMachineClaim{} - vmcId := util2.GenerateResourceName(baseName, util2.RandStringRunes(10), 10) - labels := make(map[string]string) - labels[util2.SessionLabel] = session.Name // map vmc to session - labels[util2.UserLabel] = user.GetId() // map session to user in a way that is searchable - labels[util2.AccessCodeLabel] = session.Labels[util2.AccessCodeLabel] - labels[util2.ScheduledEventLabel] = schedEvent.Name - virtualMachineClaim.Labels = labels - virtualMachineClaim.Spec.BaseName = vmcId - virtualMachineClaim.Name = vmcId - virtualMachineClaim.Spec.VirtualMachines = make(map[string]hfv1.VirtualMachineClaimVM) - for vmName, vmTemplateName := range vmset { - virtualMachineClaim.Spec.VirtualMachines[vmName] = hfv1.VirtualMachineClaimVM{Template: vmTemplateName, VirtualMachineId: ""} - // also label this vmc so we can query against it later - labels[fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s", vmTemplateName)] = "true" - } - virtualMachineClaim.Spec.UserId = user.GetId() - - virtualMachineClaim.Spec.DynamicCapable = true - - if restrictedBind { - virtualMachineClaim.Spec.RestrictedBind = restrictedBind - virtualMachineClaim.Spec.RestrictedBindValue = restrictedBindVal - } else { - virtualMachineClaim.Spec.RestrictedBind = false - } - - createdVmClaim, err := sss.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).Create(sss.ctx, &virtualMachineClaim, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating vm claim %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - createdVmClaim.Status.Bound = false - createdVmClaim.Status.Ready = false - createdVmClaim.Status.BindMode = bindMode - - _, err = sss.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, createdVmClaim, metav1.UpdateOptions{}) - if err != nil { - glog.Errorf("error updating vm claim status %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - session.Spec.VmClaimSet[index] = createdVmClaim.Name - } - - var ssTimeout string - - if course.Spec.KeepAliveDuration != "" { - ssTimeout = course.Spec.KeepAliveDuration - } else if scenario.Spec.KeepAliveDuration != "" { - ssTimeout = scenario.Spec.KeepAliveDuration - } else { - ssTimeout = newSSTimeout - } - - createdSession, err := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Create(sss.ctx, &session, metav1.CreateOptions{}) - - if err != nil { - glog.Errorf("error creating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - createdSession.Status.StartTime = now.Format(time.UnixDate) - duration, _ := time.ParseDuration(ssTimeout) - - createdSession.Status.ExpirationTime = now.Add(duration).Format(time.UnixDate) - createdSession.Status.Active = true - createdSession.Status.Finished = false - - _, err = sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, createdSession, metav1.UpdateOptions{}) - - if err != nil { - glog.Errorf("error creating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - glog.V(2).Infof("created session ID %s", createdSession.Name) - - sss.CreateProgress(createdSession.Name, accessCodeObj.Labels[util2.ScheduledEventLabel], scenario.Name, course.Name, user.GetId(), len(scenario.Spec.Steps)) - - preparedSession := preparedSession{createdSession.Name, createdSession.Spec} - encodedSS, err := json.Marshal(preparedSession) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 201, "created", encodedSS) -} - -func (sss SessionServer) CreateProgress(sessionId string, scheduledEventId string, scenarioId string, courseId string, userId string, totalSteps int) { - random := util2.RandStringRunes(16) - now := time.Now() - - progressName := util2.GenerateResourceName("progress", random, 16) - progress := hfv1.Progress{} - - progress.Name = progressName - progress.Spec.Course = courseId - progress.Spec.Scenario = scenarioId - progress.Spec.UserId = userId - progress.Spec.Started = now.Format(time.UnixDate) - progress.Spec.LastUpdate = now.Format(time.UnixDate) - progress.Spec.Finished = "false" - progress.Spec.TotalStep = totalSteps - progress.Spec.MaxStep = 0 - progress.Spec.CurrentStep = 0 - - steps := []hfv1.ProgressStep{} - step := hfv1.ProgressStep{Step: 0, Timestamp: now.Format(time.UnixDate)} - steps = append(steps, step) - progress.Spec.Steps = steps - - labels := make(map[string]string) - labels[util2.SessionLabel] = sessionId // map to session - labels[util2.ScheduledEventLabel] = scheduledEventId // map to scheduledevent - labels[util2.UserLabel] = userId // map to scheduledevent - labels["finished"] = "false" // default is in progress, finished = false - progress.Labels = labels - - createdProgress, err := sss.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).Create(sss.ctx, &progress, metav1.CreateOptions{}) - - if err != nil { - glog.Errorf("error creating progress %v", err) - return - } - - glog.V(2).Infof("created progress with ID %s", createdProgress.Name) -} - -func (sss SessionServer) FinishProgress(sessionId string, userId string) { - now := time.Now() - - progress, err := sss.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).List(sss.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s,%s=%s,finished=false", util2.SessionLabel, sessionId, util2.UserLabel, userId)}) - - if err != nil { - glog.Errorf("error while retrieving progress %v", err) - return - } - - for _, p := range progress.Items { - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - p.Labels["finished"] = "true" - p.Spec.LastUpdate = now.Format(time.UnixDate) - p.Spec.Finished = "true" - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Progresses(util2.GetReleaseNamespace()).Update(sss.ctx, &p, metav1.UpdateOptions{}) - glog.V(4).Infof("updated progress with ID %s", p.Name) - - return updateErr - }) - if retryErr != nil { - glog.Errorf("error finishing progress %v", err) - return - } - } -} - -func (sss SessionServer) FinishedSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to finish sessions") - return - } - - vars := mux.Vars(r) - - sessionId := vars["session_id"] - if len(sessionId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") - return - } - - ss, err := sss.GetSessionById(sessionId) - if ss.Spec.UserId != user.Id { - // check if the user has access to write sessions - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, sss.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "access denied to update session") - return - } - } - - now := time.Now().Format(time.UnixDate) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(sss.ctx, sessionId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", sessionId, getErr) - } - - // Change the expiration time to now, the sessionController will clean up the session - result.Status.ExpirationTime = now - result.Status.Active = false - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for environment") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error deleting session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "updated", "updated session") -} - -func (sss SessionServer) KeepAliveSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to sessions") - return - } - - vars := mux.Vars(r) - - sessionId := vars["session_id"] - if len(sessionId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") - return - } - - ss, err := sss.GetSessionById(sessionId) - if ss.Spec.UserId != user.Id { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") - return - } - - if ss.Status.Finished { - util2.ReturnHTTPMessage(w, r, 404, "notfound", "session was finished") - return - } - - if ss.Status.Paused { - glog.V(4).Infof("session %s was paused, returning paused", ss.Name) - - now := time.Now() - pauseExpiration, err := time.Parse(time.UnixDate, ss.Status.PausedTime) - - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, 304, "paused", "session is paused") - return - } - - timeUntilExpiration := pauseExpiration.Sub(now) - - util2.ReturnHTTPMessage(w, r, 202, "paused", timeUntilExpiration.String()) - return - } - - if ss.Spec.AccessCode != "" { - // If we receive an AccessCodeObj from the accessCode Client the AC from this session is still valid, if we find no AccessCode it was deleted or time ran out. - // We will gracefully end this session by just not increasing the Session ExpirationTime anymore. This will end the session at maximum after the AC expired - _, err := sss.accessCodeClient.GetAccessCodeWithOTACs(ss.Spec.AccessCode) - if err != nil { - util2.ReturnHTTPMessage(w, r, 400, "error", "Session is overdue, can not increase duration") - return - } - } - - var scenario hfv1.Scenario - var course hfv1.Course - - if ss.Spec.ScenarioId != "" { - scenario, err = sss.scenarioClient.GetScenarioById(ss.Spec.ScenarioId) - if err != nil { - glog.Errorf("error retrieving scenario %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting scenario") - return - } - } - if ss.Spec.CourseId != "" { - course, err = sss.courseClient.GetCourseById(ss.Spec.CourseId) - if err != nil { - glog.Errorf("error retrieving course %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting course") - return - } - } - - var ssTimeout string - - if course.Spec.KeepAliveDuration != "" { - ssTimeout = course.Spec.KeepAliveDuration - } else if scenario.Spec.KeepAliveDuration != "" { - ssTimeout = scenario.Spec.KeepAliveDuration - } else { - ssTimeout = newSSTimeout - } - - now := time.Now() - duration, _ := time.ParseDuration(ssTimeout) - - expiration := now.Add(duration).Format(time.UnixDate) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(sss.ctx, sessionId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", sessionId, getErr) - } - - result.Status.ExpirationTime = expiration - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated expiration time for session") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error creating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - util2.ReturnHTTPMessage(w, r, 202, "keepalived", "keepalive successful") -} - -func (sss SessionServer) PauseSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to pause sessions") - return - } - - vars := mux.Vars(r) - - sessionId := vars["session_id"] - if len(sessionId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") - return - } - - ss, err := sss.GetSessionById(sessionId) - if ss.Spec.UserId != user.Id { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") - return - } - - var course hfv1.Course - var scenario hfv1.Scenario - - if ss.Spec.CourseId != "" { - course, err = sss.courseClient.GetCourseById(ss.Spec.CourseId) - if err != nil { - glog.Errorf("error retrieving course %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting course") - return - } - } - if ss.Spec.ScenarioId != "" { - scenario, err = sss.scenarioClient.GetScenarioById(ss.Spec.ScenarioId) - if err != nil { - glog.Errorf("error retrieving scenario %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting scenario") - return - } - } - - if !course.Spec.Pauseable && !scenario.Spec.Pauseable { - glog.Errorf("session is not pauseable %s", course.Name) - util2.ReturnHTTPMessage(w, r, 500, "error", "not pauseable") - return - } - - var ssTimeout string - - if course.Spec.PauseDuration != "" { - ssTimeout = course.Spec.PauseDuration - } else if scenario.Spec.PauseDuration != "" { - ssTimeout = scenario.Spec.PauseDuration - } else { - ssTimeout = pauseSSTimeout - } - - now := time.Now() - duration, _ := time.ParseDuration(ssTimeout) - - pauseExpiration := now.Add(duration).Format(time.UnixDate) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(sss.ctx, sessionId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", sessionId, getErr) - } - - result.Status.PausedTime = pauseExpiration - result.Status.Paused = true - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for course session") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error creating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - util2.ReturnHTTPMessage(w, r, 204, "updated", "updated session") -} - -func (sss SessionServer) ResumeSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to resume sessions") - return - } - - vars := mux.Vars(r) - - sessionId := vars["session_id"] - if len(sessionId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") - return - } - - ss, err := sss.GetSessionById(sessionId) - if ss.Spec.UserId != user.Id { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") - return - } - - var course hfv1.Course - var scenario hfv1.Scenario - - if ss.Spec.CourseId != "" { - course, err = sss.courseClient.GetCourseById(ss.Spec.CourseId) - if err != nil { - glog.Errorf("error retrieving course %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting course") - return - } - } - if ss.Spec.ScenarioId != "" { - scenario, err = sss.scenarioClient.GetScenarioById(ss.Spec.ScenarioId) - if err != nil { - glog.Errorf("error retrieving scenario %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error getting scenario") - return - } - } - - var ssTimeout string - - if course.Spec.KeepAliveDuration != "" { - ssTimeout = course.Spec.KeepAliveDuration - } else if scenario.Spec.KeepAliveDuration != "" { - ssTimeout = scenario.Spec.KeepAliveDuration - } else { - ssTimeout = keepaliveSSTimeout - } - - now := time.Now() - duration, _ := time.ParseDuration(ssTimeout) - - newExpiration := now.Add(duration).Format(time.UnixDate) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - result, getErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).Get(sss.ctx, sessionId, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("error retrieving latest version of session %s: %v", sessionId, getErr) - } - - result.Status.PausedTime = "" - result.Status.ExpirationTime = newExpiration - result.Status.Paused = false - - _, updateErr := sss.hfClientSet.HobbyfarmV1().Sessions(util2.GetReleaseNamespace()).UpdateStatus(sss.ctx, result, metav1.UpdateOptions{}) - glog.V(4).Infof("updated result for session") - - return updateErr - }) - - if retryErr != nil { - glog.Errorf("error creating session %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "something happened") - return - } - - util2.ReturnHTTPMessage(w, r, 204, "updated", "resumed session") -} - -func (sss SessionServer) GetSessionFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, sss.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get sessions") - return - } - - vars := mux.Vars(r) - - sessionId := vars["session_id"] - if len(sessionId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") - return - } - - ss, err := sss.GetSessionById(sessionId) - - if err != nil { - glog.Errorf("did not find a coressponding session with the given ID") - util2.ReturnHTTPMessage(w, r, http.StatusNotFound, "error", "no session found") - return - } - - if ss.Spec.UserId != user.Id { - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, sss.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches for this user") - return - } - } - - preparedSession := preparedSession{ss.Name, ss.Spec} - encodedSS, err := json.Marshal(preparedSession) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedSS) - - glog.V(2).Infof("retrieved session %s", ss.Name) -} - -func ssIdIndexer(obj interface{}) ([]string, error) { - ss, ok := obj.(*hfv1.Session) - if !ok { - return []string{}, nil - } - return []string{ss.Name}, nil -} - -func (sss SessionServer) GetSessionById(id string) (hfv1.Session, error) { - if len(id) == 0 { - return hfv1.Session{}, fmt.Errorf("id passed in was empty") - } - - obj, err := sss.ssIndexer.ByIndex(ssIndex, id) - if err != nil { - return hfv1.Session{}, fmt.Errorf("error while retrieving session by id: %s with error: %v", id, err) - } - - if len(obj) < 1 { - return hfv1.Session{}, fmt.Errorf("session server not found by id: %s", id) - } - - Session, ok := obj[0].(*hfv1.Session) - - if !ok { - return hfv1.Session{}, fmt.Errorf("error while converting session found by id to object: %s", id) - } - - return *Session, nil -} diff --git a/v3/pkg/setting/util.go b/v3/pkg/setting/util.go index dfb7c816..c631584c 100644 --- a/v3/pkg/setting/util.go +++ b/v3/pkg/setting/util.go @@ -8,7 +8,7 @@ import ( "github.com/hobbyfarm/gargantua/v3/pkg/property" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" ) type SettingName string @@ -28,42 +28,42 @@ const ( UserTokenExpiration SettingName = "user-token-expiration" ) -var DataTypeMappingToProto = map[property.DataType]settingProto.DataType{ - property.DataTypeFloat: settingProto.DataType_DATA_TYPE_FLOAT, - property.DataTypeInteger: settingProto.DataType_DATA_TYPE_INTEGER, - property.DataTypeString: settingProto.DataType_DATA_TYPE_STRING, - property.DataTypeBoolean: settingProto.DataType_DATA_TYPE_BOOLEAN, +var DataTypeMappingToProto = map[property.DataType]settingpb.DataType{ + property.DataTypeFloat: settingpb.DataType_DATA_TYPE_FLOAT, + property.DataTypeInteger: settingpb.DataType_DATA_TYPE_INTEGER, + property.DataTypeString: settingpb.DataType_DATA_TYPE_STRING, + property.DataTypeBoolean: settingpb.DataType_DATA_TYPE_BOOLEAN, } -var ValueTypeMappingToProto = map[property.ValueType]settingProto.ValueType{ - property.ValueTypeArray: settingProto.ValueType_VALUE_TYPE_ARRAY, - property.ValueTypeMap: settingProto.ValueType_VALUE_TYPE_MAP, - property.ValueTypeScalar: settingProto.ValueType_VALUE_TYPE_SCALAR, +var ValueTypeMappingToProto = map[property.ValueType]settingpb.ValueType{ + property.ValueTypeArray: settingpb.ValueType_VALUE_TYPE_ARRAY, + property.ValueTypeMap: settingpb.ValueType_VALUE_TYPE_MAP, + property.ValueTypeScalar: settingpb.ValueType_VALUE_TYPE_SCALAR, } -var DataTypeMappingToHfTypes = map[settingProto.DataType]property.DataType{ - settingProto.DataType_DATA_TYPE_FLOAT: property.DataTypeFloat, - settingProto.DataType_DATA_TYPE_INTEGER: property.DataTypeInteger, - settingProto.DataType_DATA_TYPE_STRING: property.DataTypeString, - settingProto.DataType_DATA_TYPE_BOOLEAN: property.DataTypeBoolean, +var DataTypeMappingToHfTypes = map[settingpb.DataType]property.DataType{ + settingpb.DataType_DATA_TYPE_FLOAT: property.DataTypeFloat, + settingpb.DataType_DATA_TYPE_INTEGER: property.DataTypeInteger, + settingpb.DataType_DATA_TYPE_STRING: property.DataTypeString, + settingpb.DataType_DATA_TYPE_BOOLEAN: property.DataTypeBoolean, } -var ValueTypeMappingToHfTypes = map[settingProto.ValueType]property.ValueType{ - settingProto.ValueType_VALUE_TYPE_ARRAY: property.ValueTypeArray, - settingProto.ValueType_VALUE_TYPE_MAP: property.ValueTypeMap, - settingProto.ValueType_VALUE_TYPE_SCALAR: property.ValueTypeScalar, +var ValueTypeMappingToHfTypes = map[settingpb.ValueType]property.ValueType{ + settingpb.ValueType_VALUE_TYPE_ARRAY: property.ValueTypeArray, + settingpb.ValueType_VALUE_TYPE_MAP: property.ValueTypeMap, + settingpb.ValueType_VALUE_TYPE_SCALAR: property.ValueTypeScalar, } -func FromJSON(p *settingProto.Property, value string) (any, error) { - if p.ValueType == settingProto.ValueType_VALUE_TYPE_SCALAR { +func FromJSON(p *settingpb.Property, value string) (any, error) { + if p.ValueType == settingpb.ValueType_VALUE_TYPE_SCALAR { switch p.DataType { - case settingProto.DataType_DATA_TYPE_FLOAT: + case settingpb.DataType_DATA_TYPE_FLOAT: return strconv.ParseFloat(value, 64) - case settingProto.DataType_DATA_TYPE_INTEGER: + case settingpb.DataType_DATA_TYPE_INTEGER: return strconv.Atoi(value) - case settingProto.DataType_DATA_TYPE_BOOLEAN: + case settingpb.DataType_DATA_TYPE_BOOLEAN: return strconv.ParseBool(value) - case settingProto.DataType_DATA_TYPE_STRING: + case settingpb.DataType_DATA_TYPE_STRING: fallthrough default: return value, nil @@ -73,35 +73,35 @@ func FromJSON(p *settingProto.Property, value string) (any, error) { decoder := json.NewDecoder(strings.NewReader(value)) decoder.DisallowUnknownFields() - if p.ValueType == settingProto.ValueType_VALUE_TYPE_MAP { + if p.ValueType == settingpb.ValueType_VALUE_TYPE_MAP { switch p.DataType { - case settingProto.DataType_DATA_TYPE_FLOAT: + case settingpb.DataType_DATA_TYPE_FLOAT: var out = map[string]float64{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_INTEGER: + case settingpb.DataType_DATA_TYPE_INTEGER: var out = map[string]int{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_STRING: + case settingpb.DataType_DATA_TYPE_STRING: var out = map[string]string{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_BOOLEAN: + case settingpb.DataType_DATA_TYPE_BOOLEAN: var out = map[string]bool{} return out, decoder.Decode(&out) } } - if p.ValueType == settingProto.ValueType_VALUE_TYPE_ARRAY { + if p.ValueType == settingpb.ValueType_VALUE_TYPE_ARRAY { switch p.DataType { - case settingProto.DataType_DATA_TYPE_FLOAT: + case settingpb.DataType_DATA_TYPE_FLOAT: var out = []float64{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_INTEGER: + case settingpb.DataType_DATA_TYPE_INTEGER: var out = []int{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_STRING: + case settingpb.DataType_DATA_TYPE_STRING: var out = []string{} return out, decoder.Decode(&out) - case settingProto.DataType_DATA_TYPE_BOOLEAN: + case settingpb.DataType_DATA_TYPE_BOOLEAN: var out = []bool{} return out, decoder.Decode(&out) } diff --git a/v3/pkg/shell/shell.go b/v3/pkg/shell/shell.go index a7533090..0a8caa50 100644 --- a/v3/pkg/shell/shell.go +++ b/v3/pkg/shell/shell.go @@ -15,18 +15,20 @@ import ( "sync" "time" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - "github.com/hobbyfarm/gargantua/v3/pkg/vmclient" "github.com/golang/glog" "github.com/gorilla/mux" "github.com/gorilla/websocket" hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -34,12 +36,11 @@ import ( ) type ShellProxy struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - vmClient *vmclient.VirtualMachineClient - hfClient hfClientset.Interface - kubeClient kubernetes.Interface - ctx context.Context + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + vmClient vmpb.VMSvcClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient + kubeClient kubernetes.Interface } type Service struct { @@ -78,17 +79,20 @@ func init() { SIGWINCH = regexp.MustCompile(`.*\[8;(.*);(.*)t`) } -func NewShellProxy(authnClient authn.AuthNClient, authrClient authr.AuthRClient, vmClient *vmclient.VirtualMachineClient, hfClientSet hfClientset.Interface, kubeClient kubernetes.Interface, ctx context.Context) (*ShellProxy, error) { - shellProxy := ShellProxy{} - - shellProxy.authnClient = authnClient - shellProxy.authrClient = authrClient - shellProxy.vmClient = vmClient - shellProxy.hfClient = hfClientSet - shellProxy.kubeClient = kubeClient - shellProxy.ctx = ctx - - return &shellProxy, nil +func NewShellProxy( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + vmClient vmpb.VMSvcClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + kubeClient kubernetes.Interface, +) *ShellProxy { + return &ShellProxy{ + authnClient: authnClient, + authrClient: authrClient, + vmClient: vmClient, + vmTemplateClient: vmTemplateClient, + kubeClient: kubeClient, + } } func (sp ShellProxy) SetupRoutes(r *mux.Router) { @@ -123,7 +127,7 @@ func (sp ShellProxy) setAuthCookieAndRedirect(w http.ResponseWriter, r *http.Req cookie := http.Cookie{Name: "jwt", Value: authToken, SameSite: http.SameSiteNoneMode, Secure: true, Path: "/"} http.SetCookie(w, &cookie) url := mux.Vars(r)["rest"] - http.Redirect(w, r, "/"+url, 302) + http.Redirect(w, r, "/"+url, http.StatusFound) } @@ -146,16 +150,16 @@ func (sp ShellProxy) checkCookieAndProxy(w http.ResponseWriter, r *http.Request) sp.proxy(w, r, user) } -func (sp ShellProxy) proxyAuth(w http.ResponseWriter, r *http.Request, token string) (*userProto.User, error) { +func (sp ShellProxy) proxyAuth(w http.ResponseWriter, r *http.Request, token string) (*userpb.User, error) { r.Header.Add("Authorization", "Bearer "+token) user, err := rbac2.AuthenticateRequest(r, sp.authnClient) if err != nil { - return &userProto.User{}, err + return &userpb.User{}, err } return user, nil } -func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userProto.User) { +func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userpb.User) { vars := mux.Vars(r) // Check if variable for vm id was passed in @@ -165,7 +169,7 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro return } // Get the corresponding VM, if it exists - vm, err := sp.vmClient.GetVirtualMachineById(vmId) + vm, err := sp.vmClient.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) if err != nil { glog.Errorf("did not find the right virtual machine ID") @@ -173,10 +177,10 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro return } - if vm.Spec.UserId != user.GetId() { + if vm.GetUser() != user.GetId() { // check if the user has access to user sessions impersonatedUserId := user.GetId() - authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authr.Permission{ + authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authrpb.Permission{ rbac2.HobbyfarmPermission(rbac2.ResourcePluralUser, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralSession, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralVM, rbac2.VerbGet), @@ -189,9 +193,17 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro } // Get the corresponding VMTemplate for the VM - vmt, err := sp.hfClient.HobbyfarmV1().VirtualMachineTemplates(util.GetReleaseNamespace()).Get(sp.ctx, vm.Spec.VirtualMachineTemplateId, v1.GetOptions{}) + vmtId := vm.GetVmTemplateId() + vmt, err := sp.vmTemplateClient.GetVMTemplate(r.Context(), &generalpb.GetRequest{Id: vm.GetVmTemplateId()}) if err != nil { - util.ReturnHTTPMessage(w, r, 404, "error", "no vm template found") + glog.Errorf("error while retrieving virtual machine template: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("virtual machine template %s not found", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving virtual machine template %s", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) return } @@ -204,7 +216,7 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro // find the corresponding service service := Service{} hasService := false - if servicesMarhaled, ok := vmt.Spec.ConfigMap["webinterfaces"]; ok { + if servicesMarhaled, ok := vmt.GetConfigMap()["webinterfaces"]; ok { servicesUnmarshaled := []Service{} err = json.Unmarshal([]byte(servicesMarhaled), &servicesUnmarshaled) @@ -229,7 +241,7 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro return } - secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(sp.ctx, vm.Spec.SecretName, v1.GetOptions{}) // idk? + secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(r.Context(), vm.GetSecretName(), v1.GetOptions{}) // idk? if err != nil { glog.Errorf("did not find secret for virtual machine") util.ReturnHTTPMessage(w, r, 500, "error", "unable to find keypair secret for vm") @@ -244,7 +256,7 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro return } - sshUsername := vm.Spec.SshUsername + sshUsername := vm.GetSshUsername() if len(sshUsername) < 1 { sshUsername = defaultSshUsername } @@ -261,7 +273,7 @@ func (sp ShellProxy) proxy(w http.ResponseWriter, r *http.Request, user *userPro // get the host and port host, ok := vm.Annotations["sshEndpoint"] if !ok { - host = vm.Status.PublicIP + host = vm.GetStatus().GetPublicIp() } port := "22" if sshDev == "true" { @@ -333,7 +345,7 @@ func (sp ShellProxy) ConnectGuacFunc(w http.ResponseWriter, r *http.Request) { return } - vm, err := sp.vmClient.GetVirtualMachineById(vmId) + vm, err := sp.vmClient.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) if err != nil { glog.Errorf("did not find the right virtual machine ID") @@ -341,15 +353,15 @@ func (sp ShellProxy) ConnectGuacFunc(w http.ResponseWriter, r *http.Request) { return } - if vm.Spec.UserId != user.GetId() { + if vm.GetUser() != user.GetId() { util.ReturnHTTPMessage(w, r, 403, "forbidden", "you do not have access to shell") return } - glog.Infof("Going to upgrade guac connection now... %s", vm.Name) + glog.Infof("Going to upgrade guac connection now... %s", vmId) // ok first get the secret for the vm - secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(sp.ctx, vm.Spec.SecretName, v1.GetOptions{}) // idk? + secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(r.Context(), vm.GetSecretName(), v1.GetOptions{}) // idk? if err != nil { glog.Errorf("did not find secret for virtual machine") util.ReturnHTTPMessage(w, r, 500, "error", "unable to find keypair secret for vm") @@ -358,14 +370,14 @@ func (sp ShellProxy) ConnectGuacFunc(w http.ResponseWriter, r *http.Request) { password := string(secret.Data["password"]) - username := vm.Spec.SshUsername + username := vm.GetSshUsername() if len(username) < 1 { username = defaultSshUsername } // get the host and port - host := vm.Status.PublicIP - protocol := strings.ToLower(vm.Spec.Protocol) + host := vm.GetStatus().GetPublicIp() + protocol := strings.ToLower(vm.GetProtocol()) port := mapProtocolToPort()[protocol] optimalHeight := r.URL.Query().Get("height") @@ -677,10 +689,9 @@ func CreateNewSession(sshConn *ssh.Client, errorChan chan<- error) (*ssh.Session return sess, nil } -func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *userProto.User, vmId string, errorChan chan<- error) (*ssh.Client, error) { - - vm, err := sp.vmClient.GetVirtualMachineById(vmId) +func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *userpb.User, vmId string, errorChan chan<- error) (*ssh.Client, error) { + vm, err := sp.vmClient.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) if err != nil { glog.Errorf("did not find the right virtual machine ID") if len(errorChan) < cap(errorChan) { @@ -688,11 +699,11 @@ func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *us } return nil, err } - if vm.Spec.UserId != user.GetId() { + if vm.GetUser() != user.GetId() { // check if the user has access to access user sessions // TODO: add permission like 'virtualmachine/shell' similar to 'pod/exec' impersonatedUserId := user.GetId() - authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authr.Permission{ + authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authrpb.Permission{ rbac2.HobbyfarmPermission(rbac2.ResourcePluralUser, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralSession, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralVM, rbac2.VerbGet), @@ -705,7 +716,7 @@ func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *us } // ok first get the secret for the vm - secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(sp.ctx, vm.Spec.SecretName, v1.GetOptions{}) // idk? + secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(r.Context(), vm.GetSecretName(), v1.GetOptions{}) // idk? if err != nil { glog.Errorf("did not find secret for virtual machine") util.ReturnHTTPMessage(w, r, 500, "error", "unable to find keypair secret for vm") @@ -720,7 +731,7 @@ func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *us return nil, err } - sshUsername := vm.Spec.SshUsername + sshUsername := vm.GetSshUsername() if len(sshUsername) < 1 { sshUsername = defaultSshUsername } @@ -737,7 +748,7 @@ func (sp ShellProxy) GetSSHConn(w http.ResponseWriter, r *http.Request, user *us // get the host and port host, ok := vm.Annotations["sshEndpoint"] if !ok { - host = vm.Status.PublicIP + host = vm.GetStatus().GetPublicIp() } port := "22" if sshDev == "true" { @@ -844,7 +855,7 @@ func (sp ShellProxy) ConnectSSHFunc(w http.ResponseWriter, r *http.Request) { return } - vm, err := sp.vmClient.GetVirtualMachineById(vmId) + vm, err := sp.vmClient.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) if err != nil { glog.Errorf("did not find the right virtual machine ID") @@ -852,11 +863,11 @@ func (sp ShellProxy) ConnectSSHFunc(w http.ResponseWriter, r *http.Request) { return } - if vm.Spec.UserId != user.GetId() { + if vm.GetUser() != user.GetId() { // check if the user has access to access user sessions // TODO: add permission like 'virtualmachine/shell' similar to 'pod/exec' impersonatedUserId := user.GetId() - authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authr.Permission{ + authrResponse, err := rbac2.Authorize(r, sp.authrClient, impersonatedUserId, []*authrpb.Permission{ rbac2.HobbyfarmPermission(rbac2.ResourcePluralUser, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralSession, rbac2.VerbGet), rbac2.HobbyfarmPermission(rbac2.ResourcePluralVM, rbac2.VerbGet), @@ -868,10 +879,10 @@ func (sp ShellProxy) ConnectSSHFunc(w http.ResponseWriter, r *http.Request) { } } - glog.Infof("Going to upgrade connection now... %s", vm.Name) + glog.Infof("Going to upgrade connection now... %s", vmId) // ok first get the secret for the vm - secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(sp.ctx, vm.Spec.SecretName, v1.GetOptions{}) // idk? + secret, err := sp.kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()).Get(r.Context(), vm.GetSecretName(), v1.GetOptions{}) // idk? if err != nil { glog.Errorf("did not find secret for virtual machine") util.ReturnHTTPMessage(w, r, 500, "error", "unable to find keypair secret for vm") @@ -886,7 +897,7 @@ func (sp ShellProxy) ConnectSSHFunc(w http.ResponseWriter, r *http.Request) { return } - sshUsername := vm.Spec.SshUsername + sshUsername := vm.GetSshUsername() if len(sshUsername) < 1 { sshUsername = defaultSshUsername } @@ -903,7 +914,7 @@ func (sp ShellProxy) ConnectSSHFunc(w http.ResponseWriter, r *http.Request) { // get the host and port host, ok := vm.Annotations["sshEndpoint"] if !ok { - host = vm.Status.PublicIP + host = vm.GetStatus().GetPublicIp() } port := "22" if sshDev == "true" { diff --git a/v3/pkg/util/conversion.go b/v3/pkg/util/conversion.go new file mode 100644 index 00000000..00692f8a --- /dev/null +++ b/v3/pkg/util/conversion.go @@ -0,0 +1,57 @@ +package util + +import ( + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" +) + +type IntegerType interface { + uint32 | int +} + +// A function that converts an integer type T to an integer type U +func ConvertIntMap[T, U IntegerType](input map[string]T) map[string]U { + output := make(map[string]U) + for key, value := range input { + output[key] = U(value) + } + return output +} + +// A helper function that converts nested maps containing a struct with a map field into raw nested maps. +// E. g., it can convert map[string]*generalpb.StringMap to map[string]map[string]string. +// To make this work generic, we additionally need to pass a function which retrieves the raw map from our struct value. +// E. g., GetRawStringMap retrieves the raw map[string]string from *generalpb.StringMap. +func ConvertMapStruct[K comparable, V any, T any](input map[string]T, getMapFunc func(T) map[K]V) map[string]map[K]V { + output := make(map[string]map[K]V, len(input)) + for key, val := range input { + output[key] = getMapFunc(val) + } + return output +} + +func GetRawStringMap(val *generalpb.StringMap) map[string]string { + return val.GetValue() +} + +func GetRawVMTemplateCountMap(val *scheduledeventpb.VMTemplateCountMap) map[string]uint32 { + return val.GetVmTemplateCounts() +} + +// A function that converts []*generalpb.StringMap to []map[string]string +func ConvertToStringMapSlice(stringMapSlice []*generalpb.StringMap) []map[string]string { + output := make([]map[string]string, 0, len(stringMapSlice)) + for _, vm := range stringMapSlice { + output = append(output, vm.GetValue()) + } + return output +} + +// A function that converts map[string]map[string]string to map[string]*generalpb.StringMap +func ConvertToStringMapStructMap(in map[string]map[string]string) map[string]*generalpb.StringMap { + output := make(map[string]*generalpb.StringMap, len(in)) + for key, val := range in { + output[key] = &generalpb.StringMap{Value: val} + } + return output +} diff --git a/v3/pkg/util/delete.go b/v3/pkg/util/delete.go new file mode 100644 index 00000000..5fa38f23 --- /dev/null +++ b/v3/pkg/util/delete.go @@ -0,0 +1,67 @@ +package util + +import ( + "context" + + "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type HfClientDelete interface { + Delete(ctx context.Context, id string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, deleteOptions metav1.DeleteOptions, listOptions metav1.ListOptions) error +} + +func DeleteHfResource( + ctx context.Context, + req *generalpb.ResourceId, + clientDelete HfClientDelete, + resourceName string, +) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + glog.V(2).Infof("error no id provided for %s", resourceName) + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + err := clientDelete.Delete(ctx, id, metav1.DeleteOptions{}) + if errors.IsNotFound(err) { + return &emptypb.Empty{}, hferrors.GrpcNotFoundError(req, resourceName) + } else if err != nil { + glog.Errorf("error deleting %s %s: %s", resourceName, id, err) + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error deleting %s %s", + req, + resourceName, + id, + ) + } + return &emptypb.Empty{}, nil +} + +func DeleteHfCollection( + ctx context.Context, + listOptions *generalpb.ListOptions, + clientDelete HfClientDelete, + resourceName string, +) (*emptypb.Empty, error) { + err := clientDelete.DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{ + LabelSelector: listOptions.GetLabelSelector(), + }) + if err != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error deleting %s", + listOptions, + resourceName, + ) + } + + return &emptypb.Empty{}, nil +} diff --git a/v3/pkg/util/filter.go b/v3/pkg/util/filter.go new file mode 100644 index 00000000..f086862f --- /dev/null +++ b/v3/pkg/util/filter.go @@ -0,0 +1,80 @@ +package util + +import ( + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" +) + +// ScenarioProvider is an interface for any object that can provide scenarios. E. g. ScheduledEvents or Courses. +type ScenarioProvider interface { + GetScenarios() []string +} + +// Implemented by FilterByScenario and FilterByCourse +type EventFilterfunc func(se *scheduledeventpb.ScheduledEvent, objId string) bool + +// Implemented by IsSessionOfScenario and IsSessionOfCourse +type SessionFilterfunc func(se *sessionpb.Session, objId string) bool + +// Filter a ScheduledEventList to find SEs that are a) active and b) using the course/scenario specified +func FilterScheduledEvents( + objId string, + seList *scheduledeventpb.ListScheduledEventsResponse, + filterFunc EventFilterfunc, +) []*scheduledeventpb.ScheduledEvent { + outList := make([]*scheduledeventpb.ScheduledEvent, 0) + for _, se := range seList.GetScheduledevents() { + if se.GetStatus().GetFinished() { + continue + } else if filterFunc(se, objId) { + outList = append(outList, se) + } + } + + return outList +} + +func FilterSessions( + objId string, + sessList *sessionpb.ListSessionsResponse, + filterFunc SessionFilterfunc, +) []*sessionpb.Session { + outList := make([]*sessionpb.Session, 0) + for _, sess := range sessList.GetSessions() { + if filterFunc(sess, objId) { + outList = append(outList, sess) + } + } + + return outList +} + +// Specific filter function for scenarios +func FilterByScenario[T ScenarioProvider](obj T, scenario string) bool { + return containsObjId(obj.GetScenarios(), scenario) +} + +// Specific filter function for courses +func FilterByCourse(se *scheduledeventpb.ScheduledEvent, course string) bool { + return containsObjId(se.GetCourses(), course) +} + +// Returns true if session is assigned to the provided course +func IsSessionOfCourse(sess *sessionpb.Session, course string) bool { + return sess.GetCourse() == course +} + +// Returns true if session is assigned to the provided scenario +func IsSessionOfScenario(sess *sessionpb.Session, scenario string) bool { + return sess.GetScenario() == scenario +} + +// Helper function which returns if a string slice contains a specific object id +func containsObjId(objIds []string, obj string) bool { + for _, o := range objIds { + if o == obj { + return true + } + } + return false +} diff --git a/v3/pkg/util/finalizer.go b/v3/pkg/util/finalizer.go new file mode 100644 index 00000000..250301e3 --- /dev/null +++ b/v3/pkg/util/finalizer.go @@ -0,0 +1,38 @@ +package util + +// type HfClientUpdate[T metav1.Object] interface { +// Update(ctx context.Context, id string, opts metav1.UpdateOptions) (T, error) +// } + +// func GenericRemoveFinalizer[T metav1.Object, U HfClientUpdate[T]](ctx context.Context, obj T, client U, finalizer string) (err error) { +// finalizers := obj.GetFinalizers() +// if containsFinalizer(finalizers, finalizer) { +// newFinalizers := RemoveFinalizer(finalizers, finalizer) +// obj.SetFinalizers(newFinalizers) +// _, err = client.Update(ctx, obj.GetName(), metav1.UpdateOptions{}) +// } +// return err +// } + +// From ControllerUtil to save dep issues + +// RemoveFinalizer accepts a slice of finalizers and removes the provided finalizer if present. +func RemoveFinalizer(finalizers []string, finalizer string) []string { + for i := 0; i < len(finalizers); i++ { + if finalizers[i] == finalizer { + finalizers = append(finalizers[:i], finalizers[i+1:]...) + i-- + } + } + return finalizers +} + +// ContainsFinalizer checks an Object that the provided finalizer is present. +func ContainsFinalizer(finalizers []string, finalizer string) bool { + for _, e := range finalizers { + if e == finalizer { + return true + } + } + return false +} diff --git a/v3/pkg/util/getter.go b/v3/pkg/util/getter.go new file mode 100644 index 00000000..72cd2742 --- /dev/null +++ b/v3/pkg/util/getter.go @@ -0,0 +1,92 @@ +package util + +import ( + "context" + + "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + "google.golang.org/protobuf/types/known/wrapperspb" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type HfClientGet[T metav1.Object] interface { + Get(ctx context.Context, id string, opts metav1.GetOptions) (T, error) +} + +type GenericCacheRetriever[T metav1.Object] interface { + Get(id string) (T, error) +} + +func GenericHfGetter[T metav1.Object, G HfClientGet[T], C GenericCacheRetriever[T]]( + ctx context.Context, + req *generalpb.GetRequest, + getter G, + cacheGetter C, + resourceName string, + hasSynced bool, +) (T, error) { + var result T + id := req.GetId() + doLoadFromCache := req.GetLoadFromCache() + if len(id) == 0 { + glog.V(2).Infof("error no id provided for %s", resourceName) + return result, hferrors.GrpcIdNotSpecifiedError(req) + } + var obj T + var err error + if !doLoadFromCache { + obj, err = getter.Get(ctx, id, metav1.GetOptions{}) + } else if hasSynced { + obj, err = cacheGetter.Get(id) + } else { + glog.V(2).Infof("error while retrieving %s by id: cache is not properly synced yet", resourceName) + // our cache is not properly initialized yet ... returning status unavailable + return result, hferrors.GrpcCacheError(req, resourceName) + } + if errors.IsNotFound(err) { + return result, hferrors.GrpcNotFoundError(req, resourceName) + } else if err != nil { + glog.V(2).Infof("error while retrieving %s: %v", resourceName, err) + return result, hferrors.GrpcGetError(req, resourceName, err) + } + + return obj, nil +} + +func GetOwnerReferences[T metav1.Object, G HfClientGet[T], C GenericCacheRetriever[T]]( + ctx context.Context, + req *generalpb.GetRequest, + getter G, + cacheGetter C, + resourceName string, + hasSynced bool, +) (*generalpb.OwnerReferences, error) { + obj, err := GenericHfGetter(ctx, req, getter, cacheGetter, resourceName, hasSynced) + if err != nil { + return &generalpb.OwnerReferences{}, err + } + + preparedOwnerRefs := []*generalpb.OwnerReference{} + + for _, ownerRef := range obj.GetOwnerReferences() { + hasManagingController := ownerRef.Controller + hasBlockOwnerDeletion := ownerRef.BlockOwnerDeletion + tempOwnerRef := &generalpb.OwnerReference{ + ApiVersion: ownerRef.APIVersion, + Kind: ownerRef.Kind, + Id: ownerRef.Name, + Uid: string(ownerRef.UID), + } + if hasManagingController != nil { + tempOwnerRef.Controller = wrapperspb.Bool(*hasManagingController) + } + if hasBlockOwnerDeletion != nil { + tempOwnerRef.BlockOwnerDeletion = wrapperspb.Bool(*hasBlockOwnerDeletion) + } + preparedOwnerRefs = append(preparedOwnerRefs, tempOwnerRef) + } + + return &generalpb.OwnerReferences{OwnerReferences: preparedOwnerRefs}, nil +} diff --git a/v3/pkg/util/labels.go b/v3/pkg/util/labels.go deleted file mode 100644 index 49199617..00000000 --- a/v3/pkg/util/labels.go +++ /dev/null @@ -1,12 +0,0 @@ -package util - -const ( - AccessCodeLabel = "hobbyfarm.io/accesscode" - OneTimeAccessCodeLabel ="hobbyfarm.io/otac" - ScheduledEventLabel = "hobbyfarm.io/scheduledevent" - SessionLabel = "hobbyfarm.io/session" - UserLabel = "hobbyfarm.io/user" - RBACManagedLabel = "rbac.hobbyfarm.io/managed" - EnvironmentLabel = "hobbyfarm.io/environment" - VirtualMachineTemplate ="hobbyfarm.io/virtualmachinetemplate" -) \ No newline at end of file diff --git a/v3/pkg/util/lister.go b/v3/pkg/util/lister.go new file mode 100644 index 00000000..cf4e1b3a --- /dev/null +++ b/v3/pkg/util/lister.go @@ -0,0 +1,56 @@ +package util + +import ( + "context" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + "google.golang.org/grpc/codes" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +type HfClientList[T any] interface { + List(ctx context.Context, opts metav1.ListOptions) (T, error) +} + +type GenericLister[T any] interface { + List(labels.Selector) ([]*T, error) +} + +func ListByHfClient[T any, L HfClientList[T]](ctx context.Context, listOptions *generalpb.ListOptions, lister L, resourcename string) (T, error) { + labelSelectorString := listOptions.GetLabelSelector() + objList, err := lister.List(ctx, metav1.ListOptions{ + LabelSelector: labelSelectorString, + }) + if err != nil { + return objList, hferrors.GrpcListError(listOptions, resourcename) + } + return objList, nil +} + +func ListByCache[T any, L GenericLister[T]](listOptions *generalpb.ListOptions, lister L, resourcename string, hasSynced bool) ([]T, error) { + labelSelectorString := listOptions.GetLabelSelector() + labelSelector, err := labels.Parse(labelSelectorString) + if err != nil { + return []T{}, hferrors.GrpcError( + codes.Internal, + "error parsing label selector", + listOptions, + ) + } + vmClaims := []T{} + if hasSynced { + vmcList, err := lister.List(labelSelector) + if err != nil { + return []T{}, hferrors.GrpcListError(listOptions, resourcename) + } + for _, vmc := range vmcList { + vmClaims = append(vmClaims, *vmc) + } + return vmClaims, nil + } else { + // our cache is not properly initialized yet ... returning status unavailable + return []T{}, hferrors.GrpcCacheError(listOptions, resourcename) + } +} diff --git a/v3/pkg/util/unmarshal.go b/v3/pkg/util/unmarshal.go new file mode 100644 index 00000000..bf572fb9 --- /dev/null +++ b/v3/pkg/util/unmarshal.go @@ -0,0 +1,18 @@ +package util + +import ( + "encoding/json" + "fmt" + + "github.com/golang/glog" +) + +func GenericUnmarshal[T any](rawObj string, propName string) (T, error) { + var obj T + err := json.Unmarshal([]byte(rawObj), &obj) + if err != nil { + glog.Errorf("error while unmarshaling %s: %v", propName, err) + return obj, fmt.Errorf("bad") + } + return obj, nil +} diff --git a/v3/pkg/util/util.go b/v3/pkg/util/util.go index d7b2ee34..f5b13f1b 100644 --- a/v3/pkg/util/util.go +++ b/v3/pkg/util/util.go @@ -16,6 +16,14 @@ import ( hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" v1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" "github.com/golang/glog" "golang.org/x/crypto/ssh" @@ -315,16 +323,11 @@ func EnsureVMNotReady(hfClientset hfClientset.Interface, vmLister v1.VirtualMach return nil } -// pending rename... -type Maximus struct { - AvailableCount map[string]int `json:"available_count"` -} - // Range with reserved virtual machine amounts for given time range type Range struct { Start time.Time End time.Time - VMMapping map[string]int + VMMapping map[string]uint32 } // These functions are used to sort arrays of time.Time @@ -337,7 +340,7 @@ func sortTime(timeArray []time.Time) { sort.Sort(ByTime(timeArray)) } -func Max(x, y int) int { +func MaxUint32(x, y uint32) uint32 { if x < y { return y } @@ -346,10 +349,10 @@ func Max(x, y int) int { // Calculates available virtualMachineTemplates for a given period (startString, endString) and environment // Returns a map with timestamps and corresponding availability of virtualmachines. Also returns the maximum available count of virtualmachinetemplates over the whole duration. -func VirtualMachinesUsedDuringPeriod(hfClientset hfClientset.Interface, environment string, startString string, endString string, ctx context.Context) (map[time.Time]map[string]int, map[string]int, error) { +func VirtualMachinesUsedDuringPeriod(eventClient scheduledeventpb.ScheduledEventSvcClient, environment string, startString string, endString string, ctx context.Context) (map[time.Time]map[string]uint32, map[string]uint32, error) { start, err := time.Parse(time.UnixDate, startString) if err != nil { - return map[time.Time]map[string]int{}, map[string]int{}, fmt.Errorf("error parsing start time %v", err) + return map[time.Time]map[string]uint32{}, map[string]uint32{}, fmt.Errorf("error parsing start time %v", err) } // We only want to calculate for the future. Otherwise old ( even finished ) events will be considered too. @@ -359,37 +362,41 @@ func VirtualMachinesUsedDuringPeriod(hfClientset hfClientset.Interface, environm end, err := time.Parse(time.UnixDate, endString) if err != nil { - return map[time.Time]map[string]int{}, map[string]int{}, fmt.Errorf("error parsing end time %v", err) + return map[time.Time]map[string]uint32{}, map[string]uint32{}, fmt.Errorf("error parsing end time %v", err) } - scheduledEvents, err := hfClientset.HobbyfarmV1().ScheduledEvents(GetReleaseNamespace()).List(ctx, metav1.ListOptions{}) + scheduledEventList, err := eventClient.ListScheduledEvent(ctx, &generalpb.ListOptions{}) if err != nil { - return map[time.Time]map[string]int{}, map[string]int{}, fmt.Errorf("error retrieving scheduled events %v", err) + return map[time.Time]map[string]uint32{}, map[string]uint32{}, fmt.Errorf("error retrieving scheduled events: %s", hferrors.GetErrorMessage(err)) } var timeRange []Range - var changingTimestamps []time.Time // All timestamps where number of virtualmachines changes (Begin or End of Scheduled Event) - virtualMachineCount := make(map[time.Time]map[string]int) // Count of virtualmachines per VMTemplate for any given timestamp where a change happened - maximumVirtualMachineCount := make(map[string]int) // Maximum VirtualMachine Count per VirtualMachineTemplate over all timestamps + var changingTimestamps []time.Time // All timestamps where number of virtualmachines changes (Begin or End of Scheduled Event) + virtualMachineCount := make(map[time.Time]map[string]uint32) // Count of virtualmachines per VMTemplate for any given timestamp where a change happened + maximumVirtualMachineCount := make(map[string]uint32) // Maximum VirtualMachine Count per VirtualMachineTemplate over all timestamps - for _, se := range scheduledEvents.Items { + for _, se := range scheduledEventList.GetScheduledevents() { // Scheduled Event uses the environment we are checking - if vmMapping, ok := se.Spec.RequiredVirtualMachines[environment]; ok { - seStart, err := time.Parse(time.UnixDate, se.Spec.StartTime) + if vmMapping, ok := se.GetRequiredVms()[environment]; ok { + seStart, err := time.Parse(time.UnixDate, se.GetStartTime()) if err != nil { - return map[time.Time]map[string]int{}, map[string]int{}, fmt.Errorf("error parsing scheduled event start %v", err) + return map[time.Time]map[string]uint32{}, map[string]uint32{}, fmt.Errorf("error parsing scheduled event start %v", err) } - seEnd, err := time.Parse(time.UnixDate, se.Spec.EndTime) + seEnd, err := time.Parse(time.UnixDate, se.GetEndTime()) if err != nil { - return map[time.Time]map[string]int{}, map[string]int{}, fmt.Errorf("error parsing scheduled event end %v", err) + return map[time.Time]map[string]uint32{}, map[string]uint32{}, fmt.Errorf("error parsing scheduled event end %v", err) } // Scheduled Event is withing our timerange. We consider it by adding it to our Ranges if start.Equal(seStart) || end.Equal(seEnd) || (start.Before(seEnd) && end.After(seStart)) { - timeRange = append(timeRange, Range{Start: seStart, End: seEnd, VMMapping: vmMapping}) + timeRange = append(timeRange, Range{ + Start: seStart, + End: seEnd, + VMMapping: vmMapping.GetVmTemplateCounts(), + }) changingTimestamps = append(changingTimestamps, seStart) changingTimestamps = append(changingTimestamps, seEnd) - virtualMachineCount[seStart] = make(map[string]int) - virtualMachineCount[seEnd] = make(map[string]int) + virtualMachineCount[seStart] = make(map[string]uint32) + virtualMachineCount[seEnd] = make(map[string]uint32) glog.V(4).Infof("Scheduled Event %s was within the time period", se.Name) } } @@ -418,7 +425,7 @@ func VirtualMachinesUsedDuringPeriod(hfClientset hfClientset.Interface, environm } // Highest VM Capacity over all timestamps if maximumVMCapacity, ok := maximumVirtualMachineCount[vmTemplateName]; ok { - maximumVirtualMachineCount[vmTemplateName] = Max(maximumVMCapacity, virtualMachineCount[timestamp][vmTemplateName]) + maximumVirtualMachineCount[vmTemplateName] = MaxUint32(maximumVMCapacity, virtualMachineCount[timestamp][vmTemplateName]) } else { maximumVirtualMachineCount[vmTemplateName] = vmTemplateCount } @@ -430,53 +437,25 @@ func VirtualMachinesUsedDuringPeriod(hfClientset hfClientset.Interface, environm return virtualMachineCount, maximumVirtualMachineCount, nil } -func CountMachinesPerTemplateAndEnvironment(vmLister v1.VirtualMachineLister, template string, enviroment string) (int, error) { +func CountMachinesPerTemplateAndEnvironment(ctx context.Context, vmClient vmpb.VMSvcClient, template string, enviroment string) (int, error) { vmLabels := labels.Set{ - EnvironmentLabel: enviroment, - VirtualMachineTemplate: template, + hflabels.EnvironmentLabel: enviroment, + hflabels.VirtualMachineTemplate: template, } - vms, err := vmLister.List(vmLabels.AsSelector()) - return len(vms), err + vmList, err := vmClient.ListVM(ctx, &generalpb.ListOptions{LabelSelector: vmLabels.AsSelector().String(), LoadFromCache: true}) + return len(vmList.GetVms()), err } -func CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(vmLister v1.VirtualMachineLister, template string, enviroment string, se string) (int, error) { +func CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(ctx context.Context, vmClient vmpb.VMSvcClient, template string, enviroment string, se string) (int, error) { vmLabels := labels.Set{ - EnvironmentLabel: enviroment, - VirtualMachineTemplate: template, - ScheduledEventLabel: se, + hflabels.EnvironmentLabel: enviroment, + hflabels.VirtualMachineTemplate: template, + hflabels.ScheduledEventLabel: se, } - vms, err := vmLister.List(vmLabels.AsSelector()) - return len(vms), err -} - -func MaxAvailableDuringPeriod(hfClientset hfClientset.Interface, environment string, startString string, endString string, ctx context.Context) (Maximus, error) { - _, maximumVirtualMachineCount, err := VirtualMachinesUsedDuringPeriod(hfClientset, environment, startString, endString, ctx) - - if err != nil { - return Maximus{}, err - } - - environmentFromK8s, err := hfClientset.HobbyfarmV1().Environments(GetReleaseNamespace()).Get(ctx, environment, metav1.GetOptions{}) - if err != nil { - return Maximus{}, fmt.Errorf("error retrieving environment %v", err) - } - - max := Maximus{} - max.AvailableCount = make(map[string]int) - for k, v := range environmentFromK8s.Spec.CountCapacity { - max.AvailableCount[k] = v - } - for vmt, count := range maximumVirtualMachineCount { - if vmtCap, ok := environmentFromK8s.Spec.CountCapacity[vmt]; ok { - max.AvailableCount[vmt] = vmtCap - count - } else { - glog.Errorf("Error looking for maximum count capacity of virtual machine template %s", vmt) - max.AvailableCount[vmt] = 0 - } - } - return max, nil + vmList, err := vmClient.ListVM(ctx, &generalpb.ListOptions{LabelSelector: vmLabels.AsSelector().String(), LoadFromCache: true}) + return len(vmList.GetVms()), err } func GetReleaseNamespace() string { @@ -488,15 +467,15 @@ func GetReleaseNamespace() string { return provisionNS } -func GetVMConfig(env *hfv1.Environment, vmt *hfv1.VirtualMachineTemplate) map[string]string { - envSpecificConfigFromEnv := env.Spec.EnvironmentSpecifics - envTemplateInfo, exists := env.Spec.TemplateMapping[vmt.Name] +func GetVMConfig(env *environmentpb.Environment, vmt *vmtemplatepb.VMTemplate) map[string]string { + envSpecificConfigFromEnv := env.EnvironmentSpecifics + envTemplateInfo, exists := env.TemplateMapping[vmt.GetId()] config := make(map[string]string) - config["image"] = vmt.Spec.Image + config["image"] = vmt.GetImage() // First copy VMT Details (default) - for k, v := range vmt.Spec.ConfigMap { + for k, v := range vmt.GetConfigMap() { config[k] = v } @@ -508,7 +487,7 @@ func GetVMConfig(env *hfv1.Environment, vmt *hfv1.VirtualMachineTemplate) map[st //This environment has specifics for this vmt if exists { // Override with specific from VM on this environment - for k, v := range envTemplateInfo { + for k, v := range envTemplateInfo.GetValue() { config[k] = v } } @@ -554,3 +533,46 @@ func GetDurationWithDays(s string) (string, error) { return s, nil } + +func AppendDynamicScenariosByCategories( + ctx context.Context, + scenariosList []string, + categories []string, + listScenariosFunc func(ctx context.Context, in *generalpb.ListOptions) (*scenariopb.ListScenariosResponse, error), +) []string { + for _, categoryQuery := range categories { + categorySelectors := []string{} + categoryQueryParts := strings.Split(categoryQuery, "&") + for _, categoryQueryPart := range categoryQueryParts { + operator := "in" + if strings.HasPrefix(categoryQueryPart, "!") { + operator = "notin" + categoryQueryPart = categoryQueryPart[1:] + } + categorySelectors = append(categorySelectors, fmt.Sprintf("category-%s %s (true)", categoryQueryPart, operator)) + } + categorySelectorString := strings.Join(categorySelectors, ",") + + selector, err := labels.Parse(categorySelectorString) + if err != nil { + glog.Errorf("error while parsing label selector %s: %v", categorySelectorString, err) + continue + } + + scenarios, err := listScenariosFunc(ctx, &generalpb.ListOptions{ + LabelSelector: selector.String(), + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error while retrieving scenarios: %s", hferrors.GetErrorMessage(err)) + continue + } + for _, scenario := range scenarios.GetScenarios() { + scenariosList = append(scenariosList, scenario.GetId()) + } + } + + scenariosList = UniqueStringSlice(scenariosList) + return scenariosList +} diff --git a/v3/pkg/util/verify.go b/v3/pkg/util/verify.go new file mode 100644 index 00000000..f1ebb292 --- /dev/null +++ b/v3/pkg/util/verify.go @@ -0,0 +1,84 @@ +package util + +import ( + "context" + "errors" + "time" + + "github.com/golang/glog" + "github.com/golang/protobuf/proto" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "google.golang.org/grpc/codes" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Verify[T metav1.Object, C GenericCacheRetriever[T]](getter C, object T, timeout time.Duration) error { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + done := make(chan bool, 1) + go func() { + for { + select { + case <-ctx.Done(): + return + default: + var fromCache T + fromCache, err := getter.Get(object.GetName()) + if err != nil { + if apierrors.IsNotFound(err) { + done <- true + return + } + glog.Error(err) + done <- false + return + } + if ResourceVersionAtLeast(fromCache.GetResourceVersion(), object.GetResourceVersion()) { + glog.V(5).Infof("Resource version matched for %s", object.GetName()) + done <- true + return + } + time.Sleep(100 * time.Millisecond) // Wait before retrying + } + } + }() + + select { + case <-ctx.Done(): + glog.Errorf("Timeout occurred while verifying resource version for %s", object.GetName()) + return ctx.Err() + case success := <-done: + if success { + return nil + } + return errors.New("an error occurred during verification") + } +} + +func VerifyTaskContent(vm_tasks []hfv1.VirtualMachineTasks, request proto.Message) error { + //Verify that name, description and command are not empty + for _, vm_task := range vm_tasks { + if vm_task.VMName == "" { + glog.Errorf("error vm_name (of vm_tasks) is not specified") + return hferrors.GrpcError(codes.InvalidArgument, "vm_name for vm_tasks property is not specified", request) + } + for _, task := range vm_task.Tasks { + if task.Name == "" { + glog.Errorf("error name of task in vm_tasks is not specified") + return hferrors.GrpcError(codes.InvalidArgument, "name of task in vm_tasks is not specified", request) + } + if task.Description == "" { + glog.Errorf("error description of task in vm_tasks is not specified") + return hferrors.GrpcError(codes.InvalidArgument, "description of task in vm_tasks is not specified", request) + } + if task.Command == "" || task.Command == "[]" { + glog.Errorf("error command of task in vm_tasks is not specified") + return hferrors.GrpcError(codes.InvalidArgument, "command of task in vm_tasks is not specified", request) + } + } + } + return nil +} diff --git a/v3/pkg/util/watch.go b/v3/pkg/util/watch.go new file mode 100644 index 00000000..ddbddec3 --- /dev/null +++ b/v3/pkg/util/watch.go @@ -0,0 +1,41 @@ +package util + +import ( + "context" + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" +) + +type HfClientWatch interface { + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) +} + +func VerifyDeletion(ctx context.Context, clientWatch HfClientWatch, resourceId string) error { + watcher, err := clientWatch.Watch(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", resourceId), + }) + if err != nil { + return fmt.Errorf("unable to verify deletion of object with id %s: %v", resourceId, err) + } + defer watcher.Stop() + for { + select { + case event, ok := <-watcher.ResultChan(): + if !ok { + return fmt.Errorf("watch channel closed unexpectedly") + } + switch event.Type { + case watch.Deleted: + // object deleted successfully + return nil + case watch.Error: + return fmt.Errorf("error watching object: %v", event.Object) + } + case <-ctx.Done(): + // returns context.DeadlineExceeded if the context times out and context.Canceled if the context was actively canceled + return ctx.Err() + } + } +} diff --git a/v3/pkg/util/workqueue.go b/v3/pkg/util/workqueue.go new file mode 100644 index 00000000..49ee3221 --- /dev/null +++ b/v3/pkg/util/workqueue.go @@ -0,0 +1,21 @@ +package util + +import ( + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "k8s.io/client-go/util/workqueue" +) + +func AddToWorkqueue(workqueue workqueue.Interface, req *generalpb.ResourceId) (*emptypb.Empty, error) { + if workqueue == nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error adding item to workqueue: workqueue is nil", + req, + ) + } + workqueue.Add(req.GetId()) + return &emptypb.Empty{}, nil +} diff --git a/v3/pkg/vmclaimserver/vmclaimserver.go b/v3/pkg/vmclaimserver/vmclaimserver.go deleted file mode 100644 index 4985a1d2..00000000 --- a/v3/pkg/vmclaimserver/vmclaimserver.go +++ /dev/null @@ -1,136 +0,0 @@ -package vmclaimserver - -import ( - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - "k8s.io/client-go/tools/cache" -) - -const ( - idIndex = "vmcs.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralVMClaim -) - -type VMClaimServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - - vmClaimIndexer cache.Indexer -} - -func NewVMClaimServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) (*VMClaimServer, error) { - vmcs := VMClaimServer{} - - vmcs.authnClient = authnClient - vmcs.authrClient = authrClient - vmcs.hfClientSet = hfClientset - - inf := hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer() - indexers := map[string]cache.IndexFunc{idIndex: vmcIdIndexer} - inf.AddIndexers(indexers) - vmcs.vmClaimIndexer = inf.GetIndexer() - - return &vmcs, nil -} - -func (vmcs VMClaimServer) GetVirtualMachineClaimById(id string) (hfv1.VirtualMachineClaim, error) { - - empty := hfv1.VirtualMachineClaim{} - - if len(id) == 0 { - return empty, fmt.Errorf("vm claim id passed in was empty") - } - - obj, err := vmcs.vmClaimIndexer.ByIndex(idIndex, id) - if err != nil { - return empty, fmt.Errorf("error while retrieving virtualmachineclaim by id: %s with error: %v", id, err) - } - - if len(obj) < 1 { - return empty, fmt.Errorf("virtualmachineclaim not found by id: %s", id) - } - - result, ok := obj[0].(*hfv1.VirtualMachineClaim) - - if !ok { - return empty, fmt.Errorf("error while converting virtualmachineclaim found by id to object: %s", id) - } - - return *result, nil - -} - -func (vmcs VMClaimServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/vmclaim/{vm_claim_id}", vmcs.GetVMClaimFunc).Methods("GET") - glog.V(2).Infof("set up routes") -} - -type PreparedVirtualMachineClaim struct { - ID string `json:"id"` - hfv1.VirtualMachineClaimSpec - hfv1.VirtualMachineClaimStatus -} - -func (vmcs VMClaimServer) GetVMClaimFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, vmcs.authnClient) - if err != nil { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vmc") - return - } - - vars := mux.Vars(r) - - vmId := vars["vm_claim_id"] - - if len(vmId) == 0 { - util.ReturnHTTPMessage(w, r, 500, "error", "no vmc id passed in") - return - } - - vmc, err := vmcs.GetVirtualMachineClaimById(vmId) - - if err != nil { - glog.Errorf("did not find the right virtual machine claim ID") - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "error", "no vm found") - return - } - - if vmc.Spec.UserId != user.GetId() { - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vmcs.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util.ReturnHTTPMessage(w, r, 403, "forbidden", "access denied to get vmclaim") - return - } - } - - preparedVMC := PreparedVirtualMachineClaim{vmc.Name, vmc.Spec, vmc.Status} - - encodedVMC, err := json.Marshal(preparedVMC) - if err != nil { - glog.Error(err) - } - util.ReturnHTTPContent(w, r, 200, "success", encodedVMC) - - glog.V(2).Infof("retrieved vmc %s", vmc.Name) -} - -func vmcIdIndexer(obj interface{}) ([]string, error) { - vmc, ok := obj.(*hfv1.VirtualMachineClaim) - if !ok { - return []string{}, nil - } - return []string{vmc.Name}, nil -} diff --git a/v3/pkg/vmclient/vmclient.go b/v3/pkg/vmclient/vmclient.go deleted file mode 100644 index 5347b367..00000000 --- a/v3/pkg/vmclient/vmclient.go +++ /dev/null @@ -1,30 +0,0 @@ -package vmclient - -import ( - "github.com/golang/glog" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - "github.com/hobbyfarm/gargantua/v3/pkg/vmserver" -) - -type VirtualMachineClient struct { - vmServer *vmserver.VMServer -} - -func NewVirtualMachineClient(vmServer *vmserver.VMServer) (*VirtualMachineClient, error) { - a := VirtualMachineClient{} - a.vmServer = vmServer - return &a, nil -} - -func (vm VirtualMachineClient) GetVirtualMachineById(id string) (hfv1.VirtualMachine, error) { - - vmResult, err := vm.vmServer.GetVirtualMachineById(id) - - if err != nil { - glog.Errorf("error while retrieving vm by id %s %v", id, err) - return vmResult, err - } - - return vmResult, nil - -} diff --git a/v3/pkg/vmserver/vmserver.go b/v3/pkg/vmserver/vmserver.go deleted file mode 100644 index 993e9d86..00000000 --- a/v3/pkg/vmserver/vmserver.go +++ /dev/null @@ -1,294 +0,0 @@ -package vmserver - -import ( - "context" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" -) - -const ( - idIndex = "vms.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralVM -) - -type VMServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context - vmIndexer cache.Indexer -} - -type PreparedVirtualMachine struct { - ID string `json:"id"` - hfv1.VirtualMachineSpec - hfv1.VirtualMachineStatus -} - -func NewVMServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*VMServer, error) { - vms := VMServer{} - - vms.authnClient = authnClient - vms.authrClient = authrClient - vms.hfClientSet = hfClientset - vms.ctx = ctx - - inf := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() - indexers := map[string]cache.IndexFunc{idIndex: vmIdIndexer} - inf.AddIndexers(indexers) - vms.vmIndexer = inf.GetIndexer() - - return &vms, nil -} - -func (vms VMServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/vm/{vm_id}", vms.GetVMFunc).Methods("GET") - r.HandleFunc("/vm/getwebinterfaces/{vm_id}", vms.getWebinterfaces).Methods("GET") - r.HandleFunc("/a/vm/list", vms.GetAllVMListFunc).Methods("GET") - r.HandleFunc("/a/vm/scheduledevent/{se_id}", vms.GetVMListByScheduledEventFunc).Methods("GET") - r.HandleFunc("/a/vm/count", vms.CountByScheduledEvent).Methods("GET") - glog.V(2).Infof("set up routes") -} - -/* -* Checks if VMTemplate used to create VM has "webinterfaces" in ConfigMap. -* Returns those webinterface definitions or http Error Codes. - */ -func (vms VMServer) getWebinterfaces(w http.ResponseWriter, r *http.Request) { - // Check if User has access to VMs - user, err := rbac2.AuthenticateRequest(r, vms.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") - return - } - vars := mux.Vars(r) - // Check if id for the VM was provided - vmId := vars["vm_id"] - if len(vmId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no vm id passed in") - return - } - // Get the VM, Error if none is found for the given id - vm, err := vms.GetVirtualMachineById(vmId) - if err != nil { - glog.Errorf("did not find the right virtual machine ID") - util2.ReturnHTTPMessage(w, r, 500, "error", "no vm found") - return - } - - // Check if the VM belongs to the User or User has RBAC-Rights to access VMs - if vm.Spec.UserId != user.GetId() { - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - glog.Errorf("user forbidden from accessing vm id %s", vm.Name) - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") - return - } - } - - // Get the corresponding VMTemplate for the VM and Check for "ide" - vmt, err := vms.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(vms.ctx, vm.Spec.VirtualMachineTemplateId, v1.GetOptions{}) - if err != nil { - util2.ReturnHTTPMessage(w, r, 404, "error", "no vm template found") - return - } - - services, found := vmt.Spec.ConfigMap["webinterfaces"] - if !found { - util2.ReturnHTTPMessage(w, r, 404, "error", "No Webinterfaces found for this VM") - return - } - - encodedWebinterfaceDefinitions, err := json.Marshal(services) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedWebinterfaceDefinitions) -} - -func (vms VMServer) GetVirtualMachineById(id string) (hfv1.VirtualMachine, error) { - - empty := hfv1.VirtualMachine{} - - if len(id) == 0 { - return empty, fmt.Errorf("vm id passed in was empty") - } - - obj, err := vms.vmIndexer.ByIndex(idIndex, id) - if err != nil { - return empty, fmt.Errorf("error while retrieving virtualmachine by id: %s with error: %v", id, err) - } - - if len(obj) < 1 { - return empty, fmt.Errorf("virtualmachine not found by id: %s", id) - } - - result, ok := obj[0].(*hfv1.VirtualMachine) - - if !ok { - return empty, fmt.Errorf("error while converting virtualmachine found by id to object: %s", id) - } - - return *result, nil - -} - -func (vms VMServer) GetVMFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, vms.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") - return - } - - vars := mux.Vars(r) - - vmId := vars["vm_id"] - - if len(vmId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no vm id passed in") - return - } - - vm, err := vms.GetVirtualMachineById(vmId) - - if err != nil { - glog.Errorf("did not find the right virtual machine ID") - util2.ReturnHTTPMessage(w, r, http.StatusNotFound, "error", "no vm found") - return - } - - if vm.Spec.UserId != user.GetId() { - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - glog.Errorf("user forbidden from accessing vm id %s", vm.Name) - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") - return - } - } - - preparedVM := PreparedVirtualMachine{vm.Name, vm.Spec, vm.Status} - - encodedVM, err := json.Marshal(preparedVM) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedVM) - - glog.V(2).Infof("retrieved vm %s", vm.Name) -} - -func (vms VMServer) GetVMListFunc(w http.ResponseWriter, r *http.Request, listOptions metav1.ListOptions) { - user, err := rbac2.AuthenticateRequest(r, vms.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list virtualmachines") - return - } - - vmList, err := vms.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).List(vms.ctx, listOptions) - - if err != nil { - glog.Errorf("error while retrieving vms %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error retreiving vms") - return - } - - preparedVMs := []PreparedVirtualMachine{} - for _, vm := range vmList.Items { - pVM := PreparedVirtualMachine{vm.Name, vm.Spec, vm.Status} - preparedVMs = append(preparedVMs, pVM) - } - - encodedVMs, err := json.Marshal(preparedVMs) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedVMs) -} - -func (vms VMServer) GetVMListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - id := vars["se_id"] - - if len(id) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no scheduledEvent id passed in") - return - } - - lo := metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, id)} - - vms.GetVMListFunc(w, r, lo) -} - -func (vms VMServer) CountByScheduledEvent(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, vms.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list virtualmachines") - return - } - - virtualmachines, err := vms.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).List(vms.ctx, metav1.ListOptions{}) - if err != nil { - glog.Errorf("error while retrieving virtualmachine %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no virtualmachine found") - return - } - - countMap := map[string]int{} - for _, vm := range virtualmachines.Items { - se := vm.Labels[util2.ScheduledEventLabel] - if _, ok := countMap[se]; ok { - countMap[se] = countMap[se] + 1 - } else { - countMap[se] = 1 - } - } - - encodedMap, err := json.Marshal(countMap) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedMap) -} - -func (vms VMServer) GetAllVMListFunc(w http.ResponseWriter, r *http.Request) { - vms.GetVMListFunc(w, r, metav1.ListOptions{}) -} - -func vmIdIndexer(obj interface{}) ([]string, error) { - vm, ok := obj.(*hfv1.VirtualMachine) - if !ok { - return []string{}, nil - } - return []string{vm.Name}, nil -} diff --git a/v3/pkg/vmsetserver/vmsetserver.go b/v3/pkg/vmsetserver/vmsetserver.go deleted file mode 100644 index d26d5f4c..00000000 --- a/v3/pkg/vmsetserver/vmsetserver.go +++ /dev/null @@ -1,123 +0,0 @@ -package vmsetserver - -import ( - "context" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - - "github.com/golang/glog" - "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" -) - -const ( - idIndex = "vms.hobbyfarm.io/id-index" - resourcePlural = rbac2.ResourcePluralVMSet -) - -type VMSetServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context - vmIndexer cache.Indexer -} - -type PreparedVirtualMachineSet struct { - Id string `json:"id"` - hfv1.VirtualMachineSetSpec - hfv1.VirtualMachineSetStatus -} - -func NewVMSetServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*VMSetServer, error) { - vms := VMSetServer{} - - vms.authnClient = authnClient - vms.authrClient = authrClient - vms.hfClientSet = hfClientset - vms.ctx = ctx - - inf := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() - indexers := map[string]cache.IndexFunc{idIndex: vmIdIndexer} - inf.AddIndexers(indexers) - vms.vmIndexer = inf.GetIndexer() - - return &vms, nil -} - -func (vms VMSetServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/a/vmset/{se_id}", vms.GetVMSetListByScheduledEventFunc).Methods("GET") - r.HandleFunc("/a/vmset", vms.GetAllVMSetListFunc).Methods("GET") - glog.V(2).Infof("set up routes") -} - -func (vms VMSetServer) GetVMSetListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - id := vars["se_id"] - - if len(id) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no scheduledEvent id passed in") - return - } - - lo := metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", util2.ScheduledEventLabel, id)} - - vms.GetVMSetListFunc(w, r, lo) -} - -func (vms VMSetServer) GetAllVMSetListFunc(w http.ResponseWriter, r *http.Request) { - vms.GetVMSetListFunc(w, r, metav1.ListOptions{}) -} - -func (vms VMSetServer) GetVMSetListFunc(w http.ResponseWriter, r *http.Request, listOptions metav1.ListOptions) { - user, err := rbac2.AuthenticateRequest(r, vms.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list vmsets") - return - } - - vmSetList, err := vms.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).List(vms.ctx, listOptions) - - if err != nil { - glog.Errorf("error while retrieving vmsets %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error retreiving vmsets") - return - } - - preparedVMSets := []PreparedVirtualMachineSet{} - for _, vmSet := range vmSetList.Items { - pVMSet := PreparedVirtualMachineSet{vmSet.Name, vmSet.Spec, vmSet.Status} - preparedVMSets = append(preparedVMSets, pVMSet) - } - - encodedVMSets, err := json.Marshal(preparedVMSets) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedVMSets) -} - -func vmIdIndexer(obj interface{}) ([]string, error) { - vm, ok := obj.(*hfv1.VirtualMachine) - if !ok { - return []string{}, nil - } - return []string{vm.Name}, nil -} diff --git a/v3/pkg/vmtemplateserver/vmtemplateserver.go b/v3/pkg/vmtemplateserver/vmtemplateserver.go deleted file mode 100644 index 15e5da28..00000000 --- a/v3/pkg/vmtemplateserver/vmtemplateserver.go +++ /dev/null @@ -1,436 +0,0 @@ -package vmtemplateserver - -import ( - "context" - "crypto/sha256" - "encoding/base32" - "encoding/json" - "fmt" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" - hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" - rbac2 "github.com/hobbyfarm/gargantua/v3/pkg/rbac" - util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" - "net/http" - "strings" - "time" - - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - - "github.com/golang/glog" - "github.com/gorilla/mux" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/util/retry" -) - -const ( - resourcePlural = rbac2.ResourcePluralVMTemplate -) - -type VirtualMachineTemplateServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - hfClientSet hfClientset.Interface - ctx context.Context -} - -func NewVirtualMachineTemplateServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, hfClientset hfClientset.Interface, ctx context.Context) (*VirtualMachineTemplateServer, error) { - as := VirtualMachineTemplateServer{} - - as.authnClient = authnClient - as.authrClient = authrClient - as.hfClientSet = hfClientset - as.ctx = ctx - return &as, nil -} - -func (v VirtualMachineTemplateServer) getVirtualMachineTemplate(id string) (hfv1.VirtualMachineTemplate, error) { - - empty := hfv1.VirtualMachineTemplate{} - - if len(id) == 0 { - return empty, fmt.Errorf("vm template id passed in was empty") - } - - obj, err := v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(v.ctx, id, metav1.GetOptions{}) - if err != nil { - return empty, fmt.Errorf("error while retrieving Virtual Machine Template by id: %s with error: %v", id, err) - } - - return *obj, nil - -} - -func (v VirtualMachineTemplateServer) SetupRoutes(r *mux.Router) { - r.HandleFunc("/a/vmtemplate/list", v.ListFunc).Methods("GET") - r.HandleFunc("/a/vmtemplate/{id}", v.GetFunc).Methods("GET") - r.HandleFunc("/a/vmtemplate/create", v.CreateFunc).Methods("POST") - r.HandleFunc("/a/vmtemplate/{id}/update", v.UpdateFunc).Methods("PUT") - r.HandleFunc("/a/vmtemplate/{id}/delete", v.DeleteFunc).Methods("DELETE") - glog.V(2).Infof("set up routes for admin vmtemplate server") -} - -type PreparedVMTemplate struct { - ID string `json:"id"` - hfv1.VirtualMachineTemplateSpec -} - -type PreparedVMTemplateList struct { - ID string `json:"id"` - Name string `json:"name"` - Image string `json:"image"` -} - -func (v VirtualMachineTemplateServer) GetFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, v.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbGet)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm template") - return - } - - vars := mux.Vars(r) - - vmtId := vars["id"] - - if len(vmtId) == 0 { - util2.ReturnHTTPMessage(w, r, 500, "error", "no vmt id passed in") - return - } - - vmt, err := v.getVirtualMachineTemplate(vmtId) - - if err != nil { - glog.Errorf("error while retrieving virtual machine template %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "no virtual machine template found") - return - } - - preparedEnvironment := PreparedVMTemplate{vmt.Name, vmt.Spec} - - encodedEnvironment, err := json.Marshal(preparedEnvironment) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedEnvironment) - - glog.V(2).Infof("retrieved vmt %s", vmt.Name) -} - -func (v VirtualMachineTemplateServer) ListFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, v.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbList)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list vmts") - return - } - - vmts, err := v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{}) - - if err != nil { - glog.Errorf("error while listing all vmts %v", err) - util2.ReturnHTTPMessage(w, r, 500, "error", "error listing all vmts") - return - } - - preparedVirtualMachineTemplates := []PreparedVMTemplateList{} - - for _, vmt := range vmts.Items { - preparedVirtualMachineTemplates = append(preparedVirtualMachineTemplates, PreparedVMTemplateList{vmt.Name, vmt.Spec.Name, vmt.Spec.Image}) - } - - encodedVirtualMachineTemplates, err := json.Marshal(preparedVirtualMachineTemplates) - if err != nil { - glog.Error(err) - } - util2.ReturnHTTPContent(w, r, 200, "success", encodedVirtualMachineTemplates) - - glog.V(2).Infof("retrieved list of all environments") -} - -func (v VirtualMachineTemplateServer) CreateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, v.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbCreate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create vmt") - return - } - - name := r.PostFormValue("name") - if name == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "missing name") - return - } - - image := r.PostFormValue("image") - if image == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "missing image") - return - } - - configMapRaw := r.PostFormValue("config_map") // no validation, config_map not required - - vmTemplate := &hfv1.VirtualMachineTemplate{Spec: hfv1.VirtualMachineTemplateSpec{}} - - configMap := map[string]string{} - if configMapRaw != "" { - // attempt to decode if config_map passed in - err := json.Unmarshal([]byte(configMapRaw), &configMap) - if err != nil { - glog.Errorf("error while unmarshalling config_map: %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing config_map") - return - } - // no error, assign to vmtemplate - vmTemplate.Spec.ConfigMap = configMap - } - - hasher := sha256.New() - hasher.Write([]byte(name)) - sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] - vmTemplate.Name = "vmt-" + strings.ToLower(sha) - vmTemplate.Spec.Name = name - vmTemplate.Spec.Image = image - - glog.V(2).Infof("user %s creating vmtemplate", user.GetId()) - - vmTemplate, err = v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Create(v.ctx, vmTemplate, metav1.CreateOptions{}) - if err != nil { - glog.Errorf("error creating vmtemplate %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating vmtemplate") - return - } - - util2.ReturnHTTPMessage(w, r, 201, "created", vmTemplate.Name) - return -} - -func (v VirtualMachineTemplateServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { - user, err := rbac2.AuthenticateRequest(r, v.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbUpdate)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update vmt") - return - } - - vars := mux.Vars(r) - - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") - return - } - - glog.V(2).Infof("user %s updating vmtemplate %s", user.GetId(), id) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - vmTemplate, err := v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(v.ctx, id, metav1.GetOptions{}) - if err != nil { - glog.Error(err) - util2.ReturnHTTPMessage(w, r, http.StatusNotFound, "badrequest", "vmtemplate not found with given ID") - return fmt.Errorf("bad") - } - - name := r.PostFormValue("name") - image := r.PostFormValue("image") - configMapRaw := r.PostFormValue("config_map") - - if name != "" { - vmTemplate.Spec.Name = name - } - - if image != "" { - vmTemplate.Spec.Image = image - } - - if configMapRaw != "" { - configMap := map[string]string{} - err := json.Unmarshal([]byte(configMapRaw), &configMap) - if err != nil { - glog.Error(err) - return fmt.Errorf("bad") - } - vmTemplate.Spec.ConfigMap = configMap - } - - _, updateErr := v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Update(v.ctx, vmTemplate, metav1.UpdateOptions{}) - return updateErr - }) - - if retryErr != nil { - util2.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update vmtemplate") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "updated", "") - return -} - -func (v VirtualMachineTemplateServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { - // deleting a vmtemplate requires none of the following objects having reference to it - // - future scheduled events - // - virtualmachines - // - virtualmachineclaims - // - virtualmachinesets - user, err := rbac2.AuthenticateRequest(r, v.authnClient) - if err != nil { - util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") - return - } - - impersonatedUserId := user.GetId() - authrResponse, err := rbac2.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac2.HobbyfarmPermission(resourcePlural, rbac2.VerbDelete)) - if err != nil || !authrResponse.Success { - util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete vmt") - return - } - - // first, check if the vmt exists - vars := mux.Vars(r) - id := vars["id"] - if id == "" { - util2.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") - return - } - - glog.V(2).Infof("user %s deleting vmtemplate %s", user.GetId(), id) - - vmt, err := v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Get(v.ctx, id, metav1.GetOptions{}) - if err != nil { - util2.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", "no vmt found with given ID") - return - } - - // vmt exists, now we need to check all other objects for references - // start with virtualmachines - virtualmachines, err := v.hfClientSet.HobbyfarmV1().VirtualMachines(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", util2.VirtualMachineTemplate, vmt.Name)}) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error listing virtual machines while attempting vmt deletion") - return - } - - if len(virtualmachines.Items) > 0 { - util2.ReturnHTTPMessage(w, r, 409, "conflict", "existing virtual machines reference this vmtemplate") - return - } - - // now check scheduledevents - scheduledEvents, err := v.hfClientSet.HobbyfarmV1().ScheduledEvents(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{}) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error listing scheduled events while attempting vmt deletion") - return - } - - if len(scheduledEvents.Items) > 0 { - for _, v := range scheduledEvents.Items { - if v.Status.Finished != true { - // unfinished SE. Is it going on now or in the future? - startTime, err := time.Parse(time.UnixDate, v.Spec.StartTime) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error parsing time while checking scheduledevent for conflict") - return - } - endTime, err := time.Parse(time.UnixDate, v.Spec.EndTime) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error parsing time while checking scheduledevent for conflict") - return - } - - // if this starts in the future, or hasn't ended - if startTime.After(time.Now()) || endTime.After(time.Now()) { - // check for template existence - if exists := searchForTemplateInRequiredVMs(v.Spec.RequiredVirtualMachines, vmt.Name); exists { - // if template exists in this to-be-happening SE, we can't delete it - util2.ReturnHTTPMessage(w, r, 409, "conflict", - "existing or future scheduled event references this vmtemplate") - } - } - } - } - } - - // now check virtul machine claims - vmcList, err := v.hfClientSet.HobbyfarmV1().VirtualMachineClaims(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s=%s", vmt.Name, "true"), - }) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error listing virtual machine claims while attempting vmt deletion") - return - } - - if len(vmcList.Items) > 0 { - util2.ReturnHTTPMessage(w, r, 409, "conflict", - "existing virtual machine claims reference this vmtemplate") - return - } - - // now check virtualmachinesets (theoretically the VM checks above should catch this, but let's be safe) - vmsetList, err := v.hfClientSet.HobbyfarmV1().VirtualMachineSets(util2.GetReleaseNamespace()).List(v.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s=%s", vmt.Name, "true"), - }) - if err != nil { - util2.ReturnHTTPMessage(w, r, 500, "internalerror", - "error listing virtual machine sets while attempting vmt deletion") - return - } - - if len(vmsetList.Items) > 0 { - util2.ReturnHTTPMessage(w, r, 409, "conflict", - "existing virtual machine sets reference this vmtemplate") - return - } - - // if we get here, shouldn't be anything in our path stopping us from deleting the vmtemplate - // so do it! - err = v.hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util2.GetReleaseNamespace()).Delete(v.ctx, vmt.Name, metav1.DeleteOptions{}) - if err != nil { - glog.Errorf("error deleting vmtemplate: %v", err) - util2.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting vmtemplate") - return - } - - util2.ReturnHTTPMessage(w, r, 200, "deleted", "vmtemplate deleted") -} - -func searchForTemplateInRequiredVMs(req map[string]map[string]int, template string) bool { - for _, v := range req { - // k is environment, v is map[string]string - for kk, _ := range v { - // kk is vmtemplate, vv is count - if kk == template { - return true - } - } - } - - return false -} diff --git a/v3/protos/accesscode/accesscode.pb.go b/v3/protos/accesscode/accesscode.pb.go index 98a4135b..cb077a79 100644 --- a/v3/protos/accesscode/accesscode.pb.go +++ b/v3/protos/accesscode/accesscode.pb.go @@ -1,15 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: accesscode/accesscode.proto -package accesscode +package accesscodepb import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" reflect "reflect" sync "sync" ) @@ -21,16 +23,16 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type ResourceId struct { +type ResourceIds struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"` } -func (x *ResourceId) Reset() { - *x = ResourceId{} +func (x *ResourceIds) Reset() { + *x = ResourceIds{} if protoimpl.UnsafeEnabled { mi := &file_accesscode_accesscode_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -38,13 +40,13 @@ func (x *ResourceId) Reset() { } } -func (x *ResourceId) String() string { +func (x *ResourceIds) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResourceId) ProtoMessage() {} +func (*ResourceIds) ProtoMessage() {} -func (x *ResourceId) ProtoReflect() protoreflect.Message { +func (x *ResourceIds) ProtoReflect() protoreflect.Message { mi := &file_accesscode_accesscode_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -56,16 +58,16 @@ func (x *ResourceId) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ResourceId.ProtoReflect.Descriptor instead. -func (*ResourceId) Descriptor() ([]byte, []int) { +// Deprecated: Use ResourceIds.ProtoReflect.Descriptor instead. +func (*ResourceIds) Descriptor() ([]byte, []int) { return file_accesscode_accesscode_proto_rawDescGZIP(), []int{0} } -func (x *ResourceId) GetId() string { +func (x *ResourceIds) GetIds() []string { if x != nil { - return x.Id + return x.Ids } - return "" + return nil } type ResourceValidation struct { @@ -120,10 +122,12 @@ type OneTimeAccessCode struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` - RedeemedTimestamp string `protobuf:"bytes,3,opt,name=redeemed_timestamp,json=redeemedTimestamp,proto3" json:"redeemed_timestamp,omitempty"` - MaxDuration string `protobuf:"bytes,4,opt,name=max_duration,json=maxDuration,proto3" json:"max_duration,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + User string `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"` + RedeemedTimestamp string `protobuf:"bytes,4,opt,name=redeemed_timestamp,json=redeemedTimestamp,proto3" json:"redeemed_timestamp,omitempty"` + MaxDuration string `protobuf:"bytes,5,opt,name=max_duration,json=maxDuration,proto3" json:"max_duration,omitempty"` + Labels map[string]string `protobuf:"bytes,6,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *OneTimeAccessCode) Reset() { @@ -165,6 +169,13 @@ func (x *OneTimeAccessCode) GetId() string { return "" } +func (x *OneTimeAccessCode) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *OneTimeAccessCode) GetUser() string { if x != nil { return x.User @@ -186,46 +197,754 @@ func (x *OneTimeAccessCode) GetMaxDuration() string { return "" } +func (x *OneTimeAccessCode) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type ListOtacsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Otacs []*OneTimeAccessCode `protobuf:"bytes,1,rep,name=otacs,proto3" json:"otacs,omitempty"` +} + +func (x *ListOtacsResponse) Reset() { + *x = ListOtacsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOtacsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOtacsResponse) ProtoMessage() {} + +func (x *ListOtacsResponse) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListOtacsResponse.ProtoReflect.Descriptor instead. +func (*ListOtacsResponse) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{3} +} + +func (x *ListOtacsResponse) GetOtacs() []*OneTimeAccessCode { + if x != nil { + return x.Otacs + } + return nil +} + +type CreateOtacRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SeName string `protobuf:"bytes,1,opt,name=se_name,json=seName,proto3" json:"se_name,omitempty"` + SeUid string `protobuf:"bytes,2,opt,name=se_uid,json=seUid,proto3" json:"se_uid,omitempty"` + MaxDuration string `protobuf:"bytes,3,opt,name=max_duration,json=maxDuration,proto3" json:"max_duration,omitempty"` +} + +func (x *CreateOtacRequest) Reset() { + *x = CreateOtacRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateOtacRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateOtacRequest) ProtoMessage() {} + +func (x *CreateOtacRequest) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateOtacRequest.ProtoReflect.Descriptor instead. +func (*CreateOtacRequest) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateOtacRequest) GetSeName() string { + if x != nil { + return x.SeName + } + return "" +} + +func (x *CreateOtacRequest) GetSeUid() string { + if x != nil { + return x.SeUid + } + return "" +} + +func (x *CreateOtacRequest) GetMaxDuration() string { + if x != nil { + return x.MaxDuration + } + return "" +} + +type CreateAcRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AcName string `protobuf:"bytes,1,opt,name=ac_name,json=acName,proto3" json:"ac_name,omitempty"` + SeName string `protobuf:"bytes,2,opt,name=se_name,json=seName,proto3" json:"se_name,omitempty"` + SeUid string `protobuf:"bytes,3,opt,name=se_uid,json=seUid,proto3" json:"se_uid,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Scenarios []string `protobuf:"bytes,5,rep,name=scenarios,proto3" json:"scenarios,omitempty"` + Courses []string `protobuf:"bytes,6,rep,name=courses,proto3" json:"courses,omitempty"` + Expiration string `protobuf:"bytes,7,opt,name=expiration,proto3" json:"expiration,omitempty"` + RestrictedBind bool `protobuf:"varint,8,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,9,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + Printable bool `protobuf:"varint,10,opt,name=printable,proto3" json:"printable,omitempty"` +} + +func (x *CreateAcRequest) Reset() { + *x = CreateAcRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateAcRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAcRequest) ProtoMessage() {} + +func (x *CreateAcRequest) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateAcRequest.ProtoReflect.Descriptor instead. +func (*CreateAcRequest) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateAcRequest) GetAcName() string { + if x != nil { + return x.AcName + } + return "" +} + +func (x *CreateAcRequest) GetSeName() string { + if x != nil { + return x.SeName + } + return "" +} + +func (x *CreateAcRequest) GetSeUid() string { + if x != nil { + return x.SeUid + } + return "" +} + +func (x *CreateAcRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateAcRequest) GetScenarios() []string { + if x != nil { + return x.Scenarios + } + return nil +} + +func (x *CreateAcRequest) GetCourses() []string { + if x != nil { + return x.Courses + } + return nil +} + +func (x *CreateAcRequest) GetExpiration() string { + if x != nil { + return x.Expiration + } + return "" +} + +func (x *CreateAcRequest) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *CreateAcRequest) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *CreateAcRequest) GetPrintable() bool { + if x != nil { + return x.Printable + } + return false +} + +type AccessCode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Scenarios []string `protobuf:"bytes,4,rep,name=scenarios,proto3" json:"scenarios,omitempty"` + Courses []string `protobuf:"bytes,5,rep,name=courses,proto3" json:"courses,omitempty"` + Expiration string `protobuf:"bytes,6,opt,name=expiration,proto3" json:"expiration,omitempty"` + RestrictedBind bool `protobuf:"varint,7,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,8,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + Printable bool `protobuf:"varint,9,opt,name=printable,proto3" json:"printable,omitempty"` + Labels map[string]string `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *AccessCode) Reset() { + *x = AccessCode{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessCode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessCode) ProtoMessage() {} + +func (x *AccessCode) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessCode.ProtoReflect.Descriptor instead. +func (*AccessCode) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{6} +} + +func (x *AccessCode) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *AccessCode) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *AccessCode) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *AccessCode) GetScenarios() []string { + if x != nil { + return x.Scenarios + } + return nil +} + +func (x *AccessCode) GetCourses() []string { + if x != nil { + return x.Courses + } + return nil +} + +func (x *AccessCode) GetExpiration() string { + if x != nil { + return x.Expiration + } + return "" +} + +func (x *AccessCode) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *AccessCode) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *AccessCode) GetPrintable() bool { + if x != nil { + return x.Printable + } + return false +} + +func (x *AccessCode) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +// To determine if a boolean value was provided or not for the restricted_bind and printable field, we need to use a wrapper type. +// Otherwise we can not tell if the value was provided or the default value (false) was set +type UpdateAccessCodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Scenarios []string `protobuf:"bytes,3,rep,name=scenarios,proto3" json:"scenarios,omitempty"` + Courses []string `protobuf:"bytes,4,rep,name=courses,proto3" json:"courses,omitempty"` + Expiration string `protobuf:"bytes,5,opt,name=expiration,proto3" json:"expiration,omitempty"` + RestrictedBind *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + Printable *wrapperspb.BoolValue `protobuf:"bytes,7,opt,name=printable,proto3" json:"printable,omitempty"` +} + +func (x *UpdateAccessCodeRequest) Reset() { + *x = UpdateAccessCodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateAccessCodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAccessCodeRequest) ProtoMessage() {} + +func (x *UpdateAccessCodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAccessCodeRequest.ProtoReflect.Descriptor instead. +func (*UpdateAccessCodeRequest) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateAccessCodeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateAccessCodeRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *UpdateAccessCodeRequest) GetScenarios() []string { + if x != nil { + return x.Scenarios + } + return nil +} + +func (x *UpdateAccessCodeRequest) GetCourses() []string { + if x != nil { + return x.Courses + } + return nil +} + +func (x *UpdateAccessCodeRequest) GetExpiration() string { + if x != nil { + return x.Expiration + } + return "" +} + +func (x *UpdateAccessCodeRequest) GetRestrictedBind() *wrapperspb.BoolValue { + if x != nil { + return x.RestrictedBind + } + return nil +} + +func (x *UpdateAccessCodeRequest) GetPrintable() *wrapperspb.BoolValue { + if x != nil { + return x.Printable + } + return nil +} + +type ListAcsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessCodes []*AccessCode `protobuf:"bytes,1,rep,name=access_codes,json=accessCodes,proto3" json:"access_codes,omitempty"` +} + +func (x *ListAcsResponse) Reset() { + *x = ListAcsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAcsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAcsResponse) ProtoMessage() {} + +func (x *ListAcsResponse) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAcsResponse.ProtoReflect.Descriptor instead. +func (*ListAcsResponse) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{8} +} + +func (x *ListAcsResponse) GetAccessCodes() []*AccessCode { + if x != nil { + return x.AccessCodes + } + return nil +} + +type ClosestAcRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + CourseOrScenarioId string `protobuf:"bytes,2,opt,name=course_or_scenario_id,json=courseOrScenarioId,proto3" json:"course_or_scenario_id,omitempty"` +} + +func (x *ClosestAcRequest) Reset() { + *x = ClosestAcRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_accesscode_accesscode_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClosestAcRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClosestAcRequest) ProtoMessage() {} + +func (x *ClosestAcRequest) ProtoReflect() protoreflect.Message { + mi := &file_accesscode_accesscode_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClosestAcRequest.ProtoReflect.Descriptor instead. +func (*ClosestAcRequest) Descriptor() ([]byte, []int) { + return file_accesscode_accesscode_proto_rawDescGZIP(), []int{9} +} + +func (x *ClosestAcRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *ClosestAcRequest) GetCourseOrScenarioId() string { + if x != nil { + return x.CourseOrScenarioId + } + return "" +} + var File_accesscode_accesscode_proto protoreflect.FileDescriptor var file_accesscode_accesscode_proto_rawDesc = []byte{ 0x0a, 0x1b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x22, 0x89, 0x01, 0x0a, 0x11, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x72, - 0x65, 0x64, 0x65, 0x65, 0x6d, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x65, - 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, - 0x78, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xe8, 0x01, - 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x76, 0x63, 0x12, - 0x42, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4f, 0x74, 0x61, 0x63, 0x12, 0x17, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x1a, 0x1e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, - 0x6f, 0x64, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x74, 0x61, - 0x63, 0x12, 0x1e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2e, + 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, + 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x10, 0x0a, 0x03, + 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x2a, + 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x22, 0x99, 0x02, 0x0a, 0x11, 0x4f, + 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, + 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x78, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x48, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x74, + 0x61, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x6f, + 0x74, 0x61, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6f, 0x74, 0x61, 0x63, 0x73, + 0x22, 0x66, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x74, 0x61, 0x63, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x15, + 0x0a, 0x06, 0x73, 0x65, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x65, 0x55, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x78, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xcf, 0x02, 0x0a, 0x0f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, + 0x61, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x15, + 0x0a, 0x06, 0x73, 0x65, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x65, 0x55, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, + 0x61, 0x72, 0x69, 0x6f, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, + 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x9a, 0x03, 0x0a, 0x0a, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, + 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, + 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, + 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa2, 0x02, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, + 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, + 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x4c, 0x0a, 0x0f, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x39, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, + 0x64, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x10, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x73, 0x74, 0x41, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, + 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x63, 0x6f, 0x75, 0x72, 0x73, + 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x4f, 0x72, + 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x49, 0x64, 0x32, 0xc4, 0x08, 0x0a, 0x0d, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x76, 0x63, 0x12, 0x3f, 0x0a, 0x08, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x12, 0x1b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, + 0x05, 0x47, 0x65, 0x74, 0x41, 0x63, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x12, + 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x08, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x12, 0x14, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x06, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x63, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1b, 0x2e, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4f, 0x74, 0x61, 0x63, 0x12, 0x1d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, + 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x74, 0x61, 0x63, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, + 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x3d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4f, 0x74, 0x61, 0x63, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, - 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x11, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x17, - 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x1f, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, - 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x74, 0x61, 0x63, 0x12, + 0x1d, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4f, 0x6e, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4f, 0x74, 0x61, 0x63, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x44, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x74, 0x61, 0x63, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x74, 0x61, 0x63, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1d, 0x2e, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x74, 0x61, 0x63, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x11, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x64, 0x1a, 0x1e, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x4f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, + 0x6f, 0x64, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x54, 0x41, 0x43, 0x73, 0x12, 0x17, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x1a, 0x1b, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, + 0x6f, 0x64, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x43, 0x6f, 0x64, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x54, 0x41, 0x43, 0x73, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x45, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, + 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x63, + 0x6f, 0x64, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -240,25 +959,71 @@ func file_accesscode_accesscode_proto_rawDescGZIP() []byte { return file_accesscode_accesscode_proto_rawDescData } -var file_accesscode_accesscode_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_accesscode_accesscode_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_accesscode_accesscode_proto_goTypes = []interface{}{ - (*ResourceId)(nil), // 0: access_code.ResourceId - (*ResourceValidation)(nil), // 1: access_code.ResourceValidation - (*OneTimeAccessCode)(nil), // 2: access_code.OneTimeAccessCode - (*emptypb.Empty)(nil), // 3: google.protobuf.Empty + (*ResourceIds)(nil), // 0: accesscode.ResourceIds + (*ResourceValidation)(nil), // 1: accesscode.ResourceValidation + (*OneTimeAccessCode)(nil), // 2: accesscode.OneTimeAccessCode + (*ListOtacsResponse)(nil), // 3: accesscode.ListOtacsResponse + (*CreateOtacRequest)(nil), // 4: accesscode.CreateOtacRequest + (*CreateAcRequest)(nil), // 5: accesscode.CreateAcRequest + (*AccessCode)(nil), // 6: accesscode.AccessCode + (*UpdateAccessCodeRequest)(nil), // 7: accesscode.UpdateAccessCodeRequest + (*ListAcsResponse)(nil), // 8: accesscode.ListAcsResponse + (*ClosestAcRequest)(nil), // 9: accesscode.ClosestAcRequest + nil, // 10: accesscode.OneTimeAccessCode.LabelsEntry + nil, // 11: accesscode.AccessCode.LabelsEntry + (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 13: general.GetRequest + (*general.ResourceId)(nil), // 14: general.ResourceId + (*general.ListOptions)(nil), // 15: general.ListOptions + (*emptypb.Empty)(nil), // 16: google.protobuf.Empty + (*general.OwnerReferences)(nil), // 17: general.OwnerReferences } var file_accesscode_accesscode_proto_depIdxs = []int32{ - 0, // 0: access_code.AccessCodeSvc.GetOtac:input_type -> access_code.ResourceId - 2, // 1: access_code.AccessCodeSvc.UpdateOtac:input_type -> access_code.OneTimeAccessCode - 0, // 2: access_code.AccessCodeSvc.ValidateExistence:input_type -> access_code.ResourceId - 2, // 3: access_code.AccessCodeSvc.GetOtac:output_type -> access_code.OneTimeAccessCode - 3, // 4: access_code.AccessCodeSvc.UpdateOtac:output_type -> google.protobuf.Empty - 1, // 5: access_code.AccessCodeSvc.ValidateExistence:output_type -> access_code.ResourceValidation - 3, // [3:6] is the sub-list for method output_type - 0, // [0:3] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 10, // 0: accesscode.OneTimeAccessCode.labels:type_name -> accesscode.OneTimeAccessCode.LabelsEntry + 2, // 1: accesscode.ListOtacsResponse.otacs:type_name -> accesscode.OneTimeAccessCode + 11, // 2: accesscode.AccessCode.labels:type_name -> accesscode.AccessCode.LabelsEntry + 12, // 3: accesscode.UpdateAccessCodeRequest.restricted_bind:type_name -> google.protobuf.BoolValue + 12, // 4: accesscode.UpdateAccessCodeRequest.printable:type_name -> google.protobuf.BoolValue + 6, // 5: accesscode.ListAcsResponse.access_codes:type_name -> accesscode.AccessCode + 5, // 6: accesscode.AccessCodeSvc.CreateAc:input_type -> accesscode.CreateAcRequest + 13, // 7: accesscode.AccessCodeSvc.GetAc:input_type -> general.GetRequest + 7, // 8: accesscode.AccessCodeSvc.UpdateAc:input_type -> accesscode.UpdateAccessCodeRequest + 14, // 9: accesscode.AccessCodeSvc.DeleteAc:input_type -> general.ResourceId + 15, // 10: accesscode.AccessCodeSvc.DeleteCollectionAc:input_type -> general.ListOptions + 15, // 11: accesscode.AccessCodeSvc.ListAc:input_type -> general.ListOptions + 4, // 12: accesscode.AccessCodeSvc.CreateOtac:input_type -> accesscode.CreateOtacRequest + 13, // 13: accesscode.AccessCodeSvc.GetOtac:input_type -> general.GetRequest + 2, // 14: accesscode.AccessCodeSvc.UpdateOtac:input_type -> accesscode.OneTimeAccessCode + 14, // 15: accesscode.AccessCodeSvc.DeleteOtac:input_type -> general.ResourceId + 15, // 16: accesscode.AccessCodeSvc.DeleteCollectionOtac:input_type -> general.ListOptions + 15, // 17: accesscode.AccessCodeSvc.ListOtac:input_type -> general.ListOptions + 14, // 18: accesscode.AccessCodeSvc.ValidateExistence:input_type -> general.ResourceId + 0, // 19: accesscode.AccessCodeSvc.GetAccessCodesWithOTACs:input_type -> accesscode.ResourceIds + 14, // 20: accesscode.AccessCodeSvc.GetAccessCodeWithOTACs:input_type -> general.ResourceId + 13, // 21: accesscode.AccessCodeSvc.GetAcOwnerReferences:input_type -> general.GetRequest + 16, // 22: accesscode.AccessCodeSvc.CreateAc:output_type -> google.protobuf.Empty + 6, // 23: accesscode.AccessCodeSvc.GetAc:output_type -> accesscode.AccessCode + 16, // 24: accesscode.AccessCodeSvc.UpdateAc:output_type -> google.protobuf.Empty + 16, // 25: accesscode.AccessCodeSvc.DeleteAc:output_type -> google.protobuf.Empty + 16, // 26: accesscode.AccessCodeSvc.DeleteCollectionAc:output_type -> google.protobuf.Empty + 8, // 27: accesscode.AccessCodeSvc.ListAc:output_type -> accesscode.ListAcsResponse + 2, // 28: accesscode.AccessCodeSvc.CreateOtac:output_type -> accesscode.OneTimeAccessCode + 2, // 29: accesscode.AccessCodeSvc.GetOtac:output_type -> accesscode.OneTimeAccessCode + 16, // 30: accesscode.AccessCodeSvc.UpdateOtac:output_type -> google.protobuf.Empty + 16, // 31: accesscode.AccessCodeSvc.DeleteOtac:output_type -> google.protobuf.Empty + 16, // 32: accesscode.AccessCodeSvc.DeleteCollectionOtac:output_type -> google.protobuf.Empty + 3, // 33: accesscode.AccessCodeSvc.ListOtac:output_type -> accesscode.ListOtacsResponse + 1, // 34: accesscode.AccessCodeSvc.ValidateExistence:output_type -> accesscode.ResourceValidation + 8, // 35: accesscode.AccessCodeSvc.GetAccessCodesWithOTACs:output_type -> accesscode.ListAcsResponse + 6, // 36: accesscode.AccessCodeSvc.GetAccessCodeWithOTACs:output_type -> accesscode.AccessCode + 17, // 37: accesscode.AccessCodeSvc.GetAcOwnerReferences:output_type -> general.OwnerReferences + 22, // [22:38] is the sub-list for method output_type + 6, // [6:22] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_accesscode_accesscode_proto_init() } @@ -268,7 +1033,7 @@ func file_accesscode_accesscode_proto_init() { } if !protoimpl.UnsafeEnabled { file_accesscode_accesscode_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceId); i { + switch v := v.(*ResourceIds); i { case 0: return &v.state case 1: @@ -303,6 +1068,90 @@ func file_accesscode_accesscode_proto_init() { return nil } } + file_accesscode_accesscode_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOtacsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateOtacRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateAcRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessCode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateAccessCodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAcsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_accesscode_accesscode_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClosestAcRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -310,7 +1159,7 @@ func file_accesscode_accesscode_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accesscode_accesscode_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/v3/protos/accesscode/accesscode.proto b/v3/protos/accesscode/accesscode.proto index dff06000..7eef3274 100644 --- a/v3/protos/accesscode/accesscode.proto +++ b/v3/protos/accesscode/accesscode.proto @@ -1,36 +1,40 @@ syntax = "proto3"; -package access_code; +package accesscode; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/accesscode"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/accesscode;accesscodepb"; +import "general/general.proto"; import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; // Service definition service AccessCodeSvc { - // TODO: Implementation for AccessCodes + // Resource oriented RPCs for AccessCodes: + rpc CreateAc (CreateAcRequest) returns (google.protobuf.Empty); + rpc GetAc (general.GetRequest) returns (AccessCode); + rpc UpdateAc (UpdateAccessCodeRequest) returns (google.protobuf.Empty); + rpc DeleteAc (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionAc (general.ListOptions) returns (google.protobuf.Empty); + rpc ListAc (general.ListOptions) returns (ListAcsResponse); - // rpc CreateAc (CreateAcRequest) returns (AccessCodeId); - // rpc GetAc (AccessCodeId) returns (AccessCode); - // rpc UpdateAc (AccessCode) returns (google.protobuf.Empty); - // rpc DeleteAc (AccessCodeId) returns (google.protobuf.Empty); - // rpc DeleteCollectionAc (ListOptions) returns (google.protobuf.Empty); - // rpc ListAc (ListOptions) returns (AccessCodes); - - // TODO: Implement missing OTAC RPCs - - // rpc CreateOtac (CreateOtacRequest) returns (OneTimeAccessCodeId); - rpc GetOtac (ResourceId) returns (OneTimeAccessCode); + // Resource oriented RPCs for OneTimeAccessCodes: + rpc CreateOtac (CreateOtacRequest) returns (OneTimeAccessCode); + rpc GetOtac (general.GetRequest) returns (OneTimeAccessCode); rpc UpdateOtac (OneTimeAccessCode) returns (google.protobuf.Empty); - // rpc DeleteOtac (OneTimeAccessCodeId) returns (google.protobuf.Empty); - // rpc DeleteCollectionOtac (ListOptions) returns (google.protobuf.Empty); - // rpc ListOtac (ListOptions) returns (OneTimeAccessCodes); + rpc DeleteOtac (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionOtac (general.ListOptions) returns (google.protobuf.Empty); + rpc ListOtac (general.ListOptions) returns (ListOtacsResponse); - rpc ValidateExistence (ResourceId) returns (ResourceValidation); + // Helper functions + rpc ValidateExistence (general.ResourceId) returns (ResourceValidation); + rpc GetAccessCodesWithOTACs (ResourceIds) returns (ListAcsResponse); + rpc GetAccessCodeWithOTACs (general.ResourceId) returns (AccessCode); + rpc GetAcOwnerReferences (general.GetRequest) returns (general.OwnerReferences); } -message ResourceId { - string id = 1; +message ResourceIds { + repeated string ids = 1; } message ResourceValidation { @@ -39,7 +43,66 @@ message ResourceValidation { message OneTimeAccessCode { string id = 1; - string user = 2; - string redeemed_timestamp = 3; - string max_duration = 4; + string uid = 2; + string user = 3; + string redeemed_timestamp = 4; + string max_duration = 5; + map labels = 6; +} + +message ListOtacsResponse { + repeated OneTimeAccessCode otacs = 1; +} + +message CreateOtacRequest { + string se_name = 1; + string se_uid = 2; + string max_duration = 3; +} + +message CreateAcRequest { + string ac_name = 1; + string se_name = 2; + string se_uid = 3; + string description = 4; + repeated string scenarios = 5; + repeated string courses = 6; + string expiration = 7; + bool restricted_bind = 8; + string restricted_bind_value = 9; + bool printable = 10; +} + +message AccessCode { + string id = 1; + string uid = 2; + string description = 3; + repeated string scenarios = 4; + repeated string courses = 5; + string expiration = 6; + bool restricted_bind = 7; + string restricted_bind_value = 8; + bool printable = 9; + map labels = 10; +} + +// To determine if a boolean value was provided or not for the restricted_bind and printable field, we need to use a wrapper type. +// Otherwise we can not tell if the value was provided or the default value (false) was set +message UpdateAccessCodeRequest { + string id = 1; + string description = 2; + repeated string scenarios = 3; + repeated string courses = 4; + string expiration = 5; + google.protobuf.BoolValue restricted_bind = 6; + google.protobuf.BoolValue printable = 7; +} + +message ListAcsResponse { + repeated AccessCode access_codes = 1; +} + +message ClosestAcRequest { + string user_id = 1; + string course_or_scenario_id = 2; } \ No newline at end of file diff --git a/v3/protos/accesscode/accesscode_grpc.pb.go b/v3/protos/accesscode/accesscode_grpc.pb.go index 031dfd40..cb735a54 100644 --- a/v3/protos/accesscode/accesscode_grpc.pb.go +++ b/v3/protos/accesscode/accesscode_grpc.pb.go @@ -4,10 +4,11 @@ // - protoc v3.21.12 // source: accesscode/accesscode.proto -package accesscode +package accesscodepb import ( context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -20,19 +21,47 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - AccessCodeSvc_GetOtac_FullMethodName = "/access_code.AccessCodeSvc/GetOtac" - AccessCodeSvc_UpdateOtac_FullMethodName = "/access_code.AccessCodeSvc/UpdateOtac" - AccessCodeSvc_ValidateExistence_FullMethodName = "/access_code.AccessCodeSvc/ValidateExistence" + AccessCodeSvc_CreateAc_FullMethodName = "/accesscode.AccessCodeSvc/CreateAc" + AccessCodeSvc_GetAc_FullMethodName = "/accesscode.AccessCodeSvc/GetAc" + AccessCodeSvc_UpdateAc_FullMethodName = "/accesscode.AccessCodeSvc/UpdateAc" + AccessCodeSvc_DeleteAc_FullMethodName = "/accesscode.AccessCodeSvc/DeleteAc" + AccessCodeSvc_DeleteCollectionAc_FullMethodName = "/accesscode.AccessCodeSvc/DeleteCollectionAc" + AccessCodeSvc_ListAc_FullMethodName = "/accesscode.AccessCodeSvc/ListAc" + AccessCodeSvc_CreateOtac_FullMethodName = "/accesscode.AccessCodeSvc/CreateOtac" + AccessCodeSvc_GetOtac_FullMethodName = "/accesscode.AccessCodeSvc/GetOtac" + AccessCodeSvc_UpdateOtac_FullMethodName = "/accesscode.AccessCodeSvc/UpdateOtac" + AccessCodeSvc_DeleteOtac_FullMethodName = "/accesscode.AccessCodeSvc/DeleteOtac" + AccessCodeSvc_DeleteCollectionOtac_FullMethodName = "/accesscode.AccessCodeSvc/DeleteCollectionOtac" + AccessCodeSvc_ListOtac_FullMethodName = "/accesscode.AccessCodeSvc/ListOtac" + AccessCodeSvc_ValidateExistence_FullMethodName = "/accesscode.AccessCodeSvc/ValidateExistence" + AccessCodeSvc_GetAccessCodesWithOTACs_FullMethodName = "/accesscode.AccessCodeSvc/GetAccessCodesWithOTACs" + AccessCodeSvc_GetAccessCodeWithOTACs_FullMethodName = "/accesscode.AccessCodeSvc/GetAccessCodeWithOTACs" + AccessCodeSvc_GetAcOwnerReferences_FullMethodName = "/accesscode.AccessCodeSvc/GetAcOwnerReferences" ) // AccessCodeSvcClient is the client API for AccessCodeSvc service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type AccessCodeSvcClient interface { - // rpc CreateOtac (CreateOtacRequest) returns (OneTimeAccessCodeId); - GetOtac(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*OneTimeAccessCode, error) + // Resource oriented RPCs for AccessCodes: + CreateAc(ctx context.Context, in *CreateAcRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + GetAc(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*AccessCode, error) + UpdateAc(ctx context.Context, in *UpdateAccessCodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteAc(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionAc(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListAc(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListAcsResponse, error) + // Resource oriented RPCs for OneTimeAccessCodes: + CreateOtac(ctx context.Context, in *CreateOtacRequest, opts ...grpc.CallOption) (*OneTimeAccessCode, error) + GetOtac(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*OneTimeAccessCode, error) UpdateOtac(ctx context.Context, in *OneTimeAccessCode, opts ...grpc.CallOption) (*emptypb.Empty, error) - ValidateExistence(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*ResourceValidation, error) + DeleteOtac(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionOtac(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListOtac(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListOtacsResponse, error) + // Helper functions + ValidateExistence(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*ResourceValidation, error) + GetAccessCodesWithOTACs(ctx context.Context, in *ResourceIds, opts ...grpc.CallOption) (*ListAcsResponse, error) + GetAccessCodeWithOTACs(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*AccessCode, error) + GetAcOwnerReferences(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*general.OwnerReferences, error) } type accessCodeSvcClient struct { @@ -43,7 +72,70 @@ func NewAccessCodeSvcClient(cc grpc.ClientConnInterface) AccessCodeSvcClient { return &accessCodeSvcClient{cc} } -func (c *accessCodeSvcClient) GetOtac(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*OneTimeAccessCode, error) { +func (c *accessCodeSvcClient) CreateAc(ctx context.Context, in *CreateAcRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_CreateAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) GetAc(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*AccessCode, error) { + out := new(AccessCode) + err := c.cc.Invoke(ctx, AccessCodeSvc_GetAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) UpdateAc(ctx context.Context, in *UpdateAccessCodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_UpdateAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) DeleteAc(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_DeleteAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) DeleteCollectionAc(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_DeleteCollectionAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) ListAc(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListAcsResponse, error) { + out := new(ListAcsResponse) + err := c.cc.Invoke(ctx, AccessCodeSvc_ListAc_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) CreateOtac(ctx context.Context, in *CreateOtacRequest, opts ...grpc.CallOption) (*OneTimeAccessCode, error) { + out := new(OneTimeAccessCode) + err := c.cc.Invoke(ctx, AccessCodeSvc_CreateOtac_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) GetOtac(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*OneTimeAccessCode, error) { out := new(OneTimeAccessCode) err := c.cc.Invoke(ctx, AccessCodeSvc_GetOtac_FullMethodName, in, out, opts...) if err != nil { @@ -61,7 +153,34 @@ func (c *accessCodeSvcClient) UpdateOtac(ctx context.Context, in *OneTimeAccessC return out, nil } -func (c *accessCodeSvcClient) ValidateExistence(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*ResourceValidation, error) { +func (c *accessCodeSvcClient) DeleteOtac(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_DeleteOtac_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) DeleteCollectionOtac(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, AccessCodeSvc_DeleteCollectionOtac_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) ListOtac(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListOtacsResponse, error) { + out := new(ListOtacsResponse) + err := c.cc.Invoke(ctx, AccessCodeSvc_ListOtac_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) ValidateExistence(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*ResourceValidation, error) { out := new(ResourceValidation) err := c.cc.Invoke(ctx, AccessCodeSvc_ValidateExistence_FullMethodName, in, out, opts...) if err != nil { @@ -70,14 +189,56 @@ func (c *accessCodeSvcClient) ValidateExistence(ctx context.Context, in *Resourc return out, nil } +func (c *accessCodeSvcClient) GetAccessCodesWithOTACs(ctx context.Context, in *ResourceIds, opts ...grpc.CallOption) (*ListAcsResponse, error) { + out := new(ListAcsResponse) + err := c.cc.Invoke(ctx, AccessCodeSvc_GetAccessCodesWithOTACs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) GetAccessCodeWithOTACs(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*AccessCode, error) { + out := new(AccessCode) + err := c.cc.Invoke(ctx, AccessCodeSvc_GetAccessCodeWithOTACs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accessCodeSvcClient) GetAcOwnerReferences(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*general.OwnerReferences, error) { + out := new(general.OwnerReferences) + err := c.cc.Invoke(ctx, AccessCodeSvc_GetAcOwnerReferences_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AccessCodeSvcServer is the server API for AccessCodeSvc service. // All implementations must embed UnimplementedAccessCodeSvcServer // for forward compatibility type AccessCodeSvcServer interface { - // rpc CreateOtac (CreateOtacRequest) returns (OneTimeAccessCodeId); - GetOtac(context.Context, *ResourceId) (*OneTimeAccessCode, error) + // Resource oriented RPCs for AccessCodes: + CreateAc(context.Context, *CreateAcRequest) (*emptypb.Empty, error) + GetAc(context.Context, *general.GetRequest) (*AccessCode, error) + UpdateAc(context.Context, *UpdateAccessCodeRequest) (*emptypb.Empty, error) + DeleteAc(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionAc(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListAc(context.Context, *general.ListOptions) (*ListAcsResponse, error) + // Resource oriented RPCs for OneTimeAccessCodes: + CreateOtac(context.Context, *CreateOtacRequest) (*OneTimeAccessCode, error) + GetOtac(context.Context, *general.GetRequest) (*OneTimeAccessCode, error) UpdateOtac(context.Context, *OneTimeAccessCode) (*emptypb.Empty, error) - ValidateExistence(context.Context, *ResourceId) (*ResourceValidation, error) + DeleteOtac(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionOtac(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListOtac(context.Context, *general.ListOptions) (*ListOtacsResponse, error) + // Helper functions + ValidateExistence(context.Context, *general.ResourceId) (*ResourceValidation, error) + GetAccessCodesWithOTACs(context.Context, *ResourceIds) (*ListAcsResponse, error) + GetAccessCodeWithOTACs(context.Context, *general.ResourceId) (*AccessCode, error) + GetAcOwnerReferences(context.Context, *general.GetRequest) (*general.OwnerReferences, error) mustEmbedUnimplementedAccessCodeSvcServer() } @@ -85,15 +246,54 @@ type AccessCodeSvcServer interface { type UnimplementedAccessCodeSvcServer struct { } -func (UnimplementedAccessCodeSvcServer) GetOtac(context.Context, *ResourceId) (*OneTimeAccessCode, error) { +func (UnimplementedAccessCodeSvcServer) CreateAc(context.Context, *CreateAcRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) GetAc(context.Context, *general.GetRequest) (*AccessCode, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) UpdateAc(context.Context, *UpdateAccessCodeRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) DeleteAc(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) DeleteCollectionAc(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) ListAc(context.Context, *general.ListOptions) (*ListAcsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListAc not implemented") +} +func (UnimplementedAccessCodeSvcServer) CreateOtac(context.Context, *CreateOtacRequest) (*OneTimeAccessCode, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateOtac not implemented") +} +func (UnimplementedAccessCodeSvcServer) GetOtac(context.Context, *general.GetRequest) (*OneTimeAccessCode, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOtac not implemented") } func (UnimplementedAccessCodeSvcServer) UpdateOtac(context.Context, *OneTimeAccessCode) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateOtac not implemented") } -func (UnimplementedAccessCodeSvcServer) ValidateExistence(context.Context, *ResourceId) (*ResourceValidation, error) { +func (UnimplementedAccessCodeSvcServer) DeleteOtac(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteOtac not implemented") +} +func (UnimplementedAccessCodeSvcServer) DeleteCollectionOtac(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionOtac not implemented") +} +func (UnimplementedAccessCodeSvcServer) ListOtac(context.Context, *general.ListOptions) (*ListOtacsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListOtac not implemented") +} +func (UnimplementedAccessCodeSvcServer) ValidateExistence(context.Context, *general.ResourceId) (*ResourceValidation, error) { return nil, status.Errorf(codes.Unimplemented, "method ValidateExistence not implemented") } +func (UnimplementedAccessCodeSvcServer) GetAccessCodesWithOTACs(context.Context, *ResourceIds) (*ListAcsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAccessCodesWithOTACs not implemented") +} +func (UnimplementedAccessCodeSvcServer) GetAccessCodeWithOTACs(context.Context, *general.ResourceId) (*AccessCode, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAccessCodeWithOTACs not implemented") +} +func (UnimplementedAccessCodeSvcServer) GetAcOwnerReferences(context.Context, *general.GetRequest) (*general.OwnerReferences, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAcOwnerReferences not implemented") +} func (UnimplementedAccessCodeSvcServer) mustEmbedUnimplementedAccessCodeSvcServer() {} // UnsafeAccessCodeSvcServer may be embedded to opt out of forward compatibility for this service. @@ -107,8 +307,134 @@ func RegisterAccessCodeSvcServer(s grpc.ServiceRegistrar, srv AccessCodeSvcServe s.RegisterService(&AccessCodeSvc_ServiceDesc, srv) } +func _AccessCodeSvc_CreateAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateAcRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).CreateAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_CreateAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).CreateAc(ctx, req.(*CreateAcRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_GetAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).GetAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_GetAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).GetAc(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_UpdateAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateAccessCodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).UpdateAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_UpdateAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).UpdateAc(ctx, req.(*UpdateAccessCodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_DeleteAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).DeleteAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_DeleteAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).DeleteAc(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_DeleteCollectionAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).DeleteCollectionAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_DeleteCollectionAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).DeleteCollectionAc(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_ListAc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).ListAc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_ListAc_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).ListAc(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_CreateOtac_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateOtacRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).CreateOtac(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_CreateOtac_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).CreateOtac(ctx, req.(*CreateOtacRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AccessCodeSvc_GetOtac_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -120,7 +446,7 @@ func _AccessCodeSvc_GetOtac_Handler(srv interface{}, ctx context.Context, dec fu FullMethod: AccessCodeSvc_GetOtac_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AccessCodeSvcServer).GetOtac(ctx, req.(*ResourceId)) + return srv.(AccessCodeSvcServer).GetOtac(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } @@ -143,8 +469,62 @@ func _AccessCodeSvc_UpdateOtac_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _AccessCodeSvc_DeleteOtac_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).DeleteOtac(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_DeleteOtac_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).DeleteOtac(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_DeleteCollectionOtac_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).DeleteCollectionOtac(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_DeleteCollectionOtac_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).DeleteCollectionOtac(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_ListOtac_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).ListOtac(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_ListOtac_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).ListOtac(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + func _AccessCodeSvc_ValidateExistence_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -156,7 +536,61 @@ func _AccessCodeSvc_ValidateExistence_Handler(srv interface{}, ctx context.Conte FullMethod: AccessCodeSvc_ValidateExistence_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AccessCodeSvcServer).ValidateExistence(ctx, req.(*ResourceId)) + return srv.(AccessCodeSvcServer).ValidateExistence(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_GetAccessCodesWithOTACs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResourceIds) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).GetAccessCodesWithOTACs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_GetAccessCodesWithOTACs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).GetAccessCodesWithOTACs(ctx, req.(*ResourceIds)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_GetAccessCodeWithOTACs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).GetAccessCodeWithOTACs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_GetAccessCodeWithOTACs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).GetAccessCodeWithOTACs(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _AccessCodeSvc_GetAcOwnerReferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccessCodeSvcServer).GetAcOwnerReferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AccessCodeSvc_GetAcOwnerReferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccessCodeSvcServer).GetAcOwnerReferences(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } @@ -165,9 +599,37 @@ func _AccessCodeSvc_ValidateExistence_Handler(srv interface{}, ctx context.Conte // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var AccessCodeSvc_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "access_code.AccessCodeSvc", + ServiceName: "accesscode.AccessCodeSvc", HandlerType: (*AccessCodeSvcServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "CreateAc", + Handler: _AccessCodeSvc_CreateAc_Handler, + }, + { + MethodName: "GetAc", + Handler: _AccessCodeSvc_GetAc_Handler, + }, + { + MethodName: "UpdateAc", + Handler: _AccessCodeSvc_UpdateAc_Handler, + }, + { + MethodName: "DeleteAc", + Handler: _AccessCodeSvc_DeleteAc_Handler, + }, + { + MethodName: "DeleteCollectionAc", + Handler: _AccessCodeSvc_DeleteCollectionAc_Handler, + }, + { + MethodName: "ListAc", + Handler: _AccessCodeSvc_ListAc_Handler, + }, + { + MethodName: "CreateOtac", + Handler: _AccessCodeSvc_CreateOtac_Handler, + }, { MethodName: "GetOtac", Handler: _AccessCodeSvc_GetOtac_Handler, @@ -176,10 +638,34 @@ var AccessCodeSvc_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateOtac", Handler: _AccessCodeSvc_UpdateOtac_Handler, }, + { + MethodName: "DeleteOtac", + Handler: _AccessCodeSvc_DeleteOtac_Handler, + }, + { + MethodName: "DeleteCollectionOtac", + Handler: _AccessCodeSvc_DeleteCollectionOtac_Handler, + }, + { + MethodName: "ListOtac", + Handler: _AccessCodeSvc_ListOtac_Handler, + }, { MethodName: "ValidateExistence", Handler: _AccessCodeSvc_ValidateExistence_Handler, }, + { + MethodName: "GetAccessCodesWithOTACs", + Handler: _AccessCodeSvc_GetAccessCodesWithOTACs_Handler, + }, + { + MethodName: "GetAccessCodeWithOTACs", + Handler: _AccessCodeSvc_GetAccessCodeWithOTACs_Handler, + }, + { + MethodName: "GetAcOwnerReferences", + Handler: _AccessCodeSvc_GetAcOwnerReferences_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "accesscode/accesscode.proto", diff --git a/v3/protos/authn/authn.pb.go b/v3/protos/authn/authn.pb.go index e8f1c7e9..a549b6b0 100644 --- a/v3/protos/authn/authn.pb.go +++ b/v3/protos/authn/authn.pb.go @@ -1,10 +1,10 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: authn/authn.proto -package authn +package authnpb import ( user "github.com/hobbyfarm/gargantua/v3/protos/user" @@ -79,10 +79,11 @@ var file_authn_authn_proto_rawDesc = []byte{ 0x6e, 0x32, 0x31, 0x0a, 0x05, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x12, 0x28, 0x0a, 0x05, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x12, 0x13, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x55, 0x73, 0x65, 0x72, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/v3/protos/authn/authn.proto b/v3/protos/authn/authn.proto index 9b7868fc..5b770942 100644 --- a/v3/protos/authn/authn.proto +++ b/v3/protos/authn/authn.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package authn; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/authn"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/authn;authnpb"; import "user/user.proto"; diff --git a/v3/protos/authn/authn_grpc.pb.go b/v3/protos/authn/authn_grpc.pb.go index 313aef78..80b932f9 100644 --- a/v3/protos/authn/authn_grpc.pb.go +++ b/v3/protos/authn/authn_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc v3.21.12 // source: authn/authn.proto -package authn +package authnpb import ( context "context" diff --git a/v3/protos/authr/authr.pb.go b/v3/protos/authr/authr.pb.go index 74eb25ad..ed6ea512 100644 --- a/v3/protos/authr/authr.pb.go +++ b/v3/protos/authr/authr.pb.go @@ -1,10 +1,10 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: authr/authr.proto -package authr +package authrpb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -268,10 +268,11 @@ var file_authr_authr_proto_rawDesc = []byte{ 0x68, 0x52, 0x12, 0x32, 0x0a, 0x05, 0x41, 0x75, 0x74, 0x68, 0x52, 0x12, 0x13, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x72, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x72, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/v3/protos/authr/authr.proto b/v3/protos/authr/authr.proto index fa147928..9072bf8d 100644 --- a/v3/protos/authr/authr.proto +++ b/v3/protos/authr/authr.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package authr; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/authr"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/authr;authrpb"; // Service definition service AuthR { diff --git a/v3/protos/authr/authr_grpc.pb.go b/v3/protos/authr/authr_grpc.pb.go index 05408c04..589abe9a 100644 --- a/v3/protos/authr/authr_grpc.pb.go +++ b/v3/protos/authr/authr_grpc.pb.go @@ -4,7 +4,7 @@ // - protoc v3.21.12 // source: authr/authr.proto -package authr +package authrpb import ( context "context" diff --git a/v3/protos/course/course.pb.go b/v3/protos/course/course.pb.go new file mode 100644 index 00000000..9bc1dac0 --- /dev/null +++ b/v3/protos/course/course.pb.go @@ -0,0 +1,670 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: course/course.proto + +package coursepb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Course struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Scenarios []string `protobuf:"bytes,5,rep,name=scenarios,proto3" json:"scenarios,omitempty"` + Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` + Vms []*general.StringMap `protobuf:"bytes,7,rep,name=vms,proto3" json:"vms,omitempty"` + KeepaliveDuration string `protobuf:"bytes,8,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration string `protobuf:"bytes,9,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable bool `protobuf:"varint,10,opt,name=pausable,proto3" json:"pausable,omitempty"` + KeepVm bool `protobuf:"varint,11,opt,name=keep_vm,json=keepVm,proto3" json:"keep_vm,omitempty"` +} + +func (x *Course) Reset() { + *x = Course{} + if protoimpl.UnsafeEnabled { + mi := &file_course_course_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Course) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Course) ProtoMessage() {} + +func (x *Course) ProtoReflect() protoreflect.Message { + mi := &file_course_course_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Course.ProtoReflect.Descriptor instead. +func (*Course) Descriptor() ([]byte, []int) { + return file_course_course_proto_rawDescGZIP(), []int{0} +} + +func (x *Course) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Course) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *Course) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Course) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Course) GetScenarios() []string { + if x != nil { + return x.Scenarios + } + return nil +} + +func (x *Course) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +func (x *Course) GetVms() []*general.StringMap { + if x != nil { + return x.Vms + } + return nil +} + +func (x *Course) GetKeepaliveDuration() string { + if x != nil { + return x.KeepaliveDuration + } + return "" +} + +func (x *Course) GetPauseDuration() string { + if x != nil { + return x.PauseDuration + } + return "" +} + +func (x *Course) GetPausable() bool { + if x != nil { + return x.Pausable + } + return false +} + +func (x *Course) GetKeepVm() bool { + if x != nil { + return x.KeepVm + } + return false +} + +type CreateCourseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + RawScenarios string `protobuf:"bytes,3,opt,name=raw_scenarios,json=rawScenarios,proto3" json:"raw_scenarios,omitempty"` + RawCategories string `protobuf:"bytes,4,opt,name=raw_categories,json=rawCategories,proto3" json:"raw_categories,omitempty"` + RawVms string `protobuf:"bytes,5,opt,name=raw_vms,json=rawVms,proto3" json:"raw_vms,omitempty"` + KeepaliveDuration string `protobuf:"bytes,6,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration string `protobuf:"bytes,7,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable bool `protobuf:"varint,8,opt,name=pausable,proto3" json:"pausable,omitempty"` + KeepVm bool `protobuf:"varint,9,opt,name=keep_vm,json=keepVm,proto3" json:"keep_vm,omitempty"` +} + +func (x *CreateCourseRequest) Reset() { + *x = CreateCourseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_course_course_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateCourseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateCourseRequest) ProtoMessage() {} + +func (x *CreateCourseRequest) ProtoReflect() protoreflect.Message { + mi := &file_course_course_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateCourseRequest.ProtoReflect.Descriptor instead. +func (*CreateCourseRequest) Descriptor() ([]byte, []int) { + return file_course_course_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateCourseRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateCourseRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateCourseRequest) GetRawScenarios() string { + if x != nil { + return x.RawScenarios + } + return "" +} + +func (x *CreateCourseRequest) GetRawCategories() string { + if x != nil { + return x.RawCategories + } + return "" +} + +func (x *CreateCourseRequest) GetRawVms() string { + if x != nil { + return x.RawVms + } + return "" +} + +func (x *CreateCourseRequest) GetKeepaliveDuration() string { + if x != nil { + return x.KeepaliveDuration + } + return "" +} + +func (x *CreateCourseRequest) GetPauseDuration() string { + if x != nil { + return x.PauseDuration + } + return "" +} + +func (x *CreateCourseRequest) GetPausable() bool { + if x != nil { + return x.Pausable + } + return false +} + +func (x *CreateCourseRequest) GetKeepVm() bool { + if x != nil { + return x.KeepVm + } + return false +} + +type UpdateCourseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + RawScenarios string `protobuf:"bytes,4,opt,name=raw_scenarios,json=rawScenarios,proto3" json:"raw_scenarios,omitempty"` + RawCategories string `protobuf:"bytes,5,opt,name=raw_categories,json=rawCategories,proto3" json:"raw_categories,omitempty"` + RawVms string `protobuf:"bytes,6,opt,name=raw_vms,json=rawVms,proto3" json:"raw_vms,omitempty"` + KeepaliveDuration *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration *wrapperspb.StringValue `protobuf:"bytes,8,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable *wrapperspb.BoolValue `protobuf:"bytes,9,opt,name=pausable,proto3" json:"pausable,omitempty"` + KeepVm *wrapperspb.BoolValue `protobuf:"bytes,10,opt,name=keep_vm,json=keepVm,proto3" json:"keep_vm,omitempty"` +} + +func (x *UpdateCourseRequest) Reset() { + *x = UpdateCourseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_course_course_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateCourseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateCourseRequest) ProtoMessage() {} + +func (x *UpdateCourseRequest) ProtoReflect() protoreflect.Message { + mi := &file_course_course_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateCourseRequest.ProtoReflect.Descriptor instead. +func (*UpdateCourseRequest) Descriptor() ([]byte, []int) { + return file_course_course_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateCourseRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateCourseRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateCourseRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *UpdateCourseRequest) GetRawScenarios() string { + if x != nil { + return x.RawScenarios + } + return "" +} + +func (x *UpdateCourseRequest) GetRawCategories() string { + if x != nil { + return x.RawCategories + } + return "" +} + +func (x *UpdateCourseRequest) GetRawVms() string { + if x != nil { + return x.RawVms + } + return "" +} + +func (x *UpdateCourseRequest) GetKeepaliveDuration() *wrapperspb.StringValue { + if x != nil { + return x.KeepaliveDuration + } + return nil +} + +func (x *UpdateCourseRequest) GetPauseDuration() *wrapperspb.StringValue { + if x != nil { + return x.PauseDuration + } + return nil +} + +func (x *UpdateCourseRequest) GetPausable() *wrapperspb.BoolValue { + if x != nil { + return x.Pausable + } + return nil +} + +func (x *UpdateCourseRequest) GetKeepVm() *wrapperspb.BoolValue { + if x != nil { + return x.KeepVm + } + return nil +} + +type ListCoursesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Courses []*Course `protobuf:"bytes,1,rep,name=courses,proto3" json:"courses,omitempty"` +} + +func (x *ListCoursesResponse) Reset() { + *x = ListCoursesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_course_course_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListCoursesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListCoursesResponse) ProtoMessage() {} + +func (x *ListCoursesResponse) ProtoReflect() protoreflect.Message { + mi := &file_course_course_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListCoursesResponse.ProtoReflect.Descriptor instead. +func (*ListCoursesResponse) Descriptor() ([]byte, []int) { + return file_course_course_proto_rawDescGZIP(), []int{3} +} + +func (x *ListCoursesResponse) GetCourses() []*Course { + if x != nil { + return x.Courses + } + return nil +} + +var File_course_course_proto protoreflect.FileDescriptor + +var file_course_course_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x1a, 0x15, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xcf, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x24, 0x0a, 0x03, 0x76, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4d, 0x61, 0x70, 0x52, 0x03, 0x76, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, + 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, + 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x70, 0x61, 0x75, 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x65, + 0x65, 0x70, 0x5f, 0x76, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6b, 0x65, 0x65, + 0x70, 0x56, 0x6d, 0x22, 0xbb, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x53, 0x63, 0x65, + 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x61, 0x77, 0x5f, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x72, 0x61, 0x77, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x17, 0x0a, + 0x07, 0x72, 0x61, 0x77, 0x5f, 0x76, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x72, 0x61, 0x77, 0x56, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, + 0x69, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, + 0x61, 0x75, 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x65, 0x65, 0x70, + 0x5f, 0x76, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6b, 0x65, 0x65, 0x70, 0x56, + 0x6d, 0x22, 0xbf, 0x03, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x72, + 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x23, 0x0a, 0x0d, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x61, 0x77, 0x53, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x61, 0x77, 0x5f, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x61, + 0x77, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x72, + 0x61, 0x77, 0x5f, 0x76, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x61, + 0x77, 0x56, 0x6d, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, + 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, + 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x43, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x70, 0x61, 0x75, 0x73, 0x65, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x33, + 0x0a, 0x07, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x76, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6b, 0x65, 0x65, + 0x70, 0x56, 0x6d, 0x22, 0x3f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x72, 0x73, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x07, 0x63, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x75, + 0x72, 0x73, 0x65, 0x73, 0x32, 0x8a, 0x03, 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x53, + 0x76, 0x63, 0x12, 0x40, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x72, + 0x73, 0x65, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x72, 0x73, + 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2e, + 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0c, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x72, + 0x73, 0x65, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x3f, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x14, + 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1b, 0x2e, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, + 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6f, + 0x75, 0x72, 0x73, 0x65, 0x3b, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_course_course_proto_rawDescOnce sync.Once + file_course_course_proto_rawDescData = file_course_course_proto_rawDesc +) + +func file_course_course_proto_rawDescGZIP() []byte { + file_course_course_proto_rawDescOnce.Do(func() { + file_course_course_proto_rawDescData = protoimpl.X.CompressGZIP(file_course_course_proto_rawDescData) + }) + return file_course_course_proto_rawDescData +} + +var file_course_course_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_course_course_proto_goTypes = []interface{}{ + (*Course)(nil), // 0: course.Course + (*CreateCourseRequest)(nil), // 1: course.CreateCourseRequest + (*UpdateCourseRequest)(nil), // 2: course.UpdateCourseRequest + (*ListCoursesResponse)(nil), // 3: course.ListCoursesResponse + (*general.StringMap)(nil), // 4: general.StringMap + (*wrapperspb.StringValue)(nil), // 5: google.protobuf.StringValue + (*wrapperspb.BoolValue)(nil), // 6: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 7: general.GetRequest + (*general.ResourceId)(nil), // 8: general.ResourceId + (*general.ListOptions)(nil), // 9: general.ListOptions + (*emptypb.Empty)(nil), // 10: google.protobuf.Empty +} +var file_course_course_proto_depIdxs = []int32{ + 4, // 0: course.Course.vms:type_name -> general.StringMap + 5, // 1: course.UpdateCourseRequest.keepalive_duration:type_name -> google.protobuf.StringValue + 5, // 2: course.UpdateCourseRequest.pause_duration:type_name -> google.protobuf.StringValue + 6, // 3: course.UpdateCourseRequest.pausable:type_name -> google.protobuf.BoolValue + 6, // 4: course.UpdateCourseRequest.keep_vm:type_name -> google.protobuf.BoolValue + 0, // 5: course.ListCoursesResponse.courses:type_name -> course.Course + 1, // 6: course.CourseSvc.CreateCourse:input_type -> course.CreateCourseRequest + 7, // 7: course.CourseSvc.GetCourse:input_type -> general.GetRequest + 2, // 8: course.CourseSvc.UpdateCourse:input_type -> course.UpdateCourseRequest + 8, // 9: course.CourseSvc.DeleteCourse:input_type -> general.ResourceId + 9, // 10: course.CourseSvc.DeleteCollectionCourse:input_type -> general.ListOptions + 9, // 11: course.CourseSvc.ListCourse:input_type -> general.ListOptions + 8, // 12: course.CourseSvc.CreateCourse:output_type -> general.ResourceId + 0, // 13: course.CourseSvc.GetCourse:output_type -> course.Course + 10, // 14: course.CourseSvc.UpdateCourse:output_type -> google.protobuf.Empty + 10, // 15: course.CourseSvc.DeleteCourse:output_type -> google.protobuf.Empty + 10, // 16: course.CourseSvc.DeleteCollectionCourse:output_type -> google.protobuf.Empty + 3, // 17: course.CourseSvc.ListCourse:output_type -> course.ListCoursesResponse + 12, // [12:18] is the sub-list for method output_type + 6, // [6:12] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_course_course_proto_init() } +func file_course_course_proto_init() { + if File_course_course_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_course_course_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Course); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_course_course_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateCourseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_course_course_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateCourseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_course_course_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListCoursesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_course_course_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_course_course_proto_goTypes, + DependencyIndexes: file_course_course_proto_depIdxs, + MessageInfos: file_course_course_proto_msgTypes, + }.Build() + File_course_course_proto = out.File + file_course_course_proto_rawDesc = nil + file_course_course_proto_goTypes = nil + file_course_course_proto_depIdxs = nil +} diff --git a/v3/protos/course/course.proto b/v3/protos/course/course.proto new file mode 100644 index 00000000..099a508d --- /dev/null +++ b/v3/protos/course/course.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +package course; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/course;coursepb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service CourseSvc { + rpc CreateCourse (CreateCourseRequest) returns (general.ResourceId); + rpc GetCourse (general.GetRequest) returns (Course); + rpc UpdateCourse (UpdateCourseRequest) returns (google.protobuf.Empty); + rpc DeleteCourse (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionCourse (general.ListOptions) returns (google.protobuf.Empty); + rpc ListCourse (general.ListOptions) returns (ListCoursesResponse); +} + +message Course { + string id = 1; + string uid = 2; + string name = 3; + string description = 4; + repeated string scenarios = 5; + repeated string categories = 6; + repeated general.StringMap vms = 7; + string keepalive_duration = 8; + string pause_duration = 9; + bool pausable = 10; + bool keep_vm = 11; +} + +message CreateCourseRequest { + string name = 1; + string description = 2; + string raw_scenarios = 3; + string raw_categories = 4; + string raw_vms = 5; + string keepalive_duration = 6; + string pause_duration = 7; + bool pausable = 8; + bool keep_vm = 9; +} + +message UpdateCourseRequest { + string id = 1; + string name = 2; + string description = 3; + string raw_scenarios = 4; + string raw_categories = 5; + string raw_vms = 6; + google.protobuf.StringValue keepalive_duration = 7; + google.protobuf.StringValue pause_duration = 8; + google.protobuf.BoolValue pausable = 9; + google.protobuf.BoolValue keep_vm = 10; +} + +message ListCoursesResponse { + repeated Course courses = 1; +} \ No newline at end of file diff --git a/v3/protos/course/course_grpc.pb.go b/v3/protos/course/course_grpc.pb.go new file mode 100644 index 00000000..46cab069 --- /dev/null +++ b/v3/protos/course/course_grpc.pb.go @@ -0,0 +1,296 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: course/course.proto + +package coursepb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + CourseSvc_CreateCourse_FullMethodName = "/course.CourseSvc/CreateCourse" + CourseSvc_GetCourse_FullMethodName = "/course.CourseSvc/GetCourse" + CourseSvc_UpdateCourse_FullMethodName = "/course.CourseSvc/UpdateCourse" + CourseSvc_DeleteCourse_FullMethodName = "/course.CourseSvc/DeleteCourse" + CourseSvc_DeleteCollectionCourse_FullMethodName = "/course.CourseSvc/DeleteCollectionCourse" + CourseSvc_ListCourse_FullMethodName = "/course.CourseSvc/ListCourse" +) + +// CourseSvcClient is the client API for CourseSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type CourseSvcClient interface { + CreateCourse(ctx context.Context, in *CreateCourseRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetCourse(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Course, error) + UpdateCourse(ctx context.Context, in *UpdateCourseRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCourse(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionCourse(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListCourse(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListCoursesResponse, error) +} + +type courseSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewCourseSvcClient(cc grpc.ClientConnInterface) CourseSvcClient { + return &courseSvcClient{cc} +} + +func (c *courseSvcClient) CreateCourse(ctx context.Context, in *CreateCourseRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, CourseSvc_CreateCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *courseSvcClient) GetCourse(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Course, error) { + out := new(Course) + err := c.cc.Invoke(ctx, CourseSvc_GetCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *courseSvcClient) UpdateCourse(ctx context.Context, in *UpdateCourseRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, CourseSvc_UpdateCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *courseSvcClient) DeleteCourse(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, CourseSvc_DeleteCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *courseSvcClient) DeleteCollectionCourse(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, CourseSvc_DeleteCollectionCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *courseSvcClient) ListCourse(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListCoursesResponse, error) { + out := new(ListCoursesResponse) + err := c.cc.Invoke(ctx, CourseSvc_ListCourse_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CourseSvcServer is the server API for CourseSvc service. +// All implementations must embed UnimplementedCourseSvcServer +// for forward compatibility +type CourseSvcServer interface { + CreateCourse(context.Context, *CreateCourseRequest) (*general.ResourceId, error) + GetCourse(context.Context, *general.GetRequest) (*Course, error) + UpdateCourse(context.Context, *UpdateCourseRequest) (*emptypb.Empty, error) + DeleteCourse(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionCourse(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListCourse(context.Context, *general.ListOptions) (*ListCoursesResponse, error) + mustEmbedUnimplementedCourseSvcServer() +} + +// UnimplementedCourseSvcServer must be embedded to have forward compatible implementations. +type UnimplementedCourseSvcServer struct { +} + +func (UnimplementedCourseSvcServer) CreateCourse(context.Context, *CreateCourseRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateCourse not implemented") +} +func (UnimplementedCourseSvcServer) GetCourse(context.Context, *general.GetRequest) (*Course, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCourse not implemented") +} +func (UnimplementedCourseSvcServer) UpdateCourse(context.Context, *UpdateCourseRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateCourse not implemented") +} +func (UnimplementedCourseSvcServer) DeleteCourse(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCourse not implemented") +} +func (UnimplementedCourseSvcServer) DeleteCollectionCourse(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionCourse not implemented") +} +func (UnimplementedCourseSvcServer) ListCourse(context.Context, *general.ListOptions) (*ListCoursesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListCourse not implemented") +} +func (UnimplementedCourseSvcServer) mustEmbedUnimplementedCourseSvcServer() {} + +// UnsafeCourseSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CourseSvcServer will +// result in compilation errors. +type UnsafeCourseSvcServer interface { + mustEmbedUnimplementedCourseSvcServer() +} + +func RegisterCourseSvcServer(s grpc.ServiceRegistrar, srv CourseSvcServer) { + s.RegisterService(&CourseSvc_ServiceDesc, srv) +} + +func _CourseSvc_CreateCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateCourseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).CreateCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_CreateCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).CreateCourse(ctx, req.(*CreateCourseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CourseSvc_GetCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).GetCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_GetCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).GetCourse(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CourseSvc_UpdateCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateCourseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).UpdateCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_UpdateCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).UpdateCourse(ctx, req.(*UpdateCourseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CourseSvc_DeleteCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).DeleteCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_DeleteCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).DeleteCourse(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _CourseSvc_DeleteCollectionCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).DeleteCollectionCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_DeleteCollectionCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).DeleteCollectionCourse(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _CourseSvc_ListCourse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CourseSvcServer).ListCourse(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CourseSvc_ListCourse_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CourseSvcServer).ListCourse(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// CourseSvc_ServiceDesc is the grpc.ServiceDesc for CourseSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CourseSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "course.CourseSvc", + HandlerType: (*CourseSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateCourse", + Handler: _CourseSvc_CreateCourse_Handler, + }, + { + MethodName: "GetCourse", + Handler: _CourseSvc_GetCourse_Handler, + }, + { + MethodName: "UpdateCourse", + Handler: _CourseSvc_UpdateCourse_Handler, + }, + { + MethodName: "DeleteCourse", + Handler: _CourseSvc_DeleteCourse_Handler, + }, + { + MethodName: "DeleteCollectionCourse", + Handler: _CourseSvc_DeleteCollectionCourse_Handler, + }, + { + MethodName: "ListCourse", + Handler: _CourseSvc_ListCourse_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "course/course.proto", +} diff --git a/v3/protos/dbconfig/dbconfig.pb.go b/v3/protos/dbconfig/dbconfig.pb.go new file mode 100644 index 00000000..54b386a7 --- /dev/null +++ b/v3/protos/dbconfig/dbconfig.pb.go @@ -0,0 +1,585 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: dbconfig/dbconfig.proto + +package dbconfigpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DynamicBindConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Environment string `protobuf:"bytes,3,opt,name=environment,proto3" json:"environment,omitempty"` + RestrictedBind bool `protobuf:"varint,4,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,5,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + BurstCountCapacity map[string]uint32 `protobuf:"bytes,6,rep,name=burst_count_capacity,json=burstCountCapacity,proto3" json:"burst_count_capacity,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Labels map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *DynamicBindConfig) Reset() { + *x = DynamicBindConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_dbconfig_dbconfig_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DynamicBindConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DynamicBindConfig) ProtoMessage() {} + +func (x *DynamicBindConfig) ProtoReflect() protoreflect.Message { + mi := &file_dbconfig_dbconfig_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DynamicBindConfig.ProtoReflect.Descriptor instead. +func (*DynamicBindConfig) Descriptor() ([]byte, []int) { + return file_dbconfig_dbconfig_proto_rawDescGZIP(), []int{0} +} + +func (x *DynamicBindConfig) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *DynamicBindConfig) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *DynamicBindConfig) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *DynamicBindConfig) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *DynamicBindConfig) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *DynamicBindConfig) GetBurstCountCapacity() map[string]uint32 { + if x != nil { + return x.BurstCountCapacity + } + return nil +} + +func (x *DynamicBindConfig) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type CreateDynamicBindConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SeName string `protobuf:"bytes,1,opt,name=se_name,json=seName,proto3" json:"se_name,omitempty"` + SeUid string `protobuf:"bytes,2,opt,name=se_uid,json=seUid,proto3" json:"se_uid,omitempty"` + EnvName string `protobuf:"bytes,3,opt,name=env_name,json=envName,proto3" json:"env_name,omitempty"` + BurstCountCapacity map[string]uint32 `protobuf:"bytes,4,rep,name=burst_count_capacity,json=burstCountCapacity,proto3" json:"burst_count_capacity,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + RestrictedBind bool `protobuf:"varint,5,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,6,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` +} + +func (x *CreateDynamicBindConfigRequest) Reset() { + *x = CreateDynamicBindConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dbconfig_dbconfig_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDynamicBindConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDynamicBindConfigRequest) ProtoMessage() {} + +func (x *CreateDynamicBindConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_dbconfig_dbconfig_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDynamicBindConfigRequest.ProtoReflect.Descriptor instead. +func (*CreateDynamicBindConfigRequest) Descriptor() ([]byte, []int) { + return file_dbconfig_dbconfig_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateDynamicBindConfigRequest) GetSeName() string { + if x != nil { + return x.SeName + } + return "" +} + +func (x *CreateDynamicBindConfigRequest) GetSeUid() string { + if x != nil { + return x.SeUid + } + return "" +} + +func (x *CreateDynamicBindConfigRequest) GetEnvName() string { + if x != nil { + return x.EnvName + } + return "" +} + +func (x *CreateDynamicBindConfigRequest) GetBurstCountCapacity() map[string]uint32 { + if x != nil { + return x.BurstCountCapacity + } + return nil +} + +func (x *CreateDynamicBindConfigRequest) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *CreateDynamicBindConfigRequest) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +type UpdateDynamicBindConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Environment string `protobuf:"bytes,2,opt,name=environment,proto3" json:"environment,omitempty"` + RestrictedBind *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + BurstCountCapacity map[string]uint32 `protobuf:"bytes,4,rep,name=burst_count_capacity,json=burstCountCapacity,proto3" json:"burst_count_capacity,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *UpdateDynamicBindConfigRequest) Reset() { + *x = UpdateDynamicBindConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dbconfig_dbconfig_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDynamicBindConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDynamicBindConfigRequest) ProtoMessage() {} + +func (x *UpdateDynamicBindConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_dbconfig_dbconfig_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDynamicBindConfigRequest.ProtoReflect.Descriptor instead. +func (*UpdateDynamicBindConfigRequest) Descriptor() ([]byte, []int) { + return file_dbconfig_dbconfig_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateDynamicBindConfigRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateDynamicBindConfigRequest) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *UpdateDynamicBindConfigRequest) GetRestrictedBind() *wrapperspb.BoolValue { + if x != nil { + return x.RestrictedBind + } + return nil +} + +func (x *UpdateDynamicBindConfigRequest) GetBurstCountCapacity() map[string]uint32 { + if x != nil { + return x.BurstCountCapacity + } + return nil +} + +type ListDynamicBindConfigsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DbConfig []*DynamicBindConfig `protobuf:"bytes,1,rep,name=db_config,json=dbConfig,proto3" json:"db_config,omitempty"` +} + +func (x *ListDynamicBindConfigsResponse) Reset() { + *x = ListDynamicBindConfigsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dbconfig_dbconfig_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDynamicBindConfigsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDynamicBindConfigsResponse) ProtoMessage() {} + +func (x *ListDynamicBindConfigsResponse) ProtoReflect() protoreflect.Message { + mi := &file_dbconfig_dbconfig_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDynamicBindConfigsResponse.ProtoReflect.Descriptor instead. +func (*ListDynamicBindConfigsResponse) Descriptor() ([]byte, []int) { + return file_dbconfig_dbconfig_proto_rawDescGZIP(), []int{3} +} + +func (x *ListDynamicBindConfigsResponse) GetDbConfig() []*DynamicBindConfig { + if x != nil { + return x.DbConfig + } + return nil +} + +var File_dbconfig_dbconfig_proto protoreflect.FileDescriptor + +var file_dbconfig_dbconfig_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x64, 0x62, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x64, 0x62, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xde, 0x03, 0x0a, 0x11, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x65, + 0x0a, 0x14, 0x62, 0x75, 0x72, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, + 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, + 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x12, 0x62, 0x75, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x45, 0x0a, 0x17, 0x42, 0x75, 0x72, 0x73, 0x74, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, + 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x83, 0x03, 0x0a, 0x1e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x65, 0x55, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65, + 0x6e, 0x76, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, + 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x72, 0x0a, 0x14, 0x62, 0x75, 0x72, 0x73, 0x74, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, + 0x75, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x62, 0x75, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, + 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, + 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x45, 0x0a, 0x17, 0x42, 0x75, 0x72, 0x73, 0x74, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd2, + 0x02, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, + 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x72, 0x0a, 0x14, 0x62, 0x75, 0x72, 0x73, + 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, + 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x62, 0x75, 0x72, 0x73, 0x74, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x1a, 0x45, 0x0a, 0x17, + 0x42, 0x75, 0x72, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x5a, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x62, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x64, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, + 0x8e, 0x04, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x76, 0x63, 0x12, 0x5b, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x5b, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, + 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x2e, 0x64, 0x62, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x17, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x21, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, + 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x57, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x28, 0x2e, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x42, 0x69, 0x6e, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, + 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, + 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x64, 0x62, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3b, 0x64, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dbconfig_dbconfig_proto_rawDescOnce sync.Once + file_dbconfig_dbconfig_proto_rawDescData = file_dbconfig_dbconfig_proto_rawDesc +) + +func file_dbconfig_dbconfig_proto_rawDescGZIP() []byte { + file_dbconfig_dbconfig_proto_rawDescOnce.Do(func() { + file_dbconfig_dbconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_dbconfig_dbconfig_proto_rawDescData) + }) + return file_dbconfig_dbconfig_proto_rawDescData +} + +var file_dbconfig_dbconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_dbconfig_dbconfig_proto_goTypes = []interface{}{ + (*DynamicBindConfig)(nil), // 0: dbconfig.DynamicBindConfig + (*CreateDynamicBindConfigRequest)(nil), // 1: dbconfig.CreateDynamicBindConfigRequest + (*UpdateDynamicBindConfigRequest)(nil), // 2: dbconfig.UpdateDynamicBindConfigRequest + (*ListDynamicBindConfigsResponse)(nil), // 3: dbconfig.ListDynamicBindConfigsResponse + nil, // 4: dbconfig.DynamicBindConfig.BurstCountCapacityEntry + nil, // 5: dbconfig.DynamicBindConfig.LabelsEntry + nil, // 6: dbconfig.CreateDynamicBindConfigRequest.BurstCountCapacityEntry + nil, // 7: dbconfig.UpdateDynamicBindConfigRequest.BurstCountCapacityEntry + (*wrapperspb.BoolValue)(nil), // 8: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 9: general.GetRequest + (*general.ResourceId)(nil), // 10: general.ResourceId + (*general.ListOptions)(nil), // 11: general.ListOptions + (*emptypb.Empty)(nil), // 12: google.protobuf.Empty +} +var file_dbconfig_dbconfig_proto_depIdxs = []int32{ + 4, // 0: dbconfig.DynamicBindConfig.burst_count_capacity:type_name -> dbconfig.DynamicBindConfig.BurstCountCapacityEntry + 5, // 1: dbconfig.DynamicBindConfig.labels:type_name -> dbconfig.DynamicBindConfig.LabelsEntry + 6, // 2: dbconfig.CreateDynamicBindConfigRequest.burst_count_capacity:type_name -> dbconfig.CreateDynamicBindConfigRequest.BurstCountCapacityEntry + 8, // 3: dbconfig.UpdateDynamicBindConfigRequest.restricted_bind:type_name -> google.protobuf.BoolValue + 7, // 4: dbconfig.UpdateDynamicBindConfigRequest.burst_count_capacity:type_name -> dbconfig.UpdateDynamicBindConfigRequest.BurstCountCapacityEntry + 0, // 5: dbconfig.ListDynamicBindConfigsResponse.db_config:type_name -> dbconfig.DynamicBindConfig + 1, // 6: dbconfig.DynamicBindConfigSvc.CreateDynamicBindConfig:input_type -> dbconfig.CreateDynamicBindConfigRequest + 9, // 7: dbconfig.DynamicBindConfigSvc.GetDynamicBindConfig:input_type -> general.GetRequest + 2, // 8: dbconfig.DynamicBindConfigSvc.UpdateDynamicBindConfig:input_type -> dbconfig.UpdateDynamicBindConfigRequest + 10, // 9: dbconfig.DynamicBindConfigSvc.DeleteDynamicBindConfig:input_type -> general.ResourceId + 11, // 10: dbconfig.DynamicBindConfigSvc.DeleteCollectionDynamicBindConfig:input_type -> general.ListOptions + 11, // 11: dbconfig.DynamicBindConfigSvc.ListDynamicBindConfig:input_type -> general.ListOptions + 12, // 12: dbconfig.DynamicBindConfigSvc.CreateDynamicBindConfig:output_type -> google.protobuf.Empty + 0, // 13: dbconfig.DynamicBindConfigSvc.GetDynamicBindConfig:output_type -> dbconfig.DynamicBindConfig + 12, // 14: dbconfig.DynamicBindConfigSvc.UpdateDynamicBindConfig:output_type -> google.protobuf.Empty + 12, // 15: dbconfig.DynamicBindConfigSvc.DeleteDynamicBindConfig:output_type -> google.protobuf.Empty + 12, // 16: dbconfig.DynamicBindConfigSvc.DeleteCollectionDynamicBindConfig:output_type -> google.protobuf.Empty + 3, // 17: dbconfig.DynamicBindConfigSvc.ListDynamicBindConfig:output_type -> dbconfig.ListDynamicBindConfigsResponse + 12, // [12:18] is the sub-list for method output_type + 6, // [6:12] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_dbconfig_dbconfig_proto_init() } +func file_dbconfig_dbconfig_proto_init() { + if File_dbconfig_dbconfig_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dbconfig_dbconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DynamicBindConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dbconfig_dbconfig_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDynamicBindConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dbconfig_dbconfig_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDynamicBindConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dbconfig_dbconfig_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDynamicBindConfigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dbconfig_dbconfig_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_dbconfig_dbconfig_proto_goTypes, + DependencyIndexes: file_dbconfig_dbconfig_proto_depIdxs, + MessageInfos: file_dbconfig_dbconfig_proto_msgTypes, + }.Build() + File_dbconfig_dbconfig_proto = out.File + file_dbconfig_dbconfig_proto_rawDesc = nil + file_dbconfig_dbconfig_proto_goTypes = nil + file_dbconfig_dbconfig_proto_depIdxs = nil +} diff --git a/v3/protos/dbconfig/dbconfig.proto b/v3/protos/dbconfig/dbconfig.proto new file mode 100644 index 00000000..918c92f8 --- /dev/null +++ b/v3/protos/dbconfig/dbconfig.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package dbconfig; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/dbconfig;dbconfigpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service DynamicBindConfigSvc { + rpc CreateDynamicBindConfig (CreateDynamicBindConfigRequest) returns (google.protobuf.Empty); + rpc GetDynamicBindConfig (general.GetRequest) returns (DynamicBindConfig); + rpc UpdateDynamicBindConfig (UpdateDynamicBindConfigRequest) returns (google.protobuf.Empty); + rpc DeleteDynamicBindConfig (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionDynamicBindConfig (general.ListOptions) returns (google.protobuf.Empty); + rpc ListDynamicBindConfig (general.ListOptions) returns (ListDynamicBindConfigsResponse); +} + +message DynamicBindConfig { + string id = 1; + string uid = 2; + string environment = 3; + bool restricted_bind = 4; + string restricted_bind_value = 5; + map burst_count_capacity = 6; + map labels = 7; +} + +message CreateDynamicBindConfigRequest { + string se_name = 1; + string se_uid = 2; + string env_name = 3; + map burst_count_capacity = 4; + bool restricted_bind = 5; + string restricted_bind_value = 6; +} + +message UpdateDynamicBindConfigRequest { + string id = 1; + string environment = 2; + google.protobuf.BoolValue restricted_bind = 3; + map burst_count_capacity = 4; +} + +message ListDynamicBindConfigsResponse { + repeated DynamicBindConfig db_config = 1; +} \ No newline at end of file diff --git a/v3/protos/dbconfig/dbconfig_grpc.pb.go b/v3/protos/dbconfig/dbconfig_grpc.pb.go new file mode 100644 index 00000000..cd3501f7 --- /dev/null +++ b/v3/protos/dbconfig/dbconfig_grpc.pb.go @@ -0,0 +1,296 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: dbconfig/dbconfig.proto + +package dbconfigpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + DynamicBindConfigSvc_CreateDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/CreateDynamicBindConfig" + DynamicBindConfigSvc_GetDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/GetDynamicBindConfig" + DynamicBindConfigSvc_UpdateDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/UpdateDynamicBindConfig" + DynamicBindConfigSvc_DeleteDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/DeleteDynamicBindConfig" + DynamicBindConfigSvc_DeleteCollectionDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/DeleteCollectionDynamicBindConfig" + DynamicBindConfigSvc_ListDynamicBindConfig_FullMethodName = "/dbconfig.DynamicBindConfigSvc/ListDynamicBindConfig" +) + +// DynamicBindConfigSvcClient is the client API for DynamicBindConfigSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DynamicBindConfigSvcClient interface { + CreateDynamicBindConfig(ctx context.Context, in *CreateDynamicBindConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + GetDynamicBindConfig(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*DynamicBindConfig, error) + UpdateDynamicBindConfig(ctx context.Context, in *UpdateDynamicBindConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteDynamicBindConfig(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionDynamicBindConfig(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListDynamicBindConfig(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListDynamicBindConfigsResponse, error) +} + +type dynamicBindConfigSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewDynamicBindConfigSvcClient(cc grpc.ClientConnInterface) DynamicBindConfigSvcClient { + return &dynamicBindConfigSvcClient{cc} +} + +func (c *dynamicBindConfigSvcClient) CreateDynamicBindConfig(ctx context.Context, in *CreateDynamicBindConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_CreateDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dynamicBindConfigSvcClient) GetDynamicBindConfig(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*DynamicBindConfig, error) { + out := new(DynamicBindConfig) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_GetDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dynamicBindConfigSvcClient) UpdateDynamicBindConfig(ctx context.Context, in *UpdateDynamicBindConfigRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_UpdateDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dynamicBindConfigSvcClient) DeleteDynamicBindConfig(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_DeleteDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dynamicBindConfigSvcClient) DeleteCollectionDynamicBindConfig(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_DeleteCollectionDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dynamicBindConfigSvcClient) ListDynamicBindConfig(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListDynamicBindConfigsResponse, error) { + out := new(ListDynamicBindConfigsResponse) + err := c.cc.Invoke(ctx, DynamicBindConfigSvc_ListDynamicBindConfig_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DynamicBindConfigSvcServer is the server API for DynamicBindConfigSvc service. +// All implementations must embed UnimplementedDynamicBindConfigSvcServer +// for forward compatibility +type DynamicBindConfigSvcServer interface { + CreateDynamicBindConfig(context.Context, *CreateDynamicBindConfigRequest) (*emptypb.Empty, error) + GetDynamicBindConfig(context.Context, *general.GetRequest) (*DynamicBindConfig, error) + UpdateDynamicBindConfig(context.Context, *UpdateDynamicBindConfigRequest) (*emptypb.Empty, error) + DeleteDynamicBindConfig(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionDynamicBindConfig(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListDynamicBindConfig(context.Context, *general.ListOptions) (*ListDynamicBindConfigsResponse, error) + mustEmbedUnimplementedDynamicBindConfigSvcServer() +} + +// UnimplementedDynamicBindConfigSvcServer must be embedded to have forward compatible implementations. +type UnimplementedDynamicBindConfigSvcServer struct { +} + +func (UnimplementedDynamicBindConfigSvcServer) CreateDynamicBindConfig(context.Context, *CreateDynamicBindConfigRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) GetDynamicBindConfig(context.Context, *general.GetRequest) (*DynamicBindConfig, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) UpdateDynamicBindConfig(context.Context, *UpdateDynamicBindConfigRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) DeleteDynamicBindConfig(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) DeleteCollectionDynamicBindConfig(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) ListDynamicBindConfig(context.Context, *general.ListOptions) (*ListDynamicBindConfigsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListDynamicBindConfig not implemented") +} +func (UnimplementedDynamicBindConfigSvcServer) mustEmbedUnimplementedDynamicBindConfigSvcServer() {} + +// UnsafeDynamicBindConfigSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DynamicBindConfigSvcServer will +// result in compilation errors. +type UnsafeDynamicBindConfigSvcServer interface { + mustEmbedUnimplementedDynamicBindConfigSvcServer() +} + +func RegisterDynamicBindConfigSvcServer(s grpc.ServiceRegistrar, srv DynamicBindConfigSvcServer) { + s.RegisterService(&DynamicBindConfigSvc_ServiceDesc, srv) +} + +func _DynamicBindConfigSvc_CreateDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateDynamicBindConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).CreateDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_CreateDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).CreateDynamicBindConfig(ctx, req.(*CreateDynamicBindConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DynamicBindConfigSvc_GetDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).GetDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_GetDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).GetDynamicBindConfig(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DynamicBindConfigSvc_UpdateDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateDynamicBindConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).UpdateDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_UpdateDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).UpdateDynamicBindConfig(ctx, req.(*UpdateDynamicBindConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DynamicBindConfigSvc_DeleteDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).DeleteDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_DeleteDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).DeleteDynamicBindConfig(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _DynamicBindConfigSvc_DeleteCollectionDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).DeleteCollectionDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_DeleteCollectionDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).DeleteCollectionDynamicBindConfig(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _DynamicBindConfigSvc_ListDynamicBindConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DynamicBindConfigSvcServer).ListDynamicBindConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DynamicBindConfigSvc_ListDynamicBindConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DynamicBindConfigSvcServer).ListDynamicBindConfig(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// DynamicBindConfigSvc_ServiceDesc is the grpc.ServiceDesc for DynamicBindConfigSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DynamicBindConfigSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dbconfig.DynamicBindConfigSvc", + HandlerType: (*DynamicBindConfigSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateDynamicBindConfig", + Handler: _DynamicBindConfigSvc_CreateDynamicBindConfig_Handler, + }, + { + MethodName: "GetDynamicBindConfig", + Handler: _DynamicBindConfigSvc_GetDynamicBindConfig_Handler, + }, + { + MethodName: "UpdateDynamicBindConfig", + Handler: _DynamicBindConfigSvc_UpdateDynamicBindConfig_Handler, + }, + { + MethodName: "DeleteDynamicBindConfig", + Handler: _DynamicBindConfigSvc_DeleteDynamicBindConfig_Handler, + }, + { + MethodName: "DeleteCollectionDynamicBindConfig", + Handler: _DynamicBindConfigSvc_DeleteCollectionDynamicBindConfig_Handler, + }, + { + MethodName: "ListDynamicBindConfig", + Handler: _DynamicBindConfigSvc_ListDynamicBindConfig_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dbconfig/dbconfig.proto", +} diff --git a/v3/protos/environment/environment.pb.go b/v3/protos/environment/environment.pb.go new file mode 100644 index 00000000..d2711185 --- /dev/null +++ b/v3/protos/environment/environment.pb.go @@ -0,0 +1,705 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: environment/environment.proto + +package environmentpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Environment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Dnssuffix string `protobuf:"bytes,4,opt,name=dnssuffix,proto3" json:"dnssuffix,omitempty"` + Provider string `protobuf:"bytes,5,opt,name=provider,proto3" json:"provider,omitempty"` + TemplateMapping map[string]*general.StringMap `protobuf:"bytes,6,rep,name=template_mapping,json=templateMapping,proto3" json:"template_mapping,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + EnvironmentSpecifics map[string]string `protobuf:"bytes,7,rep,name=environment_specifics,json=environmentSpecifics,proto3" json:"environment_specifics,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + IpTranslationMap map[string]string `protobuf:"bytes,8,rep,name=ip_translation_map,json=ipTranslationMap,proto3" json:"ip_translation_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + WsEndpoint string `protobuf:"bytes,9,opt,name=ws_endpoint,json=wsEndpoint,proto3" json:"ws_endpoint,omitempty"` + CountCapacity map[string]uint32 `protobuf:"bytes,10,rep,name=count_capacity,json=countCapacity,proto3" json:"count_capacity,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Annotations map[string]string `protobuf:"bytes,11,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Environment) Reset() { + *x = Environment{} + if protoimpl.UnsafeEnabled { + mi := &file_environment_environment_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Environment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Environment) ProtoMessage() {} + +func (x *Environment) ProtoReflect() protoreflect.Message { + mi := &file_environment_environment_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Environment.ProtoReflect.Descriptor instead. +func (*Environment) Descriptor() ([]byte, []int) { + return file_environment_environment_proto_rawDescGZIP(), []int{0} +} + +func (x *Environment) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Environment) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *Environment) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *Environment) GetDnssuffix() string { + if x != nil { + return x.Dnssuffix + } + return "" +} + +func (x *Environment) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *Environment) GetTemplateMapping() map[string]*general.StringMap { + if x != nil { + return x.TemplateMapping + } + return nil +} + +func (x *Environment) GetEnvironmentSpecifics() map[string]string { + if x != nil { + return x.EnvironmentSpecifics + } + return nil +} + +func (x *Environment) GetIpTranslationMap() map[string]string { + if x != nil { + return x.IpTranslationMap + } + return nil +} + +func (x *Environment) GetWsEndpoint() string { + if x != nil { + return x.WsEndpoint + } + return "" +} + +func (x *Environment) GetCountCapacity() map[string]uint32 { + if x != nil { + return x.CountCapacity + } + return nil +} + +func (x *Environment) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +type CreateEnvironmentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Dnssuffix string `protobuf:"bytes,2,opt,name=dnssuffix,proto3" json:"dnssuffix,omitempty"` + Provider string `protobuf:"bytes,3,opt,name=provider,proto3" json:"provider,omitempty"` + TemplateMapping string `protobuf:"bytes,4,opt,name=template_mapping,json=templateMapping,proto3" json:"template_mapping,omitempty"` + EnvironmentSpecifics string `protobuf:"bytes,5,opt,name=environment_specifics,json=environmentSpecifics,proto3" json:"environment_specifics,omitempty"` + IpTranslationMap string `protobuf:"bytes,6,opt,name=ip_translation_map,json=ipTranslationMap,proto3" json:"ip_translation_map,omitempty"` + WsEndpoint string `protobuf:"bytes,7,opt,name=ws_endpoint,json=wsEndpoint,proto3" json:"ws_endpoint,omitempty"` + CountCapacity string `protobuf:"bytes,8,opt,name=count_capacity,json=countCapacity,proto3" json:"count_capacity,omitempty"` +} + +func (x *CreateEnvironmentRequest) Reset() { + *x = CreateEnvironmentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_environment_environment_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateEnvironmentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateEnvironmentRequest) ProtoMessage() {} + +func (x *CreateEnvironmentRequest) ProtoReflect() protoreflect.Message { + mi := &file_environment_environment_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateEnvironmentRequest.ProtoReflect.Descriptor instead. +func (*CreateEnvironmentRequest) Descriptor() ([]byte, []int) { + return file_environment_environment_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateEnvironmentRequest) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *CreateEnvironmentRequest) GetDnssuffix() string { + if x != nil { + return x.Dnssuffix + } + return "" +} + +func (x *CreateEnvironmentRequest) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *CreateEnvironmentRequest) GetTemplateMapping() string { + if x != nil { + return x.TemplateMapping + } + return "" +} + +func (x *CreateEnvironmentRequest) GetEnvironmentSpecifics() string { + if x != nil { + return x.EnvironmentSpecifics + } + return "" +} + +func (x *CreateEnvironmentRequest) GetIpTranslationMap() string { + if x != nil { + return x.IpTranslationMap + } + return "" +} + +func (x *CreateEnvironmentRequest) GetWsEndpoint() string { + if x != nil { + return x.WsEndpoint + } + return "" +} + +func (x *CreateEnvironmentRequest) GetCountCapacity() string { + if x != nil { + return x.CountCapacity + } + return "" +} + +type UpdateEnvironmentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Dnssuffix *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=dnssuffix,proto3" json:"dnssuffix,omitempty"` // optional + Provider string `protobuf:"bytes,4,opt,name=provider,proto3" json:"provider,omitempty"` + TemplateMapping string `protobuf:"bytes,5,opt,name=template_mapping,json=templateMapping,proto3" json:"template_mapping,omitempty"` + EnvironmentSpecifics string `protobuf:"bytes,6,opt,name=environment_specifics,json=environmentSpecifics,proto3" json:"environment_specifics,omitempty"` + IpTranslationMap string `protobuf:"bytes,7,opt,name=ip_translation_map,json=ipTranslationMap,proto3" json:"ip_translation_map,omitempty"` + WsEndpoint string `protobuf:"bytes,8,opt,name=ws_endpoint,json=wsEndpoint,proto3" json:"ws_endpoint,omitempty"` + CountCapacity string `protobuf:"bytes,9,opt,name=count_capacity,json=countCapacity,proto3" json:"count_capacity,omitempty"` +} + +func (x *UpdateEnvironmentRequest) Reset() { + *x = UpdateEnvironmentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_environment_environment_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateEnvironmentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateEnvironmentRequest) ProtoMessage() {} + +func (x *UpdateEnvironmentRequest) ProtoReflect() protoreflect.Message { + mi := &file_environment_environment_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateEnvironmentRequest.ProtoReflect.Descriptor instead. +func (*UpdateEnvironmentRequest) Descriptor() ([]byte, []int) { + return file_environment_environment_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateEnvironmentRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetDnssuffix() *wrapperspb.StringValue { + if x != nil { + return x.Dnssuffix + } + return nil +} + +func (x *UpdateEnvironmentRequest) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetTemplateMapping() string { + if x != nil { + return x.TemplateMapping + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetEnvironmentSpecifics() string { + if x != nil { + return x.EnvironmentSpecifics + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetIpTranslationMap() string { + if x != nil { + return x.IpTranslationMap + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetWsEndpoint() string { + if x != nil { + return x.WsEndpoint + } + return "" +} + +func (x *UpdateEnvironmentRequest) GetCountCapacity() string { + if x != nil { + return x.CountCapacity + } + return "" +} + +type ListEnvironmentsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Environments []*Environment `protobuf:"bytes,1,rep,name=environments,proto3" json:"environments,omitempty"` +} + +func (x *ListEnvironmentsResponse) Reset() { + *x = ListEnvironmentsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_environment_environment_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListEnvironmentsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListEnvironmentsResponse) ProtoMessage() {} + +func (x *ListEnvironmentsResponse) ProtoReflect() protoreflect.Message { + mi := &file_environment_environment_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListEnvironmentsResponse.ProtoReflect.Descriptor instead. +func (*ListEnvironmentsResponse) Descriptor() ([]byte, []int) { + return file_environment_environment_proto_rawDescGZIP(), []int{3} +} + +func (x *ListEnvironmentsResponse) GetEnvironments() []*Environment { + if x != nil { + return x.Environments + } + return nil +} + +var File_environment_environment_proto protoreflect.FileDescriptor + +var file_environment_environment_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x65, 0x6e, + 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x15, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xd7, 0x07, 0x0a, 0x0b, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x73, 0x75, 0x66, 0x66, + 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x6e, 0x73, 0x73, 0x75, 0x66, + 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x58, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, + 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, + 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x73, 0x12, 0x5c, 0x0a, 0x12, 0x69, 0x70, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, + 0x69, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x70, + 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x73, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x52, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x4b, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x56, 0x0a, 0x14, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, + 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x49, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x40, 0x0a, 0x12, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcd, 0x02, 0x0a, 0x18, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x6e, + 0x73, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, + 0x6e, 0x73, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, + 0x33, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, + 0x66, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x70, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x69, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x73, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x22, 0xfb, 0x02, 0x0a, 0x18, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x64, 0x6e, + 0x73, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6e, 0x73, + 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, + 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x63, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x65, 0x6e, + 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x70, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x69, 0x70, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x70, + 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x73, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x43, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x22, 0x58, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x32, 0xd5, 0x03, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x76, 0x63, 0x12, 0x4f, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x65, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x52, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x65, + 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x40, 0x0a, 0x11, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4b, 0x0a, + 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x25, 0x2e, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, + 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x3b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_environment_environment_proto_rawDescOnce sync.Once + file_environment_environment_proto_rawDescData = file_environment_environment_proto_rawDesc +) + +func file_environment_environment_proto_rawDescGZIP() []byte { + file_environment_environment_proto_rawDescOnce.Do(func() { + file_environment_environment_proto_rawDescData = protoimpl.X.CompressGZIP(file_environment_environment_proto_rawDescData) + }) + return file_environment_environment_proto_rawDescData +} + +var file_environment_environment_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_environment_environment_proto_goTypes = []interface{}{ + (*Environment)(nil), // 0: environment.Environment + (*CreateEnvironmentRequest)(nil), // 1: environment.CreateEnvironmentRequest + (*UpdateEnvironmentRequest)(nil), // 2: environment.UpdateEnvironmentRequest + (*ListEnvironmentsResponse)(nil), // 3: environment.ListEnvironmentsResponse + nil, // 4: environment.Environment.TemplateMappingEntry + nil, // 5: environment.Environment.EnvironmentSpecificsEntry + nil, // 6: environment.Environment.IpTranslationMapEntry + nil, // 7: environment.Environment.CountCapacityEntry + nil, // 8: environment.Environment.AnnotationsEntry + (*wrapperspb.StringValue)(nil), // 9: google.protobuf.StringValue + (*general.StringMap)(nil), // 10: general.StringMap + (*general.GetRequest)(nil), // 11: general.GetRequest + (*general.ResourceId)(nil), // 12: general.ResourceId + (*general.ListOptions)(nil), // 13: general.ListOptions + (*emptypb.Empty)(nil), // 14: google.protobuf.Empty +} +var file_environment_environment_proto_depIdxs = []int32{ + 4, // 0: environment.Environment.template_mapping:type_name -> environment.Environment.TemplateMappingEntry + 5, // 1: environment.Environment.environment_specifics:type_name -> environment.Environment.EnvironmentSpecificsEntry + 6, // 2: environment.Environment.ip_translation_map:type_name -> environment.Environment.IpTranslationMapEntry + 7, // 3: environment.Environment.count_capacity:type_name -> environment.Environment.CountCapacityEntry + 8, // 4: environment.Environment.annotations:type_name -> environment.Environment.AnnotationsEntry + 9, // 5: environment.UpdateEnvironmentRequest.dnssuffix:type_name -> google.protobuf.StringValue + 0, // 6: environment.ListEnvironmentsResponse.environments:type_name -> environment.Environment + 10, // 7: environment.Environment.TemplateMappingEntry.value:type_name -> general.StringMap + 1, // 8: environment.EnvironmentSvc.CreateEnvironment:input_type -> environment.CreateEnvironmentRequest + 11, // 9: environment.EnvironmentSvc.GetEnvironment:input_type -> general.GetRequest + 2, // 10: environment.EnvironmentSvc.UpdateEnvironment:input_type -> environment.UpdateEnvironmentRequest + 12, // 11: environment.EnvironmentSvc.DeleteEnvironment:input_type -> general.ResourceId + 13, // 12: environment.EnvironmentSvc.DeleteCollectionEnvironment:input_type -> general.ListOptions + 13, // 13: environment.EnvironmentSvc.ListEnvironment:input_type -> general.ListOptions + 12, // 14: environment.EnvironmentSvc.CreateEnvironment:output_type -> general.ResourceId + 0, // 15: environment.EnvironmentSvc.GetEnvironment:output_type -> environment.Environment + 14, // 16: environment.EnvironmentSvc.UpdateEnvironment:output_type -> google.protobuf.Empty + 14, // 17: environment.EnvironmentSvc.DeleteEnvironment:output_type -> google.protobuf.Empty + 14, // 18: environment.EnvironmentSvc.DeleteCollectionEnvironment:output_type -> google.protobuf.Empty + 3, // 19: environment.EnvironmentSvc.ListEnvironment:output_type -> environment.ListEnvironmentsResponse + 14, // [14:20] is the sub-list for method output_type + 8, // [8:14] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_environment_environment_proto_init() } +func file_environment_environment_proto_init() { + if File_environment_environment_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_environment_environment_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Environment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_environment_environment_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateEnvironmentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_environment_environment_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateEnvironmentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_environment_environment_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListEnvironmentsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_environment_environment_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_environment_environment_proto_goTypes, + DependencyIndexes: file_environment_environment_proto_depIdxs, + MessageInfos: file_environment_environment_proto_msgTypes, + }.Build() + File_environment_environment_proto = out.File + file_environment_environment_proto_rawDesc = nil + file_environment_environment_proto_goTypes = nil + file_environment_environment_proto_depIdxs = nil +} diff --git a/v3/protos/environment/environment.proto b/v3/protos/environment/environment.proto new file mode 100644 index 00000000..36a7c579 --- /dev/null +++ b/v3/protos/environment/environment.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +package environment; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/environment;environmentpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service EnvironmentSvc { + rpc CreateEnvironment (CreateEnvironmentRequest) returns (general.ResourceId); + rpc GetEnvironment (general.GetRequest) returns (Environment); + rpc UpdateEnvironment (UpdateEnvironmentRequest) returns (google.protobuf.Empty); + rpc DeleteEnvironment (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionEnvironment (general.ListOptions) returns (google.protobuf.Empty); + rpc ListEnvironment (general.ListOptions) returns (ListEnvironmentsResponse); +} + +message Environment { + string id = 1; + string uid = 2; + string display_name = 3; + string dnssuffix = 4; + string provider = 5; + map template_mapping = 6; + map environment_specifics = 7; + map ip_translation_map = 8; + string ws_endpoint = 9; + map count_capacity = 10; + map annotations = 11; +} + +message CreateEnvironmentRequest { + string display_name = 1; + string dnssuffix = 2; + string provider = 3; + string template_mapping = 4; + string environment_specifics = 5; + string ip_translation_map = 6; + string ws_endpoint = 7; + string count_capacity = 8; +} + +message UpdateEnvironmentRequest { + string id = 1; + string display_name = 2; + google.protobuf.StringValue dnssuffix = 3; // optional + string provider = 4; + string template_mapping = 5; + string environment_specifics = 6; + string ip_translation_map = 7; + string ws_endpoint = 8; + string count_capacity = 9; +} + +message ListEnvironmentsResponse { + repeated Environment environments = 1; +} \ No newline at end of file diff --git a/v3/protos/environment/environment_grpc.pb.go b/v3/protos/environment/environment_grpc.pb.go new file mode 100644 index 00000000..8966df71 --- /dev/null +++ b/v3/protos/environment/environment_grpc.pb.go @@ -0,0 +1,296 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: environment/environment.proto + +package environmentpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + EnvironmentSvc_CreateEnvironment_FullMethodName = "/environment.EnvironmentSvc/CreateEnvironment" + EnvironmentSvc_GetEnvironment_FullMethodName = "/environment.EnvironmentSvc/GetEnvironment" + EnvironmentSvc_UpdateEnvironment_FullMethodName = "/environment.EnvironmentSvc/UpdateEnvironment" + EnvironmentSvc_DeleteEnvironment_FullMethodName = "/environment.EnvironmentSvc/DeleteEnvironment" + EnvironmentSvc_DeleteCollectionEnvironment_FullMethodName = "/environment.EnvironmentSvc/DeleteCollectionEnvironment" + EnvironmentSvc_ListEnvironment_FullMethodName = "/environment.EnvironmentSvc/ListEnvironment" +) + +// EnvironmentSvcClient is the client API for EnvironmentSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type EnvironmentSvcClient interface { + CreateEnvironment(ctx context.Context, in *CreateEnvironmentRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetEnvironment(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Environment, error) + UpdateEnvironment(ctx context.Context, in *UpdateEnvironmentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteEnvironment(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionEnvironment(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListEnvironment(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListEnvironmentsResponse, error) +} + +type environmentSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewEnvironmentSvcClient(cc grpc.ClientConnInterface) EnvironmentSvcClient { + return &environmentSvcClient{cc} +} + +func (c *environmentSvcClient) CreateEnvironment(ctx context.Context, in *CreateEnvironmentRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, EnvironmentSvc_CreateEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *environmentSvcClient) GetEnvironment(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Environment, error) { + out := new(Environment) + err := c.cc.Invoke(ctx, EnvironmentSvc_GetEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *environmentSvcClient) UpdateEnvironment(ctx context.Context, in *UpdateEnvironmentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, EnvironmentSvc_UpdateEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *environmentSvcClient) DeleteEnvironment(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, EnvironmentSvc_DeleteEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *environmentSvcClient) DeleteCollectionEnvironment(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, EnvironmentSvc_DeleteCollectionEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *environmentSvcClient) ListEnvironment(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListEnvironmentsResponse, error) { + out := new(ListEnvironmentsResponse) + err := c.cc.Invoke(ctx, EnvironmentSvc_ListEnvironment_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EnvironmentSvcServer is the server API for EnvironmentSvc service. +// All implementations must embed UnimplementedEnvironmentSvcServer +// for forward compatibility +type EnvironmentSvcServer interface { + CreateEnvironment(context.Context, *CreateEnvironmentRequest) (*general.ResourceId, error) + GetEnvironment(context.Context, *general.GetRequest) (*Environment, error) + UpdateEnvironment(context.Context, *UpdateEnvironmentRequest) (*emptypb.Empty, error) + DeleteEnvironment(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionEnvironment(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListEnvironment(context.Context, *general.ListOptions) (*ListEnvironmentsResponse, error) + mustEmbedUnimplementedEnvironmentSvcServer() +} + +// UnimplementedEnvironmentSvcServer must be embedded to have forward compatible implementations. +type UnimplementedEnvironmentSvcServer struct { +} + +func (UnimplementedEnvironmentSvcServer) CreateEnvironment(context.Context, *CreateEnvironmentRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) GetEnvironment(context.Context, *general.GetRequest) (*Environment, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) UpdateEnvironment(context.Context, *UpdateEnvironmentRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) DeleteEnvironment(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) DeleteCollectionEnvironment(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) ListEnvironment(context.Context, *general.ListOptions) (*ListEnvironmentsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListEnvironment not implemented") +} +func (UnimplementedEnvironmentSvcServer) mustEmbedUnimplementedEnvironmentSvcServer() {} + +// UnsafeEnvironmentSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EnvironmentSvcServer will +// result in compilation errors. +type UnsafeEnvironmentSvcServer interface { + mustEmbedUnimplementedEnvironmentSvcServer() +} + +func RegisterEnvironmentSvcServer(s grpc.ServiceRegistrar, srv EnvironmentSvcServer) { + s.RegisterService(&EnvironmentSvc_ServiceDesc, srv) +} + +func _EnvironmentSvc_CreateEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateEnvironmentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).CreateEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_CreateEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).CreateEnvironment(ctx, req.(*CreateEnvironmentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _EnvironmentSvc_GetEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).GetEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_GetEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).GetEnvironment(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _EnvironmentSvc_UpdateEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateEnvironmentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).UpdateEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_UpdateEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).UpdateEnvironment(ctx, req.(*UpdateEnvironmentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _EnvironmentSvc_DeleteEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).DeleteEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_DeleteEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).DeleteEnvironment(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _EnvironmentSvc_DeleteCollectionEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).DeleteCollectionEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_DeleteCollectionEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).DeleteCollectionEnvironment(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _EnvironmentSvc_ListEnvironment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EnvironmentSvcServer).ListEnvironment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EnvironmentSvc_ListEnvironment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EnvironmentSvcServer).ListEnvironment(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// EnvironmentSvc_ServiceDesc is the grpc.ServiceDesc for EnvironmentSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EnvironmentSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "environment.EnvironmentSvc", + HandlerType: (*EnvironmentSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateEnvironment", + Handler: _EnvironmentSvc_CreateEnvironment_Handler, + }, + { + MethodName: "GetEnvironment", + Handler: _EnvironmentSvc_GetEnvironment_Handler, + }, + { + MethodName: "UpdateEnvironment", + Handler: _EnvironmentSvc_UpdateEnvironment_Handler, + }, + { + MethodName: "DeleteEnvironment", + Handler: _EnvironmentSvc_DeleteEnvironment_Handler, + }, + { + MethodName: "DeleteCollectionEnvironment", + Handler: _EnvironmentSvc_DeleteCollectionEnvironment_Handler, + }, + { + MethodName: "ListEnvironment", + Handler: _EnvironmentSvc_ListEnvironment_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "environment/environment.proto", +} diff --git a/v3/protos/general/general.pb.go b/v3/protos/general/general.pb.go new file mode 100644 index 00000000..19860352 --- /dev/null +++ b/v3/protos/general/general.pb.go @@ -0,0 +1,614 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: general/general.proto + +package generalpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ResourceId struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ResourceId) Reset() { + *x = ResourceId{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceId) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceId) ProtoMessage() {} + +func (x *ResourceId) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceId.ProtoReflect.Descriptor instead. +func (*ResourceId) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{0} +} + +func (x *ResourceId) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + LoadFromCache bool `protobuf:"varint,2,opt,name=load_from_cache,json=loadFromCache,proto3" json:"load_from_cache,omitempty"` +} + +func (x *GetRequest) Reset() { + *x = GetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRequest) ProtoMessage() {} + +func (x *GetRequest) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRequest.ProtoReflect.Descriptor instead. +func (*GetRequest) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{1} +} + +func (x *GetRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetRequest) GetLoadFromCache() bool { + if x != nil { + return x.LoadFromCache + } + return false +} + +type ListOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LabelSelector string `protobuf:"bytes,1,opt,name=label_selector,json=labelSelector,proto3" json:"label_selector,omitempty"` + LoadFromCache bool `protobuf:"varint,2,opt,name=load_from_cache,json=loadFromCache,proto3" json:"load_from_cache,omitempty"` +} + +func (x *ListOptions) Reset() { + *x = ListOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOptions) ProtoMessage() {} + +func (x *ListOptions) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListOptions.ProtoReflect.Descriptor instead. +func (*ListOptions) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{2} +} + +func (x *ListOptions) GetLabelSelector() string { + if x != nil { + return x.LabelSelector + } + return "" +} + +func (x *ListOptions) GetLoadFromCache() bool { + if x != nil { + return x.LoadFromCache + } + return false +} + +type OwnerReference struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ApiVersion string `protobuf:"bytes,1,opt,name=api_version,json=apiVersion,proto3" json:"api_version,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,4,opt,name=uid,proto3" json:"uid,omitempty"` + Controller *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=controller,proto3" json:"controller,omitempty"` + BlockOwnerDeletion *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=block_owner_deletion,json=blockOwnerDeletion,proto3" json:"block_owner_deletion,omitempty"` +} + +func (x *OwnerReference) Reset() { + *x = OwnerReference{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OwnerReference) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OwnerReference) ProtoMessage() {} + +func (x *OwnerReference) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OwnerReference.ProtoReflect.Descriptor instead. +func (*OwnerReference) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{3} +} + +func (x *OwnerReference) GetApiVersion() string { + if x != nil { + return x.ApiVersion + } + return "" +} + +func (x *OwnerReference) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *OwnerReference) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *OwnerReference) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *OwnerReference) GetController() *wrapperspb.BoolValue { + if x != nil { + return x.Controller + } + return nil +} + +func (x *OwnerReference) GetBlockOwnerDeletion() *wrapperspb.BoolValue { + if x != nil { + return x.BlockOwnerDeletion + } + return nil +} + +type OwnerReferences struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OwnerReferences []*OwnerReference `protobuf:"bytes,1,rep,name=owner_references,json=ownerReferences,proto3" json:"owner_references,omitempty"` +} + +func (x *OwnerReferences) Reset() { + *x = OwnerReferences{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OwnerReferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OwnerReferences) ProtoMessage() {} + +func (x *OwnerReferences) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OwnerReferences.ProtoReflect.Descriptor instead. +func (*OwnerReferences) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{4} +} + +func (x *OwnerReferences) GetOwnerReferences() []*OwnerReference { + if x != nil { + return x.OwnerReferences + } + return nil +} + +// Since it is not possible to define an array of maps or a map of maps in protobuf, +// let's define a wrapper proto message type for string maps +type StringMap struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value map[string]string `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *StringMap) Reset() { + *x = StringMap{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StringMap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringMap) ProtoMessage() {} + +func (x *StringMap) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringMap.ProtoReflect.Descriptor instead. +func (*StringMap) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{5} +} + +func (x *StringMap) GetValue() map[string]string { + if x != nil { + return x.Value + } + return nil +} + +// A wrapper for string slices in case we need to differ between an empty and unset slice +type StringArray struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` +} + +func (x *StringArray) Reset() { + *x = StringArray{} + if protoimpl.UnsafeEnabled { + mi := &file_general_general_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StringArray) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringArray) ProtoMessage() {} + +func (x *StringArray) ProtoReflect() protoreflect.Message { + mi := &file_general_general_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringArray.ProtoReflect.Descriptor instead. +func (*StringArray) Descriptor() ([]byte, []int) { + return file_general_general_proto_rawDescGZIP(), []int{6} +} + +func (x *StringArray) GetValues() []string { + if x != nil { + return x.Values + } + return nil +} + +var File_general_general_proto protoreflect.FileDescriptor + +var file_general_general_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x44, + 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0f, + 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x22, 0x5c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x22, 0xf1, 0x01, 0x0a, 0x0e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x3a, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x14, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, 0x0f, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x10, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4f, 0x77, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x7a, 0x0a, + 0x09, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0x38, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x25, 0x0a, 0x0b, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, + 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, + 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x3b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_general_general_proto_rawDescOnce sync.Once + file_general_general_proto_rawDescData = file_general_general_proto_rawDesc +) + +func file_general_general_proto_rawDescGZIP() []byte { + file_general_general_proto_rawDescOnce.Do(func() { + file_general_general_proto_rawDescData = protoimpl.X.CompressGZIP(file_general_general_proto_rawDescData) + }) + return file_general_general_proto_rawDescData +} + +var file_general_general_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_general_general_proto_goTypes = []interface{}{ + (*ResourceId)(nil), // 0: general.ResourceId + (*GetRequest)(nil), // 1: general.GetRequest + (*ListOptions)(nil), // 2: general.ListOptions + (*OwnerReference)(nil), // 3: general.OwnerReference + (*OwnerReferences)(nil), // 4: general.OwnerReferences + (*StringMap)(nil), // 5: general.StringMap + (*StringArray)(nil), // 6: general.StringArray + nil, // 7: general.StringMap.ValueEntry + (*wrapperspb.BoolValue)(nil), // 8: google.protobuf.BoolValue +} +var file_general_general_proto_depIdxs = []int32{ + 8, // 0: general.OwnerReference.controller:type_name -> google.protobuf.BoolValue + 8, // 1: general.OwnerReference.block_owner_deletion:type_name -> google.protobuf.BoolValue + 3, // 2: general.OwnerReferences.owner_references:type_name -> general.OwnerReference + 7, // 3: general.StringMap.value:type_name -> general.StringMap.ValueEntry + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_general_general_proto_init() } +func file_general_general_proto_init() { + if File_general_general_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_general_general_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceId); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OwnerReference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OwnerReferences); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StringMap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_general_general_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StringArray); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_general_general_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_general_general_proto_goTypes, + DependencyIndexes: file_general_general_proto_depIdxs, + MessageInfos: file_general_general_proto_msgTypes, + }.Build() + File_general_general_proto = out.File + file_general_general_proto_rawDesc = nil + file_general_general_proto_goTypes = nil + file_general_general_proto_depIdxs = nil +} diff --git a/v3/protos/general/general.proto b/v3/protos/general/general.proto new file mode 100644 index 00000000..49c00223 --- /dev/null +++ b/v3/protos/general/general.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package general; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/general;generalpb"; + +import "google/protobuf/wrappers.proto"; + +// messages which are used across multiple services should be defined here + +message ResourceId { + string id = 1; +} + +message GetRequest { + string id = 1; + bool load_from_cache = 2; +} + +message ListOptions { + string label_selector = 1; + bool load_from_cache = 2; +} + +message OwnerReference { + string api_version = 1; + string kind = 2; + string id = 3; + string uid = 4; + google.protobuf.BoolValue controller = 5; + google.protobuf.BoolValue block_owner_deletion = 6; +} + +message OwnerReferences { + repeated OwnerReference owner_references = 1; +} + +// Since it is not possible to define an array of maps or a map of maps in protobuf, +// let's define a wrapper proto message type for string maps +message StringMap { + map value = 1; +} + +// A wrapper for string slices in case we need to differ between an empty and unset slice +message StringArray { + repeated string values = 1; +} \ No newline at end of file diff --git a/v3/protos/progress/progress.pb.go b/v3/protos/progress/progress.pb.go new file mode 100644 index 00000000..1acba57c --- /dev/null +++ b/v3/protos/progress/progress.pb.go @@ -0,0 +1,884 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: progress/progress.proto + +package progresspb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CreateProgressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CurrentStep uint32 `protobuf:"varint,1,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + MaxStep uint32 `protobuf:"varint,2,opt,name=max_step,json=maxStep,proto3" json:"max_step,omitempty"` + TotalStep uint32 `protobuf:"varint,3,opt,name=total_step,json=totalStep,proto3" json:"total_step,omitempty"` + Scenario string `protobuf:"bytes,4,opt,name=scenario,proto3" json:"scenario,omitempty"` + Course string `protobuf:"bytes,5,opt,name=course,proto3" json:"course,omitempty"` + User string `protobuf:"bytes,6,opt,name=user,proto3" json:"user,omitempty"` + Labels map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CreateProgressRequest) Reset() { + *x = CreateProgressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateProgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateProgressRequest) ProtoMessage() {} + +func (x *CreateProgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateProgressRequest.ProtoReflect.Descriptor instead. +func (*CreateProgressRequest) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateProgressRequest) GetCurrentStep() uint32 { + if x != nil { + return x.CurrentStep + } + return 0 +} + +func (x *CreateProgressRequest) GetMaxStep() uint32 { + if x != nil { + return x.MaxStep + } + return 0 +} + +func (x *CreateProgressRequest) GetTotalStep() uint32 { + if x != nil { + return x.TotalStep + } + return 0 +} + +func (x *CreateProgressRequest) GetScenario() string { + if x != nil { + return x.Scenario + } + return "" +} + +func (x *CreateProgressRequest) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *CreateProgressRequest) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *CreateProgressRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type Progress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + CurrentStep uint32 `protobuf:"varint,3,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + MaxStep uint32 `protobuf:"varint,4,opt,name=max_step,json=maxStep,proto3" json:"max_step,omitempty"` + TotalStep uint32 `protobuf:"varint,5,opt,name=total_step,json=totalStep,proto3" json:"total_step,omitempty"` + Scenario string `protobuf:"bytes,6,opt,name=scenario,proto3" json:"scenario,omitempty"` + Course string `protobuf:"bytes,7,opt,name=course,proto3" json:"course,omitempty"` + User string `protobuf:"bytes,8,opt,name=user,proto3" json:"user,omitempty"` + Started string `protobuf:"bytes,9,opt,name=started,proto3" json:"started,omitempty"` + LastUpdate string `protobuf:"bytes,10,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"` + Finished string `protobuf:"bytes,11,opt,name=finished,proto3" json:"finished,omitempty"` + Steps []*ProgressStep `protobuf:"bytes,12,rep,name=steps,proto3" json:"steps,omitempty"` + Labels map[string]string `protobuf:"bytes,13,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CreationTimestamp *timestamppb.Timestamp `protobuf:"bytes,14,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` +} + +func (x *Progress) Reset() { + *x = Progress{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Progress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Progress) ProtoMessage() {} + +func (x *Progress) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Progress.ProtoReflect.Descriptor instead. +func (*Progress) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{1} +} + +func (x *Progress) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Progress) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *Progress) GetCurrentStep() uint32 { + if x != nil { + return x.CurrentStep + } + return 0 +} + +func (x *Progress) GetMaxStep() uint32 { + if x != nil { + return x.MaxStep + } + return 0 +} + +func (x *Progress) GetTotalStep() uint32 { + if x != nil { + return x.TotalStep + } + return 0 +} + +func (x *Progress) GetScenario() string { + if x != nil { + return x.Scenario + } + return "" +} + +func (x *Progress) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *Progress) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *Progress) GetStarted() string { + if x != nil { + return x.Started + } + return "" +} + +func (x *Progress) GetLastUpdate() string { + if x != nil { + return x.LastUpdate + } + return "" +} + +func (x *Progress) GetFinished() string { + if x != nil { + return x.Finished + } + return "" +} + +func (x *Progress) GetSteps() []*ProgressStep { + if x != nil { + return x.Steps + } + return nil +} + +func (x *Progress) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Progress) GetCreationTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.CreationTimestamp + } + return nil +} + +type ProgressStep struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Step uint32 `protobuf:"varint,1,opt,name=step,proto3" json:"step,omitempty"` + Timestamp string `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *ProgressStep) Reset() { + *x = ProgressStep{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProgressStep) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProgressStep) ProtoMessage() {} + +func (x *ProgressStep) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProgressStep.ProtoReflect.Descriptor instead. +func (*ProgressStep) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{2} +} + +func (x *ProgressStep) GetStep() uint32 { + if x != nil { + return x.Step + } + return 0 +} + +func (x *ProgressStep) GetTimestamp() string { + if x != nil { + return x.Timestamp + } + return "" +} + +type UpdateProgressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + CurrentStep *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + MaxStep *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=max_step,json=maxStep,proto3" json:"max_step,omitempty"` + TotalStep *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=total_step,json=totalStep,proto3" json:"total_step,omitempty"` + LastUpdate string `protobuf:"bytes,5,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"` + Finished string `protobuf:"bytes,6,opt,name=finished,proto3" json:"finished,omitempty"` + Steps []*ProgressStep `protobuf:"bytes,7,rep,name=steps,proto3" json:"steps,omitempty"` +} + +func (x *UpdateProgressRequest) Reset() { + *x = UpdateProgressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateProgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateProgressRequest) ProtoMessage() {} + +func (x *UpdateProgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateProgressRequest.ProtoReflect.Descriptor instead. +func (*UpdateProgressRequest) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateProgressRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateProgressRequest) GetCurrentStep() *wrapperspb.UInt32Value { + if x != nil { + return x.CurrentStep + } + return nil +} + +func (x *UpdateProgressRequest) GetMaxStep() *wrapperspb.UInt32Value { + if x != nil { + return x.MaxStep + } + return nil +} + +func (x *UpdateProgressRequest) GetTotalStep() *wrapperspb.UInt32Value { + if x != nil { + return x.TotalStep + } + return nil +} + +func (x *UpdateProgressRequest) GetLastUpdate() string { + if x != nil { + return x.LastUpdate + } + return "" +} + +func (x *UpdateProgressRequest) GetFinished() string { + if x != nil { + return x.Finished + } + return "" +} + +func (x *UpdateProgressRequest) GetSteps() []*ProgressStep { + if x != nil { + return x.Steps + } + return nil +} + +type UpdateCollectionProgressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Labelselector string `protobuf:"bytes,1,opt,name=labelselector,proto3" json:"labelselector,omitempty"` + CurrentStep *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=current_step,json=currentStep,proto3" json:"current_step,omitempty"` + MaxStep *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=max_step,json=maxStep,proto3" json:"max_step,omitempty"` + TotalStep *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=total_step,json=totalStep,proto3" json:"total_step,omitempty"` + LastUpdate string `protobuf:"bytes,5,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"` + Finished string `protobuf:"bytes,6,opt,name=finished,proto3" json:"finished,omitempty"` + Steps []*ProgressStep `protobuf:"bytes,7,rep,name=steps,proto3" json:"steps,omitempty"` +} + +func (x *UpdateCollectionProgressRequest) Reset() { + *x = UpdateCollectionProgressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateCollectionProgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateCollectionProgressRequest) ProtoMessage() {} + +func (x *UpdateCollectionProgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateCollectionProgressRequest.ProtoReflect.Descriptor instead. +func (*UpdateCollectionProgressRequest) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateCollectionProgressRequest) GetLabelselector() string { + if x != nil { + return x.Labelselector + } + return "" +} + +func (x *UpdateCollectionProgressRequest) GetCurrentStep() *wrapperspb.UInt32Value { + if x != nil { + return x.CurrentStep + } + return nil +} + +func (x *UpdateCollectionProgressRequest) GetMaxStep() *wrapperspb.UInt32Value { + if x != nil { + return x.MaxStep + } + return nil +} + +func (x *UpdateCollectionProgressRequest) GetTotalStep() *wrapperspb.UInt32Value { + if x != nil { + return x.TotalStep + } + return nil +} + +func (x *UpdateCollectionProgressRequest) GetLastUpdate() string { + if x != nil { + return x.LastUpdate + } + return "" +} + +func (x *UpdateCollectionProgressRequest) GetFinished() string { + if x != nil { + return x.Finished + } + return "" +} + +func (x *UpdateCollectionProgressRequest) GetSteps() []*ProgressStep { + if x != nil { + return x.Steps + } + return nil +} + +type ListProgressesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Progresses []*Progress `protobuf:"bytes,1,rep,name=progresses,proto3" json:"progresses,omitempty"` +} + +func (x *ListProgressesResponse) Reset() { + *x = ListProgressesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_progress_progress_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProgressesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProgressesResponse) ProtoMessage() {} + +func (x *ListProgressesResponse) ProtoReflect() protoreflect.Message { + mi := &file_progress_progress_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProgressesResponse.ProtoReflect.Descriptor instead. +func (*ListProgressesResponse) Descriptor() ([]byte, []int) { + return file_progress_progress_proto_rawDescGZIP(), []int{5} +} + +func (x *ListProgressesResponse) GetProgresses() []*Progress { + if x != nil { + return x.Progresses + } + return nil +} + +var File_progress_progress_proto protoreflect.FileDescriptor + +var file_progress_progress_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x02, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, + 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x74, 0x65, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x74, 0x65, 0x70, + 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x12, + 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x6f, 0x75, 0x72, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x75, + 0x72, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x94, 0x04, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x53, 0x74, 0x65, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, + 0x65, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, + 0x74, 0x65, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x6f, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x12, 0x36, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x49, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x40, + 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x74, + 0x65, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0xc9, 0x02, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3f, 0x0a, 0x0c, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x37, 0x0a, 0x08, 0x6d, + 0x61, 0x78, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x53, 0x74, 0x65, 0x70, 0x12, 0x3b, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, + 0x65, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x65, + 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x2c, + 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22, 0xe9, 0x02, 0x0a, + 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x3f, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x37, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x73, + 0x74, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x53, 0x74, 0x65, 0x70, + 0x12, 0x3b, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x12, 0x1f, 0x0a, + 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x73, 0x74, + 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x65, + 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22, 0x4c, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x32, 0x88, 0x04, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x76, 0x63, 0x12, 0x46, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x36, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x5d, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x29, 0x2e, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x3d, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x48, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x0c, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, + 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, + 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x3b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_progress_progress_proto_rawDescOnce sync.Once + file_progress_progress_proto_rawDescData = file_progress_progress_proto_rawDesc +) + +func file_progress_progress_proto_rawDescGZIP() []byte { + file_progress_progress_proto_rawDescOnce.Do(func() { + file_progress_progress_proto_rawDescData = protoimpl.X.CompressGZIP(file_progress_progress_proto_rawDescData) + }) + return file_progress_progress_proto_rawDescData +} + +var file_progress_progress_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_progress_progress_proto_goTypes = []interface{}{ + (*CreateProgressRequest)(nil), // 0: progress.CreateProgressRequest + (*Progress)(nil), // 1: progress.Progress + (*ProgressStep)(nil), // 2: progress.ProgressStep + (*UpdateProgressRequest)(nil), // 3: progress.UpdateProgressRequest + (*UpdateCollectionProgressRequest)(nil), // 4: progress.UpdateCollectionProgressRequest + (*ListProgressesResponse)(nil), // 5: progress.ListProgressesResponse + nil, // 6: progress.CreateProgressRequest.LabelsEntry + nil, // 7: progress.Progress.LabelsEntry + (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*wrapperspb.UInt32Value)(nil), // 9: google.protobuf.UInt32Value + (*general.GetRequest)(nil), // 10: general.GetRequest + (*general.ResourceId)(nil), // 11: general.ResourceId + (*general.ListOptions)(nil), // 12: general.ListOptions + (*emptypb.Empty)(nil), // 13: google.protobuf.Empty +} +var file_progress_progress_proto_depIdxs = []int32{ + 6, // 0: progress.CreateProgressRequest.labels:type_name -> progress.CreateProgressRequest.LabelsEntry + 2, // 1: progress.Progress.steps:type_name -> progress.ProgressStep + 7, // 2: progress.Progress.labels:type_name -> progress.Progress.LabelsEntry + 8, // 3: progress.Progress.creation_timestamp:type_name -> google.protobuf.Timestamp + 9, // 4: progress.UpdateProgressRequest.current_step:type_name -> google.protobuf.UInt32Value + 9, // 5: progress.UpdateProgressRequest.max_step:type_name -> google.protobuf.UInt32Value + 9, // 6: progress.UpdateProgressRequest.total_step:type_name -> google.protobuf.UInt32Value + 2, // 7: progress.UpdateProgressRequest.steps:type_name -> progress.ProgressStep + 9, // 8: progress.UpdateCollectionProgressRequest.current_step:type_name -> google.protobuf.UInt32Value + 9, // 9: progress.UpdateCollectionProgressRequest.max_step:type_name -> google.protobuf.UInt32Value + 9, // 10: progress.UpdateCollectionProgressRequest.total_step:type_name -> google.protobuf.UInt32Value + 2, // 11: progress.UpdateCollectionProgressRequest.steps:type_name -> progress.ProgressStep + 1, // 12: progress.ListProgressesResponse.progresses:type_name -> progress.Progress + 0, // 13: progress.ProgressSvc.CreateProgress:input_type -> progress.CreateProgressRequest + 10, // 14: progress.ProgressSvc.GetProgress:input_type -> general.GetRequest + 3, // 15: progress.ProgressSvc.UpdateProgress:input_type -> progress.UpdateProgressRequest + 4, // 16: progress.ProgressSvc.UpdateCollectionProgress:input_type -> progress.UpdateCollectionProgressRequest + 11, // 17: progress.ProgressSvc.DeleteProgress:input_type -> general.ResourceId + 12, // 18: progress.ProgressSvc.DeleteCollectionProgress:input_type -> general.ListOptions + 12, // 19: progress.ProgressSvc.ListProgress:input_type -> general.ListOptions + 11, // 20: progress.ProgressSvc.CreateProgress:output_type -> general.ResourceId + 1, // 21: progress.ProgressSvc.GetProgress:output_type -> progress.Progress + 13, // 22: progress.ProgressSvc.UpdateProgress:output_type -> google.protobuf.Empty + 13, // 23: progress.ProgressSvc.UpdateCollectionProgress:output_type -> google.protobuf.Empty + 13, // 24: progress.ProgressSvc.DeleteProgress:output_type -> google.protobuf.Empty + 13, // 25: progress.ProgressSvc.DeleteCollectionProgress:output_type -> google.protobuf.Empty + 5, // 26: progress.ProgressSvc.ListProgress:output_type -> progress.ListProgressesResponse + 20, // [20:27] is the sub-list for method output_type + 13, // [13:20] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_progress_progress_proto_init() } +func file_progress_progress_proto_init() { + if File_progress_progress_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_progress_progress_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateProgressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_progress_progress_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Progress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_progress_progress_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProgressStep); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_progress_progress_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateProgressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_progress_progress_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateCollectionProgressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_progress_progress_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProgressesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_progress_progress_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_progress_progress_proto_goTypes, + DependencyIndexes: file_progress_progress_proto_depIdxs, + MessageInfos: file_progress_progress_proto_msgTypes, + }.Build() + File_progress_progress_proto = out.File + file_progress_progress_proto_rawDesc = nil + file_progress_progress_proto_goTypes = nil + file_progress_progress_proto_depIdxs = nil +} diff --git a/v3/protos/progress/progress.proto b/v3/protos/progress/progress.proto new file mode 100644 index 00000000..bd6712c8 --- /dev/null +++ b/v3/protos/progress/progress.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package progress; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/progress;progresspb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/timestamp.proto"; + +service ProgressSvc { + rpc CreateProgress (CreateProgressRequest) returns (general.ResourceId); + rpc GetProgress (general.GetRequest) returns (Progress); + rpc UpdateProgress (UpdateProgressRequest) returns (google.protobuf.Empty); + rpc UpdateCollectionProgress (UpdateCollectionProgressRequest) returns (google.protobuf.Empty); + rpc DeleteProgress (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionProgress (general.ListOptions) returns (google.protobuf.Empty); + rpc ListProgress (general.ListOptions) returns (ListProgressesResponse); +} + +message CreateProgressRequest { + uint32 current_step = 1; + uint32 max_step = 2; + uint32 total_step = 3; + string scenario = 4; + string course = 5; + string user = 6; + map labels = 7; +} + +message Progress { + string id = 1; + string uid = 2; + uint32 current_step = 3; + uint32 max_step = 4; + uint32 total_step = 5; + string scenario = 6; + string course = 7; + string user = 8; + string started = 9; + string last_update = 10; + string finished = 11; + repeated ProgressStep steps = 12; + map labels = 13; + google.protobuf.Timestamp creation_timestamp = 14; +} + +message ProgressStep { + uint32 step = 1; + string timestamp = 2; +} + +message UpdateProgressRequest { + string id = 1; + google.protobuf.UInt32Value current_step = 2; + google.protobuf.UInt32Value max_step = 3; + google.protobuf.UInt32Value total_step = 4; + string last_update = 5; + string finished = 6; + repeated ProgressStep steps = 7; +} + +message UpdateCollectionProgressRequest { + string labelselector = 1; + google.protobuf.UInt32Value current_step = 2; + google.protobuf.UInt32Value max_step = 3; + google.protobuf.UInt32Value total_step = 4; + string last_update = 5; + string finished = 6; + repeated ProgressStep steps = 7; +} + +message ListProgressesResponse { + repeated Progress progresses = 1; +} diff --git a/v3/protos/progress/progress_grpc.pb.go b/v3/protos/progress/progress_grpc.pb.go new file mode 100644 index 00000000..c3e41353 --- /dev/null +++ b/v3/protos/progress/progress_grpc.pb.go @@ -0,0 +1,333 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: progress/progress.proto + +package progresspb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ProgressSvc_CreateProgress_FullMethodName = "/progress.ProgressSvc/CreateProgress" + ProgressSvc_GetProgress_FullMethodName = "/progress.ProgressSvc/GetProgress" + ProgressSvc_UpdateProgress_FullMethodName = "/progress.ProgressSvc/UpdateProgress" + ProgressSvc_UpdateCollectionProgress_FullMethodName = "/progress.ProgressSvc/UpdateCollectionProgress" + ProgressSvc_DeleteProgress_FullMethodName = "/progress.ProgressSvc/DeleteProgress" + ProgressSvc_DeleteCollectionProgress_FullMethodName = "/progress.ProgressSvc/DeleteCollectionProgress" + ProgressSvc_ListProgress_FullMethodName = "/progress.ProgressSvc/ListProgress" +) + +// ProgressSvcClient is the client API for ProgressSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ProgressSvcClient interface { + CreateProgress(ctx context.Context, in *CreateProgressRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetProgress(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Progress, error) + UpdateProgress(ctx context.Context, in *UpdateProgressRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateCollectionProgress(ctx context.Context, in *UpdateCollectionProgressRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteProgress(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionProgress(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListProgress(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListProgressesResponse, error) +} + +type progressSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewProgressSvcClient(cc grpc.ClientConnInterface) ProgressSvcClient { + return &progressSvcClient{cc} +} + +func (c *progressSvcClient) CreateProgress(ctx context.Context, in *CreateProgressRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, ProgressSvc_CreateProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) GetProgress(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Progress, error) { + out := new(Progress) + err := c.cc.Invoke(ctx, ProgressSvc_GetProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) UpdateProgress(ctx context.Context, in *UpdateProgressRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ProgressSvc_UpdateProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) UpdateCollectionProgress(ctx context.Context, in *UpdateCollectionProgressRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ProgressSvc_UpdateCollectionProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) DeleteProgress(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ProgressSvc_DeleteProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) DeleteCollectionProgress(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ProgressSvc_DeleteCollectionProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *progressSvcClient) ListProgress(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListProgressesResponse, error) { + out := new(ListProgressesResponse) + err := c.cc.Invoke(ctx, ProgressSvc_ListProgress_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ProgressSvcServer is the server API for ProgressSvc service. +// All implementations must embed UnimplementedProgressSvcServer +// for forward compatibility +type ProgressSvcServer interface { + CreateProgress(context.Context, *CreateProgressRequest) (*general.ResourceId, error) + GetProgress(context.Context, *general.GetRequest) (*Progress, error) + UpdateProgress(context.Context, *UpdateProgressRequest) (*emptypb.Empty, error) + UpdateCollectionProgress(context.Context, *UpdateCollectionProgressRequest) (*emptypb.Empty, error) + DeleteProgress(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionProgress(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListProgress(context.Context, *general.ListOptions) (*ListProgressesResponse, error) + mustEmbedUnimplementedProgressSvcServer() +} + +// UnimplementedProgressSvcServer must be embedded to have forward compatible implementations. +type UnimplementedProgressSvcServer struct { +} + +func (UnimplementedProgressSvcServer) CreateProgress(context.Context, *CreateProgressRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateProgress not implemented") +} +func (UnimplementedProgressSvcServer) GetProgress(context.Context, *general.GetRequest) (*Progress, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProgress not implemented") +} +func (UnimplementedProgressSvcServer) UpdateProgress(context.Context, *UpdateProgressRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateProgress not implemented") +} +func (UnimplementedProgressSvcServer) UpdateCollectionProgress(context.Context, *UpdateCollectionProgressRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateCollectionProgress not implemented") +} +func (UnimplementedProgressSvcServer) DeleteProgress(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteProgress not implemented") +} +func (UnimplementedProgressSvcServer) DeleteCollectionProgress(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionProgress not implemented") +} +func (UnimplementedProgressSvcServer) ListProgress(context.Context, *general.ListOptions) (*ListProgressesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListProgress not implemented") +} +func (UnimplementedProgressSvcServer) mustEmbedUnimplementedProgressSvcServer() {} + +// UnsafeProgressSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProgressSvcServer will +// result in compilation errors. +type UnsafeProgressSvcServer interface { + mustEmbedUnimplementedProgressSvcServer() +} + +func RegisterProgressSvcServer(s grpc.ServiceRegistrar, srv ProgressSvcServer) { + s.RegisterService(&ProgressSvc_ServiceDesc, srv) +} + +func _ProgressSvc_CreateProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateProgressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).CreateProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_CreateProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).CreateProgress(ctx, req.(*CreateProgressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_GetProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).GetProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_GetProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).GetProgress(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_UpdateProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateProgressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).UpdateProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_UpdateProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).UpdateProgress(ctx, req.(*UpdateProgressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_UpdateCollectionProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateCollectionProgressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).UpdateCollectionProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_UpdateCollectionProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).UpdateCollectionProgress(ctx, req.(*UpdateCollectionProgressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_DeleteProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).DeleteProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_DeleteProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).DeleteProgress(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_DeleteCollectionProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).DeleteCollectionProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_DeleteCollectionProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).DeleteCollectionProgress(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProgressSvc_ListProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProgressSvcServer).ListProgress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProgressSvc_ListProgress_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProgressSvcServer).ListProgress(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// ProgressSvc_ServiceDesc is the grpc.ServiceDesc for ProgressSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProgressSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "progress.ProgressSvc", + HandlerType: (*ProgressSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateProgress", + Handler: _ProgressSvc_CreateProgress_Handler, + }, + { + MethodName: "GetProgress", + Handler: _ProgressSvc_GetProgress_Handler, + }, + { + MethodName: "UpdateProgress", + Handler: _ProgressSvc_UpdateProgress_Handler, + }, + { + MethodName: "UpdateCollectionProgress", + Handler: _ProgressSvc_UpdateCollectionProgress_Handler, + }, + { + MethodName: "DeleteProgress", + Handler: _ProgressSvc_DeleteProgress_Handler, + }, + { + MethodName: "DeleteCollectionProgress", + Handler: _ProgressSvc_DeleteCollectionProgress_Handler, + }, + { + MethodName: "ListProgress", + Handler: _ProgressSvc_ListProgress_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "progress/progress.proto", +} diff --git a/v3/protos/rbac/rbac.pb.go b/v3/protos/rbac/rbac.pb.go index 9a2ec3d5..b125d306 100644 --- a/v3/protos/rbac/rbac.pb.go +++ b/v3/protos/rbac/rbac.pb.go @@ -1,14 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: rbac/rbac.proto -package rbac +package rbacpb import ( authr "github.com/hobbyfarm/gargantua/v3/protos/authr" - user "github.com/hobbyfarm/gargantua/v3/protos/user" + general "github.com/hobbyfarm/gargantua/v3/protos/general" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -298,53 +298,6 @@ func (x *Subject) GetName() string { return "" } -type ResourceId struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *ResourceId) Reset() { - *x = ResourceId{} - if protoimpl.UnsafeEnabled { - mi := &file_rbac_rbac_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResourceId) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResourceId) ProtoMessage() {} - -func (x *ResourceId) ProtoReflect() protoreflect.Message { - mi := &file_rbac_rbac_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResourceId.ProtoReflect.Descriptor instead. -func (*ResourceId) Descriptor() ([]byte, []int) { - return file_rbac_rbac_proto_rawDescGZIP(), []int{5} -} - -func (x *ResourceId) GetId() string { - if x != nil { - return x.Id - } - return "" -} - type Role struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -357,7 +310,7 @@ type Role struct { func (x *Role) Reset() { *x = Role{} if protoimpl.UnsafeEnabled { - mi := &file_rbac_rbac_proto_msgTypes[6] + mi := &file_rbac_rbac_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -370,7 +323,7 @@ func (x *Role) String() string { func (*Role) ProtoMessage() {} func (x *Role) ProtoReflect() protoreflect.Message { - mi := &file_rbac_rbac_proto_msgTypes[6] + mi := &file_rbac_rbac_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -383,7 +336,7 @@ func (x *Role) ProtoReflect() protoreflect.Message { // Deprecated: Use Role.ProtoReflect.Descriptor instead. func (*Role) Descriptor() ([]byte, []int) { - return file_rbac_rbac_proto_rawDescGZIP(), []int{6} + return file_rbac_rbac_proto_rawDescGZIP(), []int{5} } func (x *Role) GetName() string { @@ -413,7 +366,7 @@ type Rule struct { func (x *Rule) Reset() { *x = Rule{} if protoimpl.UnsafeEnabled { - mi := &file_rbac_rbac_proto_msgTypes[7] + mi := &file_rbac_rbac_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -426,7 +379,7 @@ func (x *Rule) String() string { func (*Rule) ProtoMessage() {} func (x *Rule) ProtoReflect() protoreflect.Message { - mi := &file_rbac_rbac_proto_msgTypes[7] + mi := &file_rbac_rbac_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -439,7 +392,7 @@ func (x *Rule) ProtoReflect() protoreflect.Message { // Deprecated: Use Rule.ProtoReflect.Descriptor instead. func (*Rule) Descriptor() ([]byte, []int) { - return file_rbac_rbac_proto_rawDescGZIP(), []int{7} + return file_rbac_rbac_proto_rawDescGZIP(), []int{6} } func (x *Rule) GetVerbs() []string { @@ -474,7 +427,7 @@ type Roles struct { func (x *Roles) Reset() { *x = Roles{} if protoimpl.UnsafeEnabled { - mi := &file_rbac_rbac_proto_msgTypes[8] + mi := &file_rbac_rbac_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -487,7 +440,7 @@ func (x *Roles) String() string { func (*Roles) ProtoMessage() {} func (x *Roles) ProtoReflect() protoreflect.Message { - mi := &file_rbac_rbac_proto_msgTypes[8] + mi := &file_rbac_rbac_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -500,7 +453,7 @@ func (x *Roles) ProtoReflect() protoreflect.Message { // Deprecated: Use Roles.ProtoReflect.Descriptor instead. func (*Roles) Descriptor() ([]byte, []int) { - return file_rbac_rbac_proto_rawDescGZIP(), []int{8} + return file_rbac_rbac_proto_rawDescGZIP(), []int{7} } func (x *Roles) GetRoles() []*Role { @@ -515,102 +468,103 @@ var File_rbac_rbac_proto protoreflect.FileDescriptor var file_rbac_rbac_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x72, 0x62, 0x61, 0x63, 0x2f, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x72, 0x62, 0x61, 0x63, 0x1a, 0x11, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2f, 0x61, - 0x75, 0x74, 0x68, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x75, 0x73, 0x65, 0x72, - 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, - 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x0c, 0x47, 0x72, 0x61, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, - 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x09, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, - 0x33, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x45, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, - 0x35, 0x0a, 0x0c, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, - 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x69, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x60, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x29, 0x0a, - 0x08, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1c, 0x0a, 0x0a, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x04, 0x52, 0x6f, 0x6c, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x65, 0x72, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x65, 0x72, 0x62, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x69, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x22, 0x29, 0x0a, 0x05, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x05, 0x72, 0x6f, - 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, - 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x32, 0xd5, 0x05, 0x0a, - 0x07, 0x52, 0x62, 0x61, 0x63, 0x53, 0x76, 0x63, 0x12, 0x32, 0x0a, 0x06, 0x47, 0x72, 0x61, 0x6e, - 0x74, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2e, 0x41, - 0x75, 0x74, 0x68, 0x52, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x0c, - 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, 0x12, 0x0c, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x0f, 0x2e, 0x72, 0x62, 0x61, - 0x63, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, 0x12, 0x3c, 0x0a, 0x18, 0x47, - 0x65, 0x74, 0x48, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x42, - 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x12, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, - 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x0a, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, - 0x6f, 0x6c, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x07, 0x47, - 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x10, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, - 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, - 0x6c, 0x65, 0x12, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x36, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x10, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, - 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x0b, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, - 0x3e, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, - 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x75, 0x74, 0x68, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, + 0x0a, 0x0c, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x0a, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x95, 0x01, + 0x0a, 0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x33, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x45, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x62, + 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x0c, + 0x72, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x60, 0x0a, 0x0b, + 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x31, + 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x3c, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x72, + 0x62, 0x61, 0x63, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, + 0x58, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x65, 0x72, 0x62, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x65, 0x72, 0x62, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x61, 0x70, 0x69, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x61, 0x70, 0x69, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x29, 0x0a, 0x05, 0x52, 0x6f, 0x6c, + 0x65, 0x73, 0x12, 0x20, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x32, 0xeb, 0x05, 0x0a, 0x07, 0x52, 0x62, 0x61, 0x63, 0x53, 0x76, 0x63, + 0x12, 0x32, 0x0a, 0x06, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x62, 0x61, + 0x63, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, + 0x2e, 0x61, 0x75, 0x74, 0x68, 0x72, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x0f, 0x2e, 0x72, 0x62, 0x61, 0x63, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x74, 0x12, 0x43, 0x0a, 0x18, 0x47, 0x65, + 0x74, 0x48, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x12, 0x2e, 0x72, 0x62, + 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, + 0x30, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0a, 0x2e, + 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x2a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x13, 0x2e, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0a, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x0a, + 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0a, 0x2e, 0x72, 0x62, + 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x35, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x12, 0x10, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, - 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x72, 0x62, - 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x10, 0x2e, 0x72, 0x62, - 0x61, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, + 0x39, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x0b, 0x2e, 0x72, + 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x11, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x11, + 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x38, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x52, 0x6f, 0x6c, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x11, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, + 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, + 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x40, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, + 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, - 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x12, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x73, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, - 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2f, 0x72, 0x62, 0x61, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, + 0x65, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x12, + 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, + 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x72, + 0x62, 0x61, 0x63, 0x3b, 0x72, 0x62, 0x61, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -625,55 +579,56 @@ func file_rbac_rbac_proto_rawDescGZIP() []byte { return file_rbac_rbac_proto_rawDescData } -var file_rbac_rbac_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_rbac_rbac_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_rbac_rbac_proto_goTypes = []interface{}{ (*GrantRequest)(nil), // 0: rbac.GrantRequest (*AccessSet)(nil), // 1: rbac.AccessSet (*RoleBindings)(nil), // 2: rbac.RoleBindings (*RoleBinding)(nil), // 3: rbac.RoleBinding (*Subject)(nil), // 4: rbac.Subject - (*ResourceId)(nil), // 5: rbac.ResourceId - (*Role)(nil), // 6: rbac.Role - (*Rule)(nil), // 7: rbac.Rule - (*Roles)(nil), // 8: rbac.Roles - nil, // 9: rbac.AccessSet.AccessEntry - (*authr.Permission)(nil), // 10: authr.Permission - (*user.UserId)(nil), // 11: user.UserId - (*emptypb.Empty)(nil), // 12: google.protobuf.Empty + (*Role)(nil), // 5: rbac.Role + (*Rule)(nil), // 6: rbac.Rule + (*Roles)(nil), // 7: rbac.Roles + nil, // 8: rbac.AccessSet.AccessEntry + (*authr.Permission)(nil), // 9: authr.Permission + (*general.ResourceId)(nil), // 10: general.ResourceId + (*general.GetRequest)(nil), // 11: general.GetRequest + (*general.ListOptions)(nil), // 12: general.ListOptions (*authr.AuthRResponse)(nil), // 13: authr.AuthRResponse + (*emptypb.Empty)(nil), // 14: google.protobuf.Empty } var file_rbac_rbac_proto_depIdxs = []int32{ - 10, // 0: rbac.GrantRequest.permission:type_name -> authr.Permission - 9, // 1: rbac.AccessSet.access:type_name -> rbac.AccessSet.AccessEntry + 9, // 0: rbac.GrantRequest.permission:type_name -> authr.Permission + 8, // 1: rbac.AccessSet.access:type_name -> rbac.AccessSet.AccessEntry 3, // 2: rbac.RoleBindings.rolebindings:type_name -> rbac.RoleBinding 4, // 3: rbac.RoleBinding.subjects:type_name -> rbac.Subject - 7, // 4: rbac.Role.rules:type_name -> rbac.Rule - 6, // 5: rbac.Roles.roles:type_name -> rbac.Role + 6, // 4: rbac.Role.rules:type_name -> rbac.Rule + 5, // 5: rbac.Roles.roles:type_name -> rbac.Role 0, // 6: rbac.RbacSvc.Grants:input_type -> rbac.GrantRequest - 11, // 7: rbac.RbacSvc.GetAccessSet:input_type -> user.UserId - 11, // 8: rbac.RbacSvc.GetHobbyfarmRoleBindings:input_type -> user.UserId - 6, // 9: rbac.RbacSvc.CreateRole:input_type -> rbac.Role - 5, // 10: rbac.RbacSvc.GetRole:input_type -> rbac.ResourceId - 6, // 11: rbac.RbacSvc.UpdateRole:input_type -> rbac.Role - 5, // 12: rbac.RbacSvc.DeleteRole:input_type -> rbac.ResourceId - 12, // 13: rbac.RbacSvc.ListRole:input_type -> google.protobuf.Empty + 10, // 7: rbac.RbacSvc.GetAccessSet:input_type -> general.ResourceId + 10, // 8: rbac.RbacSvc.GetHobbyfarmRoleBindings:input_type -> general.ResourceId + 5, // 9: rbac.RbacSvc.CreateRole:input_type -> rbac.Role + 11, // 10: rbac.RbacSvc.GetRole:input_type -> general.GetRequest + 5, // 11: rbac.RbacSvc.UpdateRole:input_type -> rbac.Role + 10, // 12: rbac.RbacSvc.DeleteRole:input_type -> general.ResourceId + 12, // 13: rbac.RbacSvc.ListRole:input_type -> general.ListOptions 3, // 14: rbac.RbacSvc.CreateRolebinding:input_type -> rbac.RoleBinding - 5, // 15: rbac.RbacSvc.GetRolebinding:input_type -> rbac.ResourceId + 11, // 15: rbac.RbacSvc.GetRolebinding:input_type -> general.GetRequest 3, // 16: rbac.RbacSvc.UpdateRolebinding:input_type -> rbac.RoleBinding - 5, // 17: rbac.RbacSvc.DeleteRolebinding:input_type -> rbac.ResourceId - 12, // 18: rbac.RbacSvc.ListRolebinding:input_type -> google.protobuf.Empty + 10, // 17: rbac.RbacSvc.DeleteRolebinding:input_type -> general.ResourceId + 12, // 18: rbac.RbacSvc.ListRolebinding:input_type -> general.ListOptions 13, // 19: rbac.RbacSvc.Grants:output_type -> authr.AuthRResponse 1, // 20: rbac.RbacSvc.GetAccessSet:output_type -> rbac.AccessSet 2, // 21: rbac.RbacSvc.GetHobbyfarmRoleBindings:output_type -> rbac.RoleBindings - 12, // 22: rbac.RbacSvc.CreateRole:output_type -> google.protobuf.Empty - 6, // 23: rbac.RbacSvc.GetRole:output_type -> rbac.Role - 12, // 24: rbac.RbacSvc.UpdateRole:output_type -> google.protobuf.Empty - 12, // 25: rbac.RbacSvc.DeleteRole:output_type -> google.protobuf.Empty - 8, // 26: rbac.RbacSvc.ListRole:output_type -> rbac.Roles - 12, // 27: rbac.RbacSvc.CreateRolebinding:output_type -> google.protobuf.Empty + 14, // 22: rbac.RbacSvc.CreateRole:output_type -> google.protobuf.Empty + 5, // 23: rbac.RbacSvc.GetRole:output_type -> rbac.Role + 14, // 24: rbac.RbacSvc.UpdateRole:output_type -> google.protobuf.Empty + 14, // 25: rbac.RbacSvc.DeleteRole:output_type -> google.protobuf.Empty + 7, // 26: rbac.RbacSvc.ListRole:output_type -> rbac.Roles + 14, // 27: rbac.RbacSvc.CreateRolebinding:output_type -> google.protobuf.Empty 3, // 28: rbac.RbacSvc.GetRolebinding:output_type -> rbac.RoleBinding - 12, // 29: rbac.RbacSvc.UpdateRolebinding:output_type -> google.protobuf.Empty - 12, // 30: rbac.RbacSvc.DeleteRolebinding:output_type -> google.protobuf.Empty + 14, // 29: rbac.RbacSvc.UpdateRolebinding:output_type -> google.protobuf.Empty + 14, // 30: rbac.RbacSvc.DeleteRolebinding:output_type -> google.protobuf.Empty 2, // 31: rbac.RbacSvc.ListRolebinding:output_type -> rbac.RoleBindings 19, // [19:32] is the sub-list for method output_type 6, // [6:19] is the sub-list for method input_type @@ -749,18 +704,6 @@ func file_rbac_rbac_proto_init() { } } file_rbac_rbac_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceId); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_rbac_rbac_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Role); i { case 0: return &v.state @@ -772,7 +715,7 @@ func file_rbac_rbac_proto_init() { return nil } } - file_rbac_rbac_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_rbac_rbac_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Rule); i { case 0: return &v.state @@ -784,7 +727,7 @@ func file_rbac_rbac_proto_init() { return nil } } - file_rbac_rbac_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_rbac_rbac_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Roles); i { case 0: return &v.state @@ -803,7 +746,7 @@ func file_rbac_rbac_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rbac_rbac_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 9, NumExtensions: 0, NumServices: 1, }, diff --git a/v3/protos/rbac/rbac.proto b/v3/protos/rbac/rbac.proto index f6d9c589..3f568a7a 100644 --- a/v3/protos/rbac/rbac.proto +++ b/v3/protos/rbac/rbac.proto @@ -2,29 +2,29 @@ syntax = "proto3"; package rbac; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/rbac"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/rbac;rbacpb"; import "authr/authr.proto"; -import "user/user.proto"; +import "general/general.proto"; import "google/protobuf/empty.proto"; // Service definition service RbacSvc { rpc Grants (GrantRequest) returns (authr.AuthRResponse); - rpc GetAccessSet (user.UserId) returns (AccessSet); - rpc GetHobbyfarmRoleBindings (user.UserId) returns (RoleBindings); + rpc GetAccessSet (general.ResourceId) returns (AccessSet); + rpc GetHobbyfarmRoleBindings (general.ResourceId) returns (RoleBindings); // Resource oriented RPCs for roles: rpc CreateRole (Role) returns (google.protobuf.Empty); - rpc GetRole (ResourceId) returns (Role); + rpc GetRole (general.GetRequest) returns (Role); rpc UpdateRole (Role) returns (google.protobuf.Empty); - rpc DeleteRole (ResourceId) returns (google.protobuf.Empty); - rpc ListRole (google.protobuf.Empty) returns (Roles); + rpc DeleteRole (general.ResourceId) returns (google.protobuf.Empty); + rpc ListRole (general.ListOptions) returns (Roles); // Resource oriented RPCs for rolebindings: rpc CreateRolebinding (RoleBinding) returns (google.protobuf.Empty); - rpc GetRolebinding (ResourceId) returns (RoleBinding); + rpc GetRolebinding (general.GetRequest) returns (RoleBinding); rpc UpdateRolebinding (RoleBinding) returns (google.protobuf.Empty); - rpc DeleteRolebinding (ResourceId) returns (google.protobuf.Empty); - rpc ListRolebinding (google.protobuf.Empty) returns (RoleBindings); + rpc DeleteRolebinding (general.ResourceId) returns (google.protobuf.Empty); + rpc ListRolebinding (general.ListOptions) returns (RoleBindings); } message GrantRequest { @@ -52,10 +52,6 @@ message Subject { string name = 2; } -message ResourceId { - string id = 1; -} - message Role { string name = 1; repeated Rule rules = 2; diff --git a/v3/protos/rbac/rbac_grpc.pb.go b/v3/protos/rbac/rbac_grpc.pb.go index 399d61ac..1cbeb6fc 100644 --- a/v3/protos/rbac/rbac_grpc.pb.go +++ b/v3/protos/rbac/rbac_grpc.pb.go @@ -4,12 +4,12 @@ // - protoc v3.21.12 // source: rbac/rbac.proto -package rbac +package rbacpb import ( context "context" authr "github.com/hobbyfarm/gargantua/v3/protos/authr" - user "github.com/hobbyfarm/gargantua/v3/protos/user" + general "github.com/hobbyfarm/gargantua/v3/protos/general" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -42,20 +42,20 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type RbacSvcClient interface { Grants(ctx context.Context, in *GrantRequest, opts ...grpc.CallOption) (*authr.AuthRResponse, error) - GetAccessSet(ctx context.Context, in *user.UserId, opts ...grpc.CallOption) (*AccessSet, error) - GetHobbyfarmRoleBindings(ctx context.Context, in *user.UserId, opts ...grpc.CallOption) (*RoleBindings, error) + GetAccessSet(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*AccessSet, error) + GetHobbyfarmRoleBindings(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*RoleBindings, error) // Resource oriented RPCs for roles: CreateRole(ctx context.Context, in *Role, opts ...grpc.CallOption) (*emptypb.Empty, error) - GetRole(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*Role, error) + GetRole(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Role, error) UpdateRole(ctx context.Context, in *Role, opts ...grpc.CallOption) (*emptypb.Empty, error) - DeleteRole(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) - ListRole(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Roles, error) + DeleteRole(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListRole(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*Roles, error) // Resource oriented RPCs for rolebindings: CreateRolebinding(ctx context.Context, in *RoleBinding, opts ...grpc.CallOption) (*emptypb.Empty, error) - GetRolebinding(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*RoleBinding, error) + GetRolebinding(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*RoleBinding, error) UpdateRolebinding(ctx context.Context, in *RoleBinding, opts ...grpc.CallOption) (*emptypb.Empty, error) - DeleteRolebinding(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) - ListRolebinding(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*RoleBindings, error) + DeleteRolebinding(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListRolebinding(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*RoleBindings, error) } type rbacSvcClient struct { @@ -75,7 +75,7 @@ func (c *rbacSvcClient) Grants(ctx context.Context, in *GrantRequest, opts ...gr return out, nil } -func (c *rbacSvcClient) GetAccessSet(ctx context.Context, in *user.UserId, opts ...grpc.CallOption) (*AccessSet, error) { +func (c *rbacSvcClient) GetAccessSet(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*AccessSet, error) { out := new(AccessSet) err := c.cc.Invoke(ctx, RbacSvc_GetAccessSet_FullMethodName, in, out, opts...) if err != nil { @@ -84,7 +84,7 @@ func (c *rbacSvcClient) GetAccessSet(ctx context.Context, in *user.UserId, opts return out, nil } -func (c *rbacSvcClient) GetHobbyfarmRoleBindings(ctx context.Context, in *user.UserId, opts ...grpc.CallOption) (*RoleBindings, error) { +func (c *rbacSvcClient) GetHobbyfarmRoleBindings(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*RoleBindings, error) { out := new(RoleBindings) err := c.cc.Invoke(ctx, RbacSvc_GetHobbyfarmRoleBindings_FullMethodName, in, out, opts...) if err != nil { @@ -102,7 +102,7 @@ func (c *rbacSvcClient) CreateRole(ctx context.Context, in *Role, opts ...grpc.C return out, nil } -func (c *rbacSvcClient) GetRole(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*Role, error) { +func (c *rbacSvcClient) GetRole(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Role, error) { out := new(Role) err := c.cc.Invoke(ctx, RbacSvc_GetRole_FullMethodName, in, out, opts...) if err != nil { @@ -120,7 +120,7 @@ func (c *rbacSvcClient) UpdateRole(ctx context.Context, in *Role, opts ...grpc.C return out, nil } -func (c *rbacSvcClient) DeleteRole(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *rbacSvcClient) DeleteRole(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, RbacSvc_DeleteRole_FullMethodName, in, out, opts...) if err != nil { @@ -129,7 +129,7 @@ func (c *rbacSvcClient) DeleteRole(ctx context.Context, in *ResourceId, opts ... return out, nil } -func (c *rbacSvcClient) ListRole(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Roles, error) { +func (c *rbacSvcClient) ListRole(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*Roles, error) { out := new(Roles) err := c.cc.Invoke(ctx, RbacSvc_ListRole_FullMethodName, in, out, opts...) if err != nil { @@ -147,7 +147,7 @@ func (c *rbacSvcClient) CreateRolebinding(ctx context.Context, in *RoleBinding, return out, nil } -func (c *rbacSvcClient) GetRolebinding(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*RoleBinding, error) { +func (c *rbacSvcClient) GetRolebinding(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*RoleBinding, error) { out := new(RoleBinding) err := c.cc.Invoke(ctx, RbacSvc_GetRolebinding_FullMethodName, in, out, opts...) if err != nil { @@ -165,7 +165,7 @@ func (c *rbacSvcClient) UpdateRolebinding(ctx context.Context, in *RoleBinding, return out, nil } -func (c *rbacSvcClient) DeleteRolebinding(ctx context.Context, in *ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *rbacSvcClient) DeleteRolebinding(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, RbacSvc_DeleteRolebinding_FullMethodName, in, out, opts...) if err != nil { @@ -174,7 +174,7 @@ func (c *rbacSvcClient) DeleteRolebinding(ctx context.Context, in *ResourceId, o return out, nil } -func (c *rbacSvcClient) ListRolebinding(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*RoleBindings, error) { +func (c *rbacSvcClient) ListRolebinding(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*RoleBindings, error) { out := new(RoleBindings) err := c.cc.Invoke(ctx, RbacSvc_ListRolebinding_FullMethodName, in, out, opts...) if err != nil { @@ -188,20 +188,20 @@ func (c *rbacSvcClient) ListRolebinding(ctx context.Context, in *emptypb.Empty, // for forward compatibility type RbacSvcServer interface { Grants(context.Context, *GrantRequest) (*authr.AuthRResponse, error) - GetAccessSet(context.Context, *user.UserId) (*AccessSet, error) - GetHobbyfarmRoleBindings(context.Context, *user.UserId) (*RoleBindings, error) + GetAccessSet(context.Context, *general.ResourceId) (*AccessSet, error) + GetHobbyfarmRoleBindings(context.Context, *general.ResourceId) (*RoleBindings, error) // Resource oriented RPCs for roles: CreateRole(context.Context, *Role) (*emptypb.Empty, error) - GetRole(context.Context, *ResourceId) (*Role, error) + GetRole(context.Context, *general.GetRequest) (*Role, error) UpdateRole(context.Context, *Role) (*emptypb.Empty, error) - DeleteRole(context.Context, *ResourceId) (*emptypb.Empty, error) - ListRole(context.Context, *emptypb.Empty) (*Roles, error) + DeleteRole(context.Context, *general.ResourceId) (*emptypb.Empty, error) + ListRole(context.Context, *general.ListOptions) (*Roles, error) // Resource oriented RPCs for rolebindings: CreateRolebinding(context.Context, *RoleBinding) (*emptypb.Empty, error) - GetRolebinding(context.Context, *ResourceId) (*RoleBinding, error) + GetRolebinding(context.Context, *general.GetRequest) (*RoleBinding, error) UpdateRolebinding(context.Context, *RoleBinding) (*emptypb.Empty, error) - DeleteRolebinding(context.Context, *ResourceId) (*emptypb.Empty, error) - ListRolebinding(context.Context, *emptypb.Empty) (*RoleBindings, error) + DeleteRolebinding(context.Context, *general.ResourceId) (*emptypb.Empty, error) + ListRolebinding(context.Context, *general.ListOptions) (*RoleBindings, error) mustEmbedUnimplementedRbacSvcServer() } @@ -212,40 +212,40 @@ type UnimplementedRbacSvcServer struct { func (UnimplementedRbacSvcServer) Grants(context.Context, *GrantRequest) (*authr.AuthRResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Grants not implemented") } -func (UnimplementedRbacSvcServer) GetAccessSet(context.Context, *user.UserId) (*AccessSet, error) { +func (UnimplementedRbacSvcServer) GetAccessSet(context.Context, *general.ResourceId) (*AccessSet, error) { return nil, status.Errorf(codes.Unimplemented, "method GetAccessSet not implemented") } -func (UnimplementedRbacSvcServer) GetHobbyfarmRoleBindings(context.Context, *user.UserId) (*RoleBindings, error) { +func (UnimplementedRbacSvcServer) GetHobbyfarmRoleBindings(context.Context, *general.ResourceId) (*RoleBindings, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHobbyfarmRoleBindings not implemented") } func (UnimplementedRbacSvcServer) CreateRole(context.Context, *Role) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateRole not implemented") } -func (UnimplementedRbacSvcServer) GetRole(context.Context, *ResourceId) (*Role, error) { +func (UnimplementedRbacSvcServer) GetRole(context.Context, *general.GetRequest) (*Role, error) { return nil, status.Errorf(codes.Unimplemented, "method GetRole not implemented") } func (UnimplementedRbacSvcServer) UpdateRole(context.Context, *Role) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRole not implemented") } -func (UnimplementedRbacSvcServer) DeleteRole(context.Context, *ResourceId) (*emptypb.Empty, error) { +func (UnimplementedRbacSvcServer) DeleteRole(context.Context, *general.ResourceId) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteRole not implemented") } -func (UnimplementedRbacSvcServer) ListRole(context.Context, *emptypb.Empty) (*Roles, error) { +func (UnimplementedRbacSvcServer) ListRole(context.Context, *general.ListOptions) (*Roles, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRole not implemented") } func (UnimplementedRbacSvcServer) CreateRolebinding(context.Context, *RoleBinding) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateRolebinding not implemented") } -func (UnimplementedRbacSvcServer) GetRolebinding(context.Context, *ResourceId) (*RoleBinding, error) { +func (UnimplementedRbacSvcServer) GetRolebinding(context.Context, *general.GetRequest) (*RoleBinding, error) { return nil, status.Errorf(codes.Unimplemented, "method GetRolebinding not implemented") } func (UnimplementedRbacSvcServer) UpdateRolebinding(context.Context, *RoleBinding) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRolebinding not implemented") } -func (UnimplementedRbacSvcServer) DeleteRolebinding(context.Context, *ResourceId) (*emptypb.Empty, error) { +func (UnimplementedRbacSvcServer) DeleteRolebinding(context.Context, *general.ResourceId) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteRolebinding not implemented") } -func (UnimplementedRbacSvcServer) ListRolebinding(context.Context, *emptypb.Empty) (*RoleBindings, error) { +func (UnimplementedRbacSvcServer) ListRolebinding(context.Context, *general.ListOptions) (*RoleBindings, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRolebinding not implemented") } func (UnimplementedRbacSvcServer) mustEmbedUnimplementedRbacSvcServer() {} @@ -280,7 +280,7 @@ func _RbacSvc_Grants_Handler(srv interface{}, ctx context.Context, dec func(inte } func _RbacSvc_GetAccessSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(user.UserId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -292,13 +292,13 @@ func _RbacSvc_GetAccessSet_Handler(srv interface{}, ctx context.Context, dec fun FullMethod: RbacSvc_GetAccessSet_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).GetAccessSet(ctx, req.(*user.UserId)) + return srv.(RbacSvcServer).GetAccessSet(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } func _RbacSvc_GetHobbyfarmRoleBindings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(user.UserId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -310,7 +310,7 @@ func _RbacSvc_GetHobbyfarmRoleBindings_Handler(srv interface{}, ctx context.Cont FullMethod: RbacSvc_GetHobbyfarmRoleBindings_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).GetHobbyfarmRoleBindings(ctx, req.(*user.UserId)) + return srv.(RbacSvcServer).GetHobbyfarmRoleBindings(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } @@ -334,7 +334,7 @@ func _RbacSvc_CreateRole_Handler(srv interface{}, ctx context.Context, dec func( } func _RbacSvc_GetRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -346,7 +346,7 @@ func _RbacSvc_GetRole_Handler(srv interface{}, ctx context.Context, dec func(int FullMethod: RbacSvc_GetRole_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).GetRole(ctx, req.(*ResourceId)) + return srv.(RbacSvcServer).GetRole(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } @@ -370,7 +370,7 @@ func _RbacSvc_UpdateRole_Handler(srv interface{}, ctx context.Context, dec func( } func _RbacSvc_DeleteRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -382,13 +382,13 @@ func _RbacSvc_DeleteRole_Handler(srv interface{}, ctx context.Context, dec func( FullMethod: RbacSvc_DeleteRole_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).DeleteRole(ctx, req.(*ResourceId)) + return srv.(RbacSvcServer).DeleteRole(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } func _RbacSvc_ListRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(general.ListOptions) if err := dec(in); err != nil { return nil, err } @@ -400,7 +400,7 @@ func _RbacSvc_ListRole_Handler(srv interface{}, ctx context.Context, dec func(in FullMethod: RbacSvc_ListRole_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).ListRole(ctx, req.(*emptypb.Empty)) + return srv.(RbacSvcServer).ListRole(ctx, req.(*general.ListOptions)) } return interceptor(ctx, in, info, handler) } @@ -424,7 +424,7 @@ func _RbacSvc_CreateRolebinding_Handler(srv interface{}, ctx context.Context, de } func _RbacSvc_GetRolebinding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -436,7 +436,7 @@ func _RbacSvc_GetRolebinding_Handler(srv interface{}, ctx context.Context, dec f FullMethod: RbacSvc_GetRolebinding_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).GetRolebinding(ctx, req.(*ResourceId)) + return srv.(RbacSvcServer).GetRolebinding(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } @@ -460,7 +460,7 @@ func _RbacSvc_UpdateRolebinding_Handler(srv interface{}, ctx context.Context, de } func _RbacSvc_DeleteRolebinding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResourceId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -472,13 +472,13 @@ func _RbacSvc_DeleteRolebinding_Handler(srv interface{}, ctx context.Context, de FullMethod: RbacSvc_DeleteRolebinding_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).DeleteRolebinding(ctx, req.(*ResourceId)) + return srv.(RbacSvcServer).DeleteRolebinding(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } func _RbacSvc_ListRolebinding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(general.ListOptions) if err := dec(in); err != nil { return nil, err } @@ -490,7 +490,7 @@ func _RbacSvc_ListRolebinding_Handler(srv interface{}, ctx context.Context, dec FullMethod: RbacSvc_ListRolebinding_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RbacSvcServer).ListRolebinding(ctx, req.(*emptypb.Empty)) + return srv.(RbacSvcServer).ListRolebinding(ctx, req.(*general.ListOptions)) } return interceptor(ctx, in, info, handler) } diff --git a/v3/protos/scenario/scenario.pb.go b/v3/protos/scenario/scenario.pb.go new file mode 100644 index 00000000..9df785e9 --- /dev/null +++ b/v3/protos/scenario/scenario.pb.go @@ -0,0 +1,988 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: scenario/scenario.proto + +package scenariopb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Scenario struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Steps []*ScenarioStep `protobuf:"bytes,5,rep,name=steps,proto3" json:"steps,omitempty"` + Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` + Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` + Vms []*general.StringMap `protobuf:"bytes,8,rep,name=vms,proto3" json:"vms,omitempty"` + KeepaliveDuration string `protobuf:"bytes,9,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration string `protobuf:"bytes,10,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable bool `protobuf:"varint,11,opt,name=pausable,proto3" json:"pausable,omitempty"` + VmTasks []*VirtualMachineTasks `protobuf:"bytes,12,rep,name=vm_tasks,json=vmTasks,proto3" json:"vm_tasks,omitempty"` + Labels map[string]string `protobuf:"bytes,13,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Scenario) Reset() { + *x = Scenario{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Scenario) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Scenario) ProtoMessage() {} + +func (x *Scenario) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Scenario.ProtoReflect.Descriptor instead. +func (*Scenario) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{0} +} + +func (x *Scenario) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Scenario) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *Scenario) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Scenario) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Scenario) GetSteps() []*ScenarioStep { + if x != nil { + return x.Steps + } + return nil +} + +func (x *Scenario) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +func (x *Scenario) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Scenario) GetVms() []*general.StringMap { + if x != nil { + return x.Vms + } + return nil +} + +func (x *Scenario) GetKeepaliveDuration() string { + if x != nil { + return x.KeepaliveDuration + } + return "" +} + +func (x *Scenario) GetPauseDuration() string { + if x != nil { + return x.PauseDuration + } + return "" +} + +func (x *Scenario) GetPausable() bool { + if x != nil { + return x.Pausable + } + return false +} + +func (x *Scenario) GetVmTasks() []*VirtualMachineTasks { + if x != nil { + return x.VmTasks + } + return nil +} + +func (x *Scenario) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type CreateScenarioRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + RawSteps string `protobuf:"bytes,3,opt,name=raw_steps,json=rawSteps,proto3" json:"raw_steps,omitempty"` + RawCategories string `protobuf:"bytes,4,opt,name=raw_categories,json=rawCategories,proto3" json:"raw_categories,omitempty"` + RawTags string `protobuf:"bytes,5,opt,name=raw_tags,json=rawTags,proto3" json:"raw_tags,omitempty"` + RawVms string `protobuf:"bytes,6,opt,name=raw_vms,json=rawVms,proto3" json:"raw_vms,omitempty"` + RawVmTasks string `protobuf:"bytes,7,opt,name=raw_vm_tasks,json=rawVmTasks,proto3" json:"raw_vm_tasks,omitempty"` + KeepaliveDuration string `protobuf:"bytes,8,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration string `protobuf:"bytes,9,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable bool `protobuf:"varint,10,opt,name=pausable,proto3" json:"pausable,omitempty"` +} + +func (x *CreateScenarioRequest) Reset() { + *x = CreateScenarioRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateScenarioRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateScenarioRequest) ProtoMessage() {} + +func (x *CreateScenarioRequest) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateScenarioRequest.ProtoReflect.Descriptor instead. +func (*CreateScenarioRequest) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateScenarioRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateScenarioRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateScenarioRequest) GetRawSteps() string { + if x != nil { + return x.RawSteps + } + return "" +} + +func (x *CreateScenarioRequest) GetRawCategories() string { + if x != nil { + return x.RawCategories + } + return "" +} + +func (x *CreateScenarioRequest) GetRawTags() string { + if x != nil { + return x.RawTags + } + return "" +} + +func (x *CreateScenarioRequest) GetRawVms() string { + if x != nil { + return x.RawVms + } + return "" +} + +func (x *CreateScenarioRequest) GetRawVmTasks() string { + if x != nil { + return x.RawVmTasks + } + return "" +} + +func (x *CreateScenarioRequest) GetKeepaliveDuration() string { + if x != nil { + return x.KeepaliveDuration + } + return "" +} + +func (x *CreateScenarioRequest) GetPauseDuration() string { + if x != nil { + return x.PauseDuration + } + return "" +} + +func (x *CreateScenarioRequest) GetPausable() bool { + if x != nil { + return x.Pausable + } + return false +} + +type ScenarioStep struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *ScenarioStep) Reset() { + *x = ScenarioStep{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ScenarioStep) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ScenarioStep) ProtoMessage() {} + +func (x *ScenarioStep) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ScenarioStep.ProtoReflect.Descriptor instead. +func (*ScenarioStep) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{2} +} + +func (x *ScenarioStep) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *ScenarioStep) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +type UpdateScenarioRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + RawSteps string `protobuf:"bytes,4,opt,name=raw_steps,json=rawSteps,proto3" json:"raw_steps,omitempty"` + RawCategories string `protobuf:"bytes,5,opt,name=raw_categories,json=rawCategories,proto3" json:"raw_categories,omitempty"` + RawTags string `protobuf:"bytes,6,opt,name=raw_tags,json=rawTags,proto3" json:"raw_tags,omitempty"` + RawVms string `protobuf:"bytes,7,opt,name=raw_vms,json=rawVms,proto3" json:"raw_vms,omitempty"` + RawVmTasks string `protobuf:"bytes,8,opt,name=raw_vm_tasks,json=rawVmTasks,proto3" json:"raw_vm_tasks,omitempty"` + KeepaliveDuration *wrapperspb.StringValue `protobuf:"bytes,9,opt,name=keepalive_duration,json=keepaliveDuration,proto3" json:"keepalive_duration,omitempty"` + PauseDuration *wrapperspb.StringValue `protobuf:"bytes,10,opt,name=pause_duration,json=pauseDuration,proto3" json:"pause_duration,omitempty"` + Pausable *wrapperspb.BoolValue `protobuf:"bytes,11,opt,name=pausable,proto3" json:"pausable,omitempty"` +} + +func (x *UpdateScenarioRequest) Reset() { + *x = UpdateScenarioRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateScenarioRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateScenarioRequest) ProtoMessage() {} + +func (x *UpdateScenarioRequest) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateScenarioRequest.ProtoReflect.Descriptor instead. +func (*UpdateScenarioRequest) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateScenarioRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateScenarioRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateScenarioRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *UpdateScenarioRequest) GetRawSteps() string { + if x != nil { + return x.RawSteps + } + return "" +} + +func (x *UpdateScenarioRequest) GetRawCategories() string { + if x != nil { + return x.RawCategories + } + return "" +} + +func (x *UpdateScenarioRequest) GetRawTags() string { + if x != nil { + return x.RawTags + } + return "" +} + +func (x *UpdateScenarioRequest) GetRawVms() string { + if x != nil { + return x.RawVms + } + return "" +} + +func (x *UpdateScenarioRequest) GetRawVmTasks() string { + if x != nil { + return x.RawVmTasks + } + return "" +} + +func (x *UpdateScenarioRequest) GetKeepaliveDuration() *wrapperspb.StringValue { + if x != nil { + return x.KeepaliveDuration + } + return nil +} + +func (x *UpdateScenarioRequest) GetPauseDuration() *wrapperspb.StringValue { + if x != nil { + return x.PauseDuration + } + return nil +} + +func (x *UpdateScenarioRequest) GetPausable() *wrapperspb.BoolValue { + if x != nil { + return x.Pausable + } + return nil +} + +type ListScenariosResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scenarios []*Scenario `protobuf:"bytes,1,rep,name=scenarios,proto3" json:"scenarios,omitempty"` +} + +func (x *ListScenariosResponse) Reset() { + *x = ListScenariosResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListScenariosResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListScenariosResponse) ProtoMessage() {} + +func (x *ListScenariosResponse) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListScenariosResponse.ProtoReflect.Descriptor instead. +func (*ListScenariosResponse) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{4} +} + +func (x *ListScenariosResponse) GetScenarios() []*Scenario { + if x != nil { + return x.Scenarios + } + return nil +} + +type VirtualMachineTasks struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VmName string `protobuf:"bytes,1,opt,name=vm_name,json=vmName,proto3" json:"vm_name,omitempty"` + Tasks []*Task `protobuf:"bytes,2,rep,name=tasks,proto3" json:"tasks,omitempty"` +} + +func (x *VirtualMachineTasks) Reset() { + *x = VirtualMachineTasks{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VirtualMachineTasks) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualMachineTasks) ProtoMessage() {} + +func (x *VirtualMachineTasks) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualMachineTasks.ProtoReflect.Descriptor instead. +func (*VirtualMachineTasks) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{5} +} + +func (x *VirtualMachineTasks) GetVmName() string { + if x != nil { + return x.VmName + } + return "" +} + +func (x *VirtualMachineTasks) GetTasks() []*Task { + if x != nil { + return x.Tasks + } + return nil +} + +type Task struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Command string `protobuf:"bytes,3,opt,name=command,proto3" json:"command,omitempty"` + ExpectedOutputValue string `protobuf:"bytes,4,opt,name=expected_output_value,json=expectedOutputValue,proto3" json:"expected_output_value,omitempty"` + ExpectedReturnCode int32 `protobuf:"varint,5,opt,name=expected_return_code,json=expectedReturnCode,proto3" json:"expected_return_code,omitempty"` + ReturnType string `protobuf:"bytes,6,opt,name=return_type,json=returnType,proto3" json:"return_type,omitempty"` +} + +func (x *Task) Reset() { + *x = Task{} + if protoimpl.UnsafeEnabled { + mi := &file_scenario_scenario_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Task) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Task) ProtoMessage() {} + +func (x *Task) ProtoReflect() protoreflect.Message { + mi := &file_scenario_scenario_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Task.ProtoReflect.Descriptor instead. +func (*Task) Descriptor() ([]byte, []int) { + return file_scenario_scenario_proto_rawDescGZIP(), []int{6} +} + +func (x *Task) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Task) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Task) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *Task) GetExpectedOutputValue() string { + if x != nil { + return x.ExpectedOutputValue + } + return "" +} + +func (x *Task) GetExpectedReturnCode() int32 { + if x != nil { + return x.ExpectedReturnCode + } + return 0 +} + +func (x *Task) GetReturnType() string { + if x != nil { + return x.ReturnType + } + return "" +} + +var File_scenario_scenario_proto protoreflect.FileDescriptor + +var file_scenario_scenario_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x04, 0x0a, 0x08, 0x53, 0x63, 0x65, 0x6e, + 0x61, 0x72, 0x69, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x05, + 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, + 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x53, + 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x24, + 0x0a, 0x03, 0x76, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x52, + 0x03, 0x76, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, + 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x75, + 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, + 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x70, 0x61, + 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x76, 0x6d, 0x5f, 0x74, 0x61, 0x73, + 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x07, 0x76, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x73, + 0x12, 0x36, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x53, 0x63, 0x65, 0x6e, + 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xd9, 0x02, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, 0x74, 0x65, 0x70, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x61, 0x77, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x61, 0x77, 0x43, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x74, + 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x61, 0x77, 0x54, 0x61, + 0x67, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x61, 0x77, 0x5f, 0x76, 0x6d, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x61, 0x77, 0x56, 0x6d, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x72, + 0x61, 0x77, 0x5f, 0x76, 0x6d, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x56, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x2d, 0x0a, + 0x12, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x61, + 0x6c, 0x69, 0x76, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, + 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x75, 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x22, + 0x3e, 0x0a, 0x0c, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x53, 0x74, 0x65, 0x70, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0xc1, 0x03, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1b, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, + 0x72, 0x61, 0x77, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x61, 0x77, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x69, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x61, 0x77, 0x54, 0x61, 0x67, 0x73, 0x12, 0x17, + 0x0a, 0x07, 0x72, 0x61, 0x77, 0x5f, 0x76, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x61, 0x77, 0x56, 0x6d, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x76, + 0x6d, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, + 0x61, 0x77, 0x56, 0x6d, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x4b, 0x0a, 0x12, 0x6b, 0x65, 0x65, + 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x70, 0x61, + 0x75, 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x08, 0x70, + 0x61, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x70, 0x61, 0x75, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x22, 0x49, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x09, + 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x53, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x22, 0x54, + 0x0a, 0x13, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x76, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x05, 0x74, + 0x61, 0x73, 0x6b, 0x73, 0x22, 0xdd, 0x01, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x32, 0x0a, + 0x15, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x12, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x32, 0xe5, 0x03, 0x0a, 0x0b, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x53, 0x76, 0x63, 0x12, 0x46, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x13, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x12, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x53, 0x63, 0x65, 0x6e, + 0x61, 0x72, 0x69, 0x6f, 0x12, 0x49, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x3d, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, + 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1f, + 0x2e, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, + 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3b, 0x0a, 0x0c, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, + 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3e, 0x5a, 0x3c, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, + 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x3b, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_scenario_scenario_proto_rawDescOnce sync.Once + file_scenario_scenario_proto_rawDescData = file_scenario_scenario_proto_rawDesc +) + +func file_scenario_scenario_proto_rawDescGZIP() []byte { + file_scenario_scenario_proto_rawDescOnce.Do(func() { + file_scenario_scenario_proto_rawDescData = protoimpl.X.CompressGZIP(file_scenario_scenario_proto_rawDescData) + }) + return file_scenario_scenario_proto_rawDescData +} + +var file_scenario_scenario_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_scenario_scenario_proto_goTypes = []interface{}{ + (*Scenario)(nil), // 0: scenario.Scenario + (*CreateScenarioRequest)(nil), // 1: scenario.CreateScenarioRequest + (*ScenarioStep)(nil), // 2: scenario.ScenarioStep + (*UpdateScenarioRequest)(nil), // 3: scenario.UpdateScenarioRequest + (*ListScenariosResponse)(nil), // 4: scenario.ListScenariosResponse + (*VirtualMachineTasks)(nil), // 5: scenario.VirtualMachineTasks + (*Task)(nil), // 6: scenario.Task + nil, // 7: scenario.Scenario.LabelsEntry + (*general.StringMap)(nil), // 8: general.StringMap + (*wrapperspb.StringValue)(nil), // 9: google.protobuf.StringValue + (*wrapperspb.BoolValue)(nil), // 10: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 11: general.GetRequest + (*general.ResourceId)(nil), // 12: general.ResourceId + (*general.ListOptions)(nil), // 13: general.ListOptions + (*emptypb.Empty)(nil), // 14: google.protobuf.Empty +} +var file_scenario_scenario_proto_depIdxs = []int32{ + 2, // 0: scenario.Scenario.steps:type_name -> scenario.ScenarioStep + 8, // 1: scenario.Scenario.vms:type_name -> general.StringMap + 5, // 2: scenario.Scenario.vm_tasks:type_name -> scenario.VirtualMachineTasks + 7, // 3: scenario.Scenario.labels:type_name -> scenario.Scenario.LabelsEntry + 9, // 4: scenario.UpdateScenarioRequest.keepalive_duration:type_name -> google.protobuf.StringValue + 9, // 5: scenario.UpdateScenarioRequest.pause_duration:type_name -> google.protobuf.StringValue + 10, // 6: scenario.UpdateScenarioRequest.pausable:type_name -> google.protobuf.BoolValue + 0, // 7: scenario.ListScenariosResponse.scenarios:type_name -> scenario.Scenario + 6, // 8: scenario.VirtualMachineTasks.tasks:type_name -> scenario.Task + 1, // 9: scenario.ScenarioSvc.CreateScenario:input_type -> scenario.CreateScenarioRequest + 11, // 10: scenario.ScenarioSvc.GetScenario:input_type -> general.GetRequest + 3, // 11: scenario.ScenarioSvc.UpdateScenario:input_type -> scenario.UpdateScenarioRequest + 12, // 12: scenario.ScenarioSvc.DeleteScenario:input_type -> general.ResourceId + 13, // 13: scenario.ScenarioSvc.DeleteCollectionScenario:input_type -> general.ListOptions + 13, // 14: scenario.ScenarioSvc.ListScenario:input_type -> general.ListOptions + 12, // 15: scenario.ScenarioSvc.CopyScenario:input_type -> general.ResourceId + 12, // 16: scenario.ScenarioSvc.CreateScenario:output_type -> general.ResourceId + 0, // 17: scenario.ScenarioSvc.GetScenario:output_type -> scenario.Scenario + 14, // 18: scenario.ScenarioSvc.UpdateScenario:output_type -> google.protobuf.Empty + 14, // 19: scenario.ScenarioSvc.DeleteScenario:output_type -> google.protobuf.Empty + 14, // 20: scenario.ScenarioSvc.DeleteCollectionScenario:output_type -> google.protobuf.Empty + 4, // 21: scenario.ScenarioSvc.ListScenario:output_type -> scenario.ListScenariosResponse + 14, // 22: scenario.ScenarioSvc.CopyScenario:output_type -> google.protobuf.Empty + 16, // [16:23] is the sub-list for method output_type + 9, // [9:16] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_scenario_scenario_proto_init() } +func file_scenario_scenario_proto_init() { + if File_scenario_scenario_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_scenario_scenario_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Scenario); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateScenarioRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ScenarioStep); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateScenarioRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListScenariosResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VirtualMachineTasks); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scenario_scenario_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Task); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_scenario_scenario_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_scenario_scenario_proto_goTypes, + DependencyIndexes: file_scenario_scenario_proto_depIdxs, + MessageInfos: file_scenario_scenario_proto_msgTypes, + }.Build() + File_scenario_scenario_proto = out.File + file_scenario_scenario_proto_rawDesc = nil + file_scenario_scenario_proto_goTypes = nil + file_scenario_scenario_proto_depIdxs = nil +} diff --git a/v3/protos/scenario/scenario.proto b/v3/protos/scenario/scenario.proto new file mode 100644 index 00000000..eac62793 --- /dev/null +++ b/v3/protos/scenario/scenario.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; + +package scenario; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/scenario;scenariopb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service ScenarioSvc { + // Resource oriented functions: + rpc CreateScenario (CreateScenarioRequest) returns (general.ResourceId); + rpc GetScenario (general.GetRequest) returns (Scenario); + rpc UpdateScenario (UpdateScenarioRequest) returns (google.protobuf.Empty); + rpc DeleteScenario (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionScenario (general.ListOptions) returns (google.protobuf.Empty); + rpc ListScenario (general.ListOptions) returns (ListScenariosResponse); + // Helper functions: + rpc CopyScenario (general.ResourceId) returns (google.protobuf.Empty); +} + +message Scenario { + string id = 1; + string uid = 2; + string name = 3; + string description = 4; + repeated ScenarioStep steps = 5; + repeated string categories = 6; + repeated string tags = 7; + repeated general.StringMap vms = 8; + string keepalive_duration = 9; + string pause_duration = 10; + bool pausable = 11; + repeated VirtualMachineTasks vm_tasks = 12; + map labels = 13; +} + +message CreateScenarioRequest { + string name = 1; + string description = 2; + string raw_steps = 3; + string raw_categories = 4; + string raw_tags = 5; + string raw_vms = 6; + string raw_vm_tasks = 7; + string keepalive_duration = 8; + string pause_duration = 9; + bool pausable = 10; +} + +message ScenarioStep { + string title = 1; + string content = 2; +} + +message UpdateScenarioRequest { + string id = 1; + string name = 2; + string description = 3; + string raw_steps = 4; + string raw_categories = 5; + string raw_tags = 6; + string raw_vms = 7; + string raw_vm_tasks = 8; + google.protobuf.StringValue keepalive_duration = 9; + google.protobuf.StringValue pause_duration = 10; + google.protobuf.BoolValue pausable = 11; +} + +message ListScenariosResponse { + repeated Scenario scenarios = 1; +} + +message VirtualMachineTasks { + string vm_name = 1; + repeated Task tasks = 2; +} +message Task { + string name = 1; + string description = 2; + string command = 3; + string expected_output_value = 4; + int32 expected_return_code = 5; + string return_type = 6; +} \ No newline at end of file diff --git a/v3/protos/scenario/scenario_grpc.pb.go b/v3/protos/scenario/scenario_grpc.pb.go new file mode 100644 index 00000000..ea2f614e --- /dev/null +++ b/v3/protos/scenario/scenario_grpc.pb.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: scenario/scenario.proto + +package scenariopb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ScenarioSvc_CreateScenario_FullMethodName = "/scenario.ScenarioSvc/CreateScenario" + ScenarioSvc_GetScenario_FullMethodName = "/scenario.ScenarioSvc/GetScenario" + ScenarioSvc_UpdateScenario_FullMethodName = "/scenario.ScenarioSvc/UpdateScenario" + ScenarioSvc_DeleteScenario_FullMethodName = "/scenario.ScenarioSvc/DeleteScenario" + ScenarioSvc_DeleteCollectionScenario_FullMethodName = "/scenario.ScenarioSvc/DeleteCollectionScenario" + ScenarioSvc_ListScenario_FullMethodName = "/scenario.ScenarioSvc/ListScenario" + ScenarioSvc_CopyScenario_FullMethodName = "/scenario.ScenarioSvc/CopyScenario" +) + +// ScenarioSvcClient is the client API for ScenarioSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ScenarioSvcClient interface { + // Resource oriented functions: + CreateScenario(ctx context.Context, in *CreateScenarioRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetScenario(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Scenario, error) + UpdateScenario(ctx context.Context, in *UpdateScenarioRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteScenario(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionScenario(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListScenario(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListScenariosResponse, error) + // Helper functions: + CopyScenario(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type scenarioSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewScenarioSvcClient(cc grpc.ClientConnInterface) ScenarioSvcClient { + return &scenarioSvcClient{cc} +} + +func (c *scenarioSvcClient) CreateScenario(ctx context.Context, in *CreateScenarioRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, ScenarioSvc_CreateScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) GetScenario(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Scenario, error) { + out := new(Scenario) + err := c.cc.Invoke(ctx, ScenarioSvc_GetScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) UpdateScenario(ctx context.Context, in *UpdateScenarioRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScenarioSvc_UpdateScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) DeleteScenario(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScenarioSvc_DeleteScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) DeleteCollectionScenario(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScenarioSvc_DeleteCollectionScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) ListScenario(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListScenariosResponse, error) { + out := new(ListScenariosResponse) + err := c.cc.Invoke(ctx, ScenarioSvc_ListScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scenarioSvcClient) CopyScenario(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScenarioSvc_CopyScenario_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ScenarioSvcServer is the server API for ScenarioSvc service. +// All implementations must embed UnimplementedScenarioSvcServer +// for forward compatibility +type ScenarioSvcServer interface { + // Resource oriented functions: + CreateScenario(context.Context, *CreateScenarioRequest) (*general.ResourceId, error) + GetScenario(context.Context, *general.GetRequest) (*Scenario, error) + UpdateScenario(context.Context, *UpdateScenarioRequest) (*emptypb.Empty, error) + DeleteScenario(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionScenario(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListScenario(context.Context, *general.ListOptions) (*ListScenariosResponse, error) + // Helper functions: + CopyScenario(context.Context, *general.ResourceId) (*emptypb.Empty, error) + mustEmbedUnimplementedScenarioSvcServer() +} + +// UnimplementedScenarioSvcServer must be embedded to have forward compatible implementations. +type UnimplementedScenarioSvcServer struct { +} + +func (UnimplementedScenarioSvcServer) CreateScenario(context.Context, *CreateScenarioRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateScenario not implemented") +} +func (UnimplementedScenarioSvcServer) GetScenario(context.Context, *general.GetRequest) (*Scenario, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetScenario not implemented") +} +func (UnimplementedScenarioSvcServer) UpdateScenario(context.Context, *UpdateScenarioRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateScenario not implemented") +} +func (UnimplementedScenarioSvcServer) DeleteScenario(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteScenario not implemented") +} +func (UnimplementedScenarioSvcServer) DeleteCollectionScenario(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionScenario not implemented") +} +func (UnimplementedScenarioSvcServer) ListScenario(context.Context, *general.ListOptions) (*ListScenariosResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListScenario not implemented") +} +func (UnimplementedScenarioSvcServer) CopyScenario(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CopyScenario not implemented") +} +func (UnimplementedScenarioSvcServer) mustEmbedUnimplementedScenarioSvcServer() {} + +// UnsafeScenarioSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ScenarioSvcServer will +// result in compilation errors. +type UnsafeScenarioSvcServer interface { + mustEmbedUnimplementedScenarioSvcServer() +} + +func RegisterScenarioSvcServer(s grpc.ServiceRegistrar, srv ScenarioSvcServer) { + s.RegisterService(&ScenarioSvc_ServiceDesc, srv) +} + +func _ScenarioSvc_CreateScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateScenarioRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).CreateScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_CreateScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).CreateScenario(ctx, req.(*CreateScenarioRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_GetScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).GetScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_GetScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).GetScenario(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_UpdateScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateScenarioRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).UpdateScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_UpdateScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).UpdateScenario(ctx, req.(*UpdateScenarioRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_DeleteScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).DeleteScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_DeleteScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).DeleteScenario(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_DeleteCollectionScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).DeleteCollectionScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_DeleteCollectionScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).DeleteCollectionScenario(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_ListScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).ListScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_ListScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).ListScenario(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScenarioSvc_CopyScenario_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScenarioSvcServer).CopyScenario(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScenarioSvc_CopyScenario_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScenarioSvcServer).CopyScenario(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +// ScenarioSvc_ServiceDesc is the grpc.ServiceDesc for ScenarioSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ScenarioSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "scenario.ScenarioSvc", + HandlerType: (*ScenarioSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateScenario", + Handler: _ScenarioSvc_CreateScenario_Handler, + }, + { + MethodName: "GetScenario", + Handler: _ScenarioSvc_GetScenario_Handler, + }, + { + MethodName: "UpdateScenario", + Handler: _ScenarioSvc_UpdateScenario_Handler, + }, + { + MethodName: "DeleteScenario", + Handler: _ScenarioSvc_DeleteScenario_Handler, + }, + { + MethodName: "DeleteCollectionScenario", + Handler: _ScenarioSvc_DeleteCollectionScenario_Handler, + }, + { + MethodName: "ListScenario", + Handler: _ScenarioSvc_ListScenario_Handler, + }, + { + MethodName: "CopyScenario", + Handler: _ScenarioSvc_CopyScenario_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "scenario/scenario.proto", +} diff --git a/v3/protos/scheduledevent/scheduledevent.pb.go b/v3/protos/scheduledevent/scheduledevent.pb.go new file mode 100644 index 00000000..da8d4e35 --- /dev/null +++ b/v3/protos/scheduledevent/scheduledevent.pb.go @@ -0,0 +1,1204 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: scheduledevent/scheduledevent.proto + +package scheduledeventpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ScheduledEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty"` + StartTime string `protobuf:"bytes,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime string `protobuf:"bytes,7,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + OnDemand bool `protobuf:"varint,8,opt,name=on_demand,json=onDemand,proto3" json:"on_demand,omitempty"` + Printable bool `protobuf:"varint,9,opt,name=printable,proto3" json:"printable,omitempty"` + RestrictedBind bool `protobuf:"varint,10,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,11,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + RequiredVms map[string]*VMTemplateCountMap `protobuf:"bytes,12,rep,name=required_vms,json=requiredVms,proto3" json:"required_vms,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AccessCode string `protobuf:"bytes,13,opt,name=access_code,json=accessCode,proto3" json:"access_code,omitempty"` + Scenarios []string `protobuf:"bytes,14,rep,name=scenarios,proto3" json:"scenarios,omitempty"` + Courses []string `protobuf:"bytes,15,rep,name=courses,proto3" json:"courses,omitempty"` + Labels map[string]string `protobuf:"bytes,16,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Status *ScheduledEventStatus `protobuf:"bytes,17,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *ScheduledEvent) Reset() { + *x = ScheduledEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ScheduledEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ScheduledEvent) ProtoMessage() {} + +func (x *ScheduledEvent) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ScheduledEvent.ProtoReflect.Descriptor instead. +func (*ScheduledEvent) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{0} +} + +func (x *ScheduledEvent) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ScheduledEvent) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *ScheduledEvent) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ScheduledEvent) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ScheduledEvent) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +func (x *ScheduledEvent) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *ScheduledEvent) GetEndTime() string { + if x != nil { + return x.EndTime + } + return "" +} + +func (x *ScheduledEvent) GetOnDemand() bool { + if x != nil { + return x.OnDemand + } + return false +} + +func (x *ScheduledEvent) GetPrintable() bool { + if x != nil { + return x.Printable + } + return false +} + +func (x *ScheduledEvent) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *ScheduledEvent) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *ScheduledEvent) GetRequiredVms() map[string]*VMTemplateCountMap { + if x != nil { + return x.RequiredVms + } + return nil +} + +func (x *ScheduledEvent) GetAccessCode() string { + if x != nil { + return x.AccessCode + } + return "" +} + +func (x *ScheduledEvent) GetScenarios() []string { + if x != nil { + return x.Scenarios + } + return nil +} + +func (x *ScheduledEvent) GetCourses() []string { + if x != nil { + return x.Courses + } + return nil +} + +func (x *ScheduledEvent) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *ScheduledEvent) GetStatus() *ScheduledEventStatus { + if x != nil { + return x.Status + } + return nil +} + +type CreateScheduledEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The displayed scheduled event name, not id! + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Creator string `protobuf:"bytes,3,opt,name=creator,proto3" json:"creator,omitempty"` + StartTime string `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime string `protobuf:"bytes,5,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + OnDemand bool `protobuf:"varint,6,opt,name=on_demand,json=onDemand,proto3" json:"on_demand,omitempty"` + Printable bool `protobuf:"varint,7,opt,name=printable,proto3" json:"printable,omitempty"` + RestrictedBind bool `protobuf:"varint,8,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + // required_vms is mapping environments to their respective VMTemplateCountMap + RequiredVmsRaw string `protobuf:"bytes,9,opt,name=required_vms_raw,json=requiredVmsRaw,proto3" json:"required_vms_raw,omitempty"` + AccessCode string `protobuf:"bytes,10,opt,name=access_code,json=accessCode,proto3" json:"access_code,omitempty"` + ScenariosRaw string `protobuf:"bytes,11,opt,name=scenarios_raw,json=scenariosRaw,proto3" json:"scenarios_raw,omitempty"` + CoursesRaw string `protobuf:"bytes,12,opt,name=courses_raw,json=coursesRaw,proto3" json:"courses_raw,omitempty"` + Labels map[string]string `protobuf:"bytes,13,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CreateScheduledEventRequest) Reset() { + *x = CreateScheduledEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateScheduledEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateScheduledEventRequest) ProtoMessage() {} + +func (x *CreateScheduledEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateScheduledEventRequest.ProtoReflect.Descriptor instead. +func (*CreateScheduledEventRequest) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateScheduledEventRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateScheduledEventRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateScheduledEventRequest) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +func (x *CreateScheduledEventRequest) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *CreateScheduledEventRequest) GetEndTime() string { + if x != nil { + return x.EndTime + } + return "" +} + +func (x *CreateScheduledEventRequest) GetOnDemand() bool { + if x != nil { + return x.OnDemand + } + return false +} + +func (x *CreateScheduledEventRequest) GetPrintable() bool { + if x != nil { + return x.Printable + } + return false +} + +func (x *CreateScheduledEventRequest) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *CreateScheduledEventRequest) GetRequiredVmsRaw() string { + if x != nil { + return x.RequiredVmsRaw + } + return "" +} + +func (x *CreateScheduledEventRequest) GetAccessCode() string { + if x != nil { + return x.AccessCode + } + return "" +} + +func (x *CreateScheduledEventRequest) GetScenariosRaw() string { + if x != nil { + return x.ScenariosRaw + } + return "" +} + +func (x *CreateScheduledEventRequest) GetCoursesRaw() string { + if x != nil { + return x.CoursesRaw + } + return "" +} + +func (x *CreateScheduledEventRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +// This message is mapping vmtemplates to their required count within a scheduled event +type VMTemplateCountMap struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VmTemplateCounts map[string]uint32 `protobuf:"bytes,1,rep,name=vmTemplateCounts,proto3" json:"vmTemplateCounts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *VMTemplateCountMap) Reset() { + *x = VMTemplateCountMap{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMTemplateCountMap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMTemplateCountMap) ProtoMessage() {} + +func (x *VMTemplateCountMap) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMTemplateCountMap.ProtoReflect.Descriptor instead. +func (*VMTemplateCountMap) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{2} +} + +func (x *VMTemplateCountMap) GetVmTemplateCounts() map[string]uint32 { + if x != nil { + return x.VmTemplateCounts + } + return nil +} + +type UpdateScheduledEventRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + StartTime string `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime string `protobuf:"bytes,5,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + OnDemand *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=on_demand,json=onDemand,proto3" json:"on_demand,omitempty"` + Printable *wrapperspb.BoolValue `protobuf:"bytes,7,opt,name=printable,proto3" json:"printable,omitempty"` + RestrictedBind *wrapperspb.BoolValue `protobuf:"bytes,8,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + // required_vms is mapping environments to their respective VMTemplateCountMap + RequiredVmsRaw string `protobuf:"bytes,9,opt,name=required_vms_raw,json=requiredVmsRaw,proto3" json:"required_vms_raw,omitempty"` + AccessCode string `protobuf:"bytes,10,opt,name=access_code,json=accessCode,proto3" json:"access_code,omitempty"` + ScenariosRaw string `protobuf:"bytes,11,opt,name=scenarios_raw,json=scenariosRaw,proto3" json:"scenarios_raw,omitempty"` + CoursesRaw string `protobuf:"bytes,12,opt,name=courses_raw,json=coursesRaw,proto3" json:"courses_raw,omitempty"` +} + +func (x *UpdateScheduledEventRequest) Reset() { + *x = UpdateScheduledEventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateScheduledEventRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateScheduledEventRequest) ProtoMessage() {} + +func (x *UpdateScheduledEventRequest) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateScheduledEventRequest.ProtoReflect.Descriptor instead. +func (*UpdateScheduledEventRequest) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateScheduledEventRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetEndTime() string { + if x != nil { + return x.EndTime + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetOnDemand() *wrapperspb.BoolValue { + if x != nil { + return x.OnDemand + } + return nil +} + +func (x *UpdateScheduledEventRequest) GetPrintable() *wrapperspb.BoolValue { + if x != nil { + return x.Printable + } + return nil +} + +func (x *UpdateScheduledEventRequest) GetRestrictedBind() *wrapperspb.BoolValue { + if x != nil { + return x.RestrictedBind + } + return nil +} + +func (x *UpdateScheduledEventRequest) GetRequiredVmsRaw() string { + if x != nil { + return x.RequiredVmsRaw + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetAccessCode() string { + if x != nil { + return x.AccessCode + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetScenariosRaw() string { + if x != nil { + return x.ScenariosRaw + } + return "" +} + +func (x *UpdateScheduledEventRequest) GetCoursesRaw() string { + if x != nil { + return x.CoursesRaw + } + return "" +} + +type UpdateScheduledEventStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Vmsets *VMSetsWrapper `protobuf:"bytes,2,opt,name=vmsets,proto3" json:"vmsets,omitempty"` + Active *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=active,proto3" json:"active,omitempty"` + Provisioned *wrapperspb.BoolValue `protobuf:"bytes,4,opt,name=provisioned,proto3" json:"provisioned,omitempty"` + Ready *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=ready,proto3" json:"ready,omitempty"` + Finished *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=finished,proto3" json:"finished,omitempty"` +} + +func (x *UpdateScheduledEventStatusRequest) Reset() { + *x = UpdateScheduledEventStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateScheduledEventStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateScheduledEventStatusRequest) ProtoMessage() {} + +func (x *UpdateScheduledEventStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateScheduledEventStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateScheduledEventStatusRequest) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateScheduledEventStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateScheduledEventStatusRequest) GetVmsets() *VMSetsWrapper { + if x != nil { + return x.Vmsets + } + return nil +} + +func (x *UpdateScheduledEventStatusRequest) GetActive() *wrapperspb.BoolValue { + if x != nil { + return x.Active + } + return nil +} + +func (x *UpdateScheduledEventStatusRequest) GetProvisioned() *wrapperspb.BoolValue { + if x != nil { + return x.Provisioned + } + return nil +} + +func (x *UpdateScheduledEventStatusRequest) GetReady() *wrapperspb.BoolValue { + if x != nil { + return x.Ready + } + return nil +} + +func (x *UpdateScheduledEventStatusRequest) GetFinished() *wrapperspb.BoolValue { + if x != nil { + return x.Finished + } + return nil +} + +type VMSetsWrapper struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value []string `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"` +} + +func (x *VMSetsWrapper) Reset() { + *x = VMSetsWrapper{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMSetsWrapper) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMSetsWrapper) ProtoMessage() {} + +func (x *VMSetsWrapper) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMSetsWrapper.ProtoReflect.Descriptor instead. +func (*VMSetsWrapper) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{5} +} + +func (x *VMSetsWrapper) GetValue() []string { + if x != nil { + return x.Value + } + return nil +} + +type ScheduledEventStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vmsets []string `protobuf:"bytes,1,rep,name=vmsets,proto3" json:"vmsets,omitempty"` + Active bool `protobuf:"varint,2,opt,name=active,proto3" json:"active,omitempty"` + Provisioned bool `protobuf:"varint,3,opt,name=provisioned,proto3" json:"provisioned,omitempty"` + Ready bool `protobuf:"varint,4,opt,name=ready,proto3" json:"ready,omitempty"` + Finished bool `protobuf:"varint,5,opt,name=finished,proto3" json:"finished,omitempty"` +} + +func (x *ScheduledEventStatus) Reset() { + *x = ScheduledEventStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ScheduledEventStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ScheduledEventStatus) ProtoMessage() {} + +func (x *ScheduledEventStatus) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ScheduledEventStatus.ProtoReflect.Descriptor instead. +func (*ScheduledEventStatus) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{6} +} + +func (x *ScheduledEventStatus) GetVmsets() []string { + if x != nil { + return x.Vmsets + } + return nil +} + +func (x *ScheduledEventStatus) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +func (x *ScheduledEventStatus) GetProvisioned() bool { + if x != nil { + return x.Provisioned + } + return false +} + +func (x *ScheduledEventStatus) GetReady() bool { + if x != nil { + return x.Ready + } + return false +} + +func (x *ScheduledEventStatus) GetFinished() bool { + if x != nil { + return x.Finished + } + return false +} + +type ListScheduledEventsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scheduledevents []*ScheduledEvent `protobuf:"bytes,1,rep,name=scheduledevents,proto3" json:"scheduledevents,omitempty"` +} + +func (x *ListScheduledEventsResponse) Reset() { + *x = ListScheduledEventsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListScheduledEventsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListScheduledEventsResponse) ProtoMessage() {} + +func (x *ListScheduledEventsResponse) ProtoReflect() protoreflect.Message { + mi := &file_scheduledevent_scheduledevent_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListScheduledEventsResponse.ProtoReflect.Descriptor instead. +func (*ListScheduledEventsResponse) Descriptor() ([]byte, []int) { + return file_scheduledevent_scheduledevent_proto_rawDescGZIP(), []int{7} +} + +func (x *ListScheduledEventsResponse) GetScheduledevents() []*ScheduledEvent { + if x != nil { + return x.Scheduledevents + } + return nil +} + +var File_scheduledevent_scheduledevent_proto protoreflect.FileDescriptor + +var file_scheduledevent_scheduledevent_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, 0x06, 0x0a, 0x0e, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x6e, 0x44, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x52, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x76, 0x6d, 0x73, + 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x56, + 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x56, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, + 0x6f, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x18, 0x0f, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x12, 0x42, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0x62, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x56, 0x6d, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa8, + 0x04, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x6e, 0x44, + 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x28, 0x0a, 0x10, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x76, 0x6d, 0x73, 0x5f, 0x72, 0x61, 0x77, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x56, 0x6d, 0x73, 0x52, 0x61, 0x77, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x63, 0x65, 0x6e, 0x61, + 0x72, 0x69, 0x6f, 0x73, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x52, 0x61, 0x77, 0x12, 0x1f, 0x0a, 0x0b, + 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x52, 0x61, 0x77, 0x12, 0x4f, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, + 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbf, 0x01, 0x0a, 0x12, 0x56, 0x4d, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x70, + 0x12, 0x64, 0x0a, 0x10, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x4d, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x2e, 0x56, + 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x43, 0x0a, 0x15, 0x56, 0x6d, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe6, 0x03, 0x0a, 0x1b, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x6f, + 0x6e, 0x5f, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x6e, 0x44, 0x65, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x43, + 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, + 0x69, 0x6e, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, + 0x76, 0x6d, 0x73, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x56, 0x6d, 0x73, 0x52, 0x61, 0x77, 0x12, 0x1f, 0x0a, + 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, 0x5f, 0x72, 0x61, 0x77, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x73, + 0x52, 0x61, 0x77, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x5f, 0x72, + 0x61, 0x77, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, + 0x73, 0x52, 0x61, 0x77, 0x22, 0xc6, 0x02, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x06, 0x76, 0x6d, + 0x73, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x56, 0x4d, 0x53, 0x65, + 0x74, 0x73, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x06, 0x76, 0x6d, 0x73, 0x65, 0x74, + 0x73, 0x12, 0x32, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x22, 0x25, 0x0a, + 0x0d, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x73, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x14, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, + 0x6d, 0x73, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x22, 0x67, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x48, 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x32, 0xeb, 0x04, 0x0a, 0x11, 0x53, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x76, 0x63, + 0x12, 0x58, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x48, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x5b, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x67, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x14, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x4e, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x57, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x2b, 0x2e, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, + 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x3b, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_scheduledevent_scheduledevent_proto_rawDescOnce sync.Once + file_scheduledevent_scheduledevent_proto_rawDescData = file_scheduledevent_scheduledevent_proto_rawDesc +) + +func file_scheduledevent_scheduledevent_proto_rawDescGZIP() []byte { + file_scheduledevent_scheduledevent_proto_rawDescOnce.Do(func() { + file_scheduledevent_scheduledevent_proto_rawDescData = protoimpl.X.CompressGZIP(file_scheduledevent_scheduledevent_proto_rawDescData) + }) + return file_scheduledevent_scheduledevent_proto_rawDescData +} + +var file_scheduledevent_scheduledevent_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_scheduledevent_scheduledevent_proto_goTypes = []interface{}{ + (*ScheduledEvent)(nil), // 0: scheduledevent.ScheduledEvent + (*CreateScheduledEventRequest)(nil), // 1: scheduledevent.CreateScheduledEventRequest + (*VMTemplateCountMap)(nil), // 2: scheduledevent.VMTemplateCountMap + (*UpdateScheduledEventRequest)(nil), // 3: scheduledevent.UpdateScheduledEventRequest + (*UpdateScheduledEventStatusRequest)(nil), // 4: scheduledevent.UpdateScheduledEventStatusRequest + (*VMSetsWrapper)(nil), // 5: scheduledevent.VMSetsWrapper + (*ScheduledEventStatus)(nil), // 6: scheduledevent.ScheduledEventStatus + (*ListScheduledEventsResponse)(nil), // 7: scheduledevent.ListScheduledEventsResponse + nil, // 8: scheduledevent.ScheduledEvent.RequiredVmsEntry + nil, // 9: scheduledevent.ScheduledEvent.LabelsEntry + nil, // 10: scheduledevent.CreateScheduledEventRequest.LabelsEntry + nil, // 11: scheduledevent.VMTemplateCountMap.VmTemplateCountsEntry + (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 13: general.GetRequest + (*general.ResourceId)(nil), // 14: general.ResourceId + (*general.ListOptions)(nil), // 15: general.ListOptions + (*emptypb.Empty)(nil), // 16: google.protobuf.Empty +} +var file_scheduledevent_scheduledevent_proto_depIdxs = []int32{ + 8, // 0: scheduledevent.ScheduledEvent.required_vms:type_name -> scheduledevent.ScheduledEvent.RequiredVmsEntry + 9, // 1: scheduledevent.ScheduledEvent.labels:type_name -> scheduledevent.ScheduledEvent.LabelsEntry + 6, // 2: scheduledevent.ScheduledEvent.status:type_name -> scheduledevent.ScheduledEventStatus + 10, // 3: scheduledevent.CreateScheduledEventRequest.labels:type_name -> scheduledevent.CreateScheduledEventRequest.LabelsEntry + 11, // 4: scheduledevent.VMTemplateCountMap.vmTemplateCounts:type_name -> scheduledevent.VMTemplateCountMap.VmTemplateCountsEntry + 12, // 5: scheduledevent.UpdateScheduledEventRequest.on_demand:type_name -> google.protobuf.BoolValue + 12, // 6: scheduledevent.UpdateScheduledEventRequest.printable:type_name -> google.protobuf.BoolValue + 12, // 7: scheduledevent.UpdateScheduledEventRequest.restricted_bind:type_name -> google.protobuf.BoolValue + 5, // 8: scheduledevent.UpdateScheduledEventStatusRequest.vmsets:type_name -> scheduledevent.VMSetsWrapper + 12, // 9: scheduledevent.UpdateScheduledEventStatusRequest.active:type_name -> google.protobuf.BoolValue + 12, // 10: scheduledevent.UpdateScheduledEventStatusRequest.provisioned:type_name -> google.protobuf.BoolValue + 12, // 11: scheduledevent.UpdateScheduledEventStatusRequest.ready:type_name -> google.protobuf.BoolValue + 12, // 12: scheduledevent.UpdateScheduledEventStatusRequest.finished:type_name -> google.protobuf.BoolValue + 0, // 13: scheduledevent.ListScheduledEventsResponse.scheduledevents:type_name -> scheduledevent.ScheduledEvent + 2, // 14: scheduledevent.ScheduledEvent.RequiredVmsEntry.value:type_name -> scheduledevent.VMTemplateCountMap + 1, // 15: scheduledevent.ScheduledEventSvc.CreateScheduledEvent:input_type -> scheduledevent.CreateScheduledEventRequest + 13, // 16: scheduledevent.ScheduledEventSvc.GetScheduledEvent:input_type -> general.GetRequest + 3, // 17: scheduledevent.ScheduledEventSvc.UpdateScheduledEvent:input_type -> scheduledevent.UpdateScheduledEventRequest + 4, // 18: scheduledevent.ScheduledEventSvc.UpdateScheduledEventStatus:input_type -> scheduledevent.UpdateScheduledEventStatusRequest + 14, // 19: scheduledevent.ScheduledEventSvc.DeleteScheduledEvent:input_type -> general.ResourceId + 15, // 20: scheduledevent.ScheduledEventSvc.DeleteCollectionScheduledEvent:input_type -> general.ListOptions + 15, // 21: scheduledevent.ScheduledEventSvc.ListScheduledEvent:input_type -> general.ListOptions + 14, // 22: scheduledevent.ScheduledEventSvc.CreateScheduledEvent:output_type -> general.ResourceId + 0, // 23: scheduledevent.ScheduledEventSvc.GetScheduledEvent:output_type -> scheduledevent.ScheduledEvent + 16, // 24: scheduledevent.ScheduledEventSvc.UpdateScheduledEvent:output_type -> google.protobuf.Empty + 16, // 25: scheduledevent.ScheduledEventSvc.UpdateScheduledEventStatus:output_type -> google.protobuf.Empty + 16, // 26: scheduledevent.ScheduledEventSvc.DeleteScheduledEvent:output_type -> google.protobuf.Empty + 16, // 27: scheduledevent.ScheduledEventSvc.DeleteCollectionScheduledEvent:output_type -> google.protobuf.Empty + 7, // 28: scheduledevent.ScheduledEventSvc.ListScheduledEvent:output_type -> scheduledevent.ListScheduledEventsResponse + 22, // [22:29] is the sub-list for method output_type + 15, // [15:22] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name +} + +func init() { file_scheduledevent_scheduledevent_proto_init() } +func file_scheduledevent_scheduledevent_proto_init() { + if File_scheduledevent_scheduledevent_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_scheduledevent_scheduledevent_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ScheduledEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateScheduledEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMTemplateCountMap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateScheduledEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateScheduledEventStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMSetsWrapper); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ScheduledEventStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_scheduledevent_scheduledevent_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListScheduledEventsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_scheduledevent_scheduledevent_proto_rawDesc, + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_scheduledevent_scheduledevent_proto_goTypes, + DependencyIndexes: file_scheduledevent_scheduledevent_proto_depIdxs, + MessageInfos: file_scheduledevent_scheduledevent_proto_msgTypes, + }.Build() + File_scheduledevent_scheduledevent_proto = out.File + file_scheduledevent_scheduledevent_proto_rawDesc = nil + file_scheduledevent_scheduledevent_proto_goTypes = nil + file_scheduledevent_scheduledevent_proto_depIdxs = nil +} diff --git a/v3/protos/scheduledevent/scheduledevent.proto b/v3/protos/scheduledevent/scheduledevent.proto new file mode 100644 index 00000000..98dcdf9b --- /dev/null +++ b/v3/protos/scheduledevent/scheduledevent.proto @@ -0,0 +1,102 @@ +syntax = "proto3"; + +package scheduledevent; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent;scheduledeventpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service ScheduledEventSvc { + rpc CreateScheduledEvent (CreateScheduledEventRequest) returns (general.ResourceId); + rpc GetScheduledEvent (general.GetRequest) returns (ScheduledEvent); + rpc UpdateScheduledEvent (UpdateScheduledEventRequest) returns (google.protobuf.Empty); + rpc UpdateScheduledEventStatus (UpdateScheduledEventStatusRequest) returns (google.protobuf.Empty); + rpc DeleteScheduledEvent (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionScheduledEvent (general.ListOptions) returns (google.protobuf.Empty); + rpc ListScheduledEvent (general.ListOptions) returns (ListScheduledEventsResponse); +} + +message ScheduledEvent { + string id = 1; + string uid = 2; + string name = 3; + string description = 4; + string creator = 5; + string start_time = 6; + string end_time = 7; + bool on_demand = 8; + bool printable = 9; + bool restricted_bind = 10; + string restricted_bind_value = 11; + map required_vms = 12; + string access_code = 13; + repeated string scenarios = 14; + repeated string courses = 15; + map labels = 16; + ScheduledEventStatus status = 17; +} + +message CreateScheduledEventRequest { + string name = 1; // The displayed scheduled event name, not id! + string description = 2; + string creator = 3; + string start_time = 4; + string end_time = 5; + bool on_demand = 6; + bool printable = 7; + bool restricted_bind = 8; + // required_vms is mapping environments to their respective VMTemplateCountMap + string required_vms_raw = 9; + string access_code = 10; + string scenarios_raw = 11; + string courses_raw = 12; + map labels = 13; +} + +// This message is mapping vmtemplates to their required count within a scheduled event +message VMTemplateCountMap { + map vmTemplateCounts = 1; +} + +message UpdateScheduledEventRequest { + string id = 1; + string name = 2; + string description = 3; + string start_time = 4; + string end_time = 5; + google.protobuf.BoolValue on_demand = 6; + google.protobuf.BoolValue printable = 7; + google.protobuf.BoolValue restricted_bind = 8; + // required_vms is mapping environments to their respective VMTemplateCountMap + string required_vms_raw = 9; + string access_code = 10; + string scenarios_raw = 11; + string courses_raw = 12; +} + +message UpdateScheduledEventStatusRequest { + string id = 1; + VMSetsWrapper vmsets = 2; + google.protobuf.BoolValue active = 3; + google.protobuf.BoolValue provisioned = 4; + google.protobuf.BoolValue ready = 5; + google.protobuf.BoolValue finished = 6; +} + +message VMSetsWrapper { + repeated string value = 1; +} + +message ScheduledEventStatus { + repeated string vmsets = 1; + bool active = 2; + bool provisioned = 3; + bool ready = 4; + bool finished = 5; +} + +message ListScheduledEventsResponse { + repeated ScheduledEvent scheduledevents = 1; +} \ No newline at end of file diff --git a/v3/protos/scheduledevent/scheduledevent_grpc.pb.go b/v3/protos/scheduledevent/scheduledevent_grpc.pb.go new file mode 100644 index 00000000..606c019d --- /dev/null +++ b/v3/protos/scheduledevent/scheduledevent_grpc.pb.go @@ -0,0 +1,333 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: scheduledevent/scheduledevent.proto + +package scheduledeventpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ScheduledEventSvc_CreateScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/CreateScheduledEvent" + ScheduledEventSvc_GetScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/GetScheduledEvent" + ScheduledEventSvc_UpdateScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/UpdateScheduledEvent" + ScheduledEventSvc_UpdateScheduledEventStatus_FullMethodName = "/scheduledevent.ScheduledEventSvc/UpdateScheduledEventStatus" + ScheduledEventSvc_DeleteScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/DeleteScheduledEvent" + ScheduledEventSvc_DeleteCollectionScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/DeleteCollectionScheduledEvent" + ScheduledEventSvc_ListScheduledEvent_FullMethodName = "/scheduledevent.ScheduledEventSvc/ListScheduledEvent" +) + +// ScheduledEventSvcClient is the client API for ScheduledEventSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ScheduledEventSvcClient interface { + CreateScheduledEvent(ctx context.Context, in *CreateScheduledEventRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetScheduledEvent(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*ScheduledEvent, error) + UpdateScheduledEvent(ctx context.Context, in *UpdateScheduledEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateScheduledEventStatus(ctx context.Context, in *UpdateScheduledEventStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteScheduledEvent(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionScheduledEvent(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListScheduledEvent(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListScheduledEventsResponse, error) +} + +type scheduledEventSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewScheduledEventSvcClient(cc grpc.ClientConnInterface) ScheduledEventSvcClient { + return &scheduledEventSvcClient{cc} +} + +func (c *scheduledEventSvcClient) CreateScheduledEvent(ctx context.Context, in *CreateScheduledEventRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, ScheduledEventSvc_CreateScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) GetScheduledEvent(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*ScheduledEvent, error) { + out := new(ScheduledEvent) + err := c.cc.Invoke(ctx, ScheduledEventSvc_GetScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) UpdateScheduledEvent(ctx context.Context, in *UpdateScheduledEventRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScheduledEventSvc_UpdateScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) UpdateScheduledEventStatus(ctx context.Context, in *UpdateScheduledEventStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScheduledEventSvc_UpdateScheduledEventStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) DeleteScheduledEvent(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScheduledEventSvc_DeleteScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) DeleteCollectionScheduledEvent(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, ScheduledEventSvc_DeleteCollectionScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *scheduledEventSvcClient) ListScheduledEvent(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListScheduledEventsResponse, error) { + out := new(ListScheduledEventsResponse) + err := c.cc.Invoke(ctx, ScheduledEventSvc_ListScheduledEvent_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ScheduledEventSvcServer is the server API for ScheduledEventSvc service. +// All implementations must embed UnimplementedScheduledEventSvcServer +// for forward compatibility +type ScheduledEventSvcServer interface { + CreateScheduledEvent(context.Context, *CreateScheduledEventRequest) (*general.ResourceId, error) + GetScheduledEvent(context.Context, *general.GetRequest) (*ScheduledEvent, error) + UpdateScheduledEvent(context.Context, *UpdateScheduledEventRequest) (*emptypb.Empty, error) + UpdateScheduledEventStatus(context.Context, *UpdateScheduledEventStatusRequest) (*emptypb.Empty, error) + DeleteScheduledEvent(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionScheduledEvent(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListScheduledEvent(context.Context, *general.ListOptions) (*ListScheduledEventsResponse, error) + mustEmbedUnimplementedScheduledEventSvcServer() +} + +// UnimplementedScheduledEventSvcServer must be embedded to have forward compatible implementations. +type UnimplementedScheduledEventSvcServer struct { +} + +func (UnimplementedScheduledEventSvcServer) CreateScheduledEvent(context.Context, *CreateScheduledEventRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) GetScheduledEvent(context.Context, *general.GetRequest) (*ScheduledEvent, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) UpdateScheduledEvent(context.Context, *UpdateScheduledEventRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) UpdateScheduledEventStatus(context.Context, *UpdateScheduledEventStatusRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateScheduledEventStatus not implemented") +} +func (UnimplementedScheduledEventSvcServer) DeleteScheduledEvent(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) DeleteCollectionScheduledEvent(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) ListScheduledEvent(context.Context, *general.ListOptions) (*ListScheduledEventsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListScheduledEvent not implemented") +} +func (UnimplementedScheduledEventSvcServer) mustEmbedUnimplementedScheduledEventSvcServer() {} + +// UnsafeScheduledEventSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ScheduledEventSvcServer will +// result in compilation errors. +type UnsafeScheduledEventSvcServer interface { + mustEmbedUnimplementedScheduledEventSvcServer() +} + +func RegisterScheduledEventSvcServer(s grpc.ServiceRegistrar, srv ScheduledEventSvcServer) { + s.RegisterService(&ScheduledEventSvc_ServiceDesc, srv) +} + +func _ScheduledEventSvc_CreateScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateScheduledEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).CreateScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_CreateScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).CreateScheduledEvent(ctx, req.(*CreateScheduledEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_GetScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).GetScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_GetScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).GetScheduledEvent(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_UpdateScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateScheduledEventRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).UpdateScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_UpdateScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).UpdateScheduledEvent(ctx, req.(*UpdateScheduledEventRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_UpdateScheduledEventStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateScheduledEventStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).UpdateScheduledEventStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_UpdateScheduledEventStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).UpdateScheduledEventStatus(ctx, req.(*UpdateScheduledEventStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_DeleteScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).DeleteScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_DeleteScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).DeleteScheduledEvent(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_DeleteCollectionScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).DeleteCollectionScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_DeleteCollectionScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).DeleteCollectionScheduledEvent(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _ScheduledEventSvc_ListScheduledEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ScheduledEventSvcServer).ListScheduledEvent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ScheduledEventSvc_ListScheduledEvent_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ScheduledEventSvcServer).ListScheduledEvent(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// ScheduledEventSvc_ServiceDesc is the grpc.ServiceDesc for ScheduledEventSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ScheduledEventSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "scheduledevent.ScheduledEventSvc", + HandlerType: (*ScheduledEventSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateScheduledEvent", + Handler: _ScheduledEventSvc_CreateScheduledEvent_Handler, + }, + { + MethodName: "GetScheduledEvent", + Handler: _ScheduledEventSvc_GetScheduledEvent_Handler, + }, + { + MethodName: "UpdateScheduledEvent", + Handler: _ScheduledEventSvc_UpdateScheduledEvent_Handler, + }, + { + MethodName: "UpdateScheduledEventStatus", + Handler: _ScheduledEventSvc_UpdateScheduledEventStatus_Handler, + }, + { + MethodName: "DeleteScheduledEvent", + Handler: _ScheduledEventSvc_DeleteScheduledEvent_Handler, + }, + { + MethodName: "DeleteCollectionScheduledEvent", + Handler: _ScheduledEventSvc_DeleteCollectionScheduledEvent_Handler, + }, + { + MethodName: "ListScheduledEvent", + Handler: _ScheduledEventSvc_ListScheduledEvent_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "scheduledevent/scheduledevent.proto", +} diff --git a/v3/protos/session/session.pb.go b/v3/protos/session/session.pb.go new file mode 100644 index 00000000..b5ea9618 --- /dev/null +++ b/v3/protos/session/session.pb.go @@ -0,0 +1,816 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: session/session.proto + +package sessionpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Session struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Scenario string `protobuf:"bytes,3,opt,name=scenario,proto3" json:"scenario,omitempty"` + Course string `protobuf:"bytes,4,opt,name=course,proto3" json:"course,omitempty"` + KeepCourseVm bool `protobuf:"varint,5,opt,name=keep_course_vm,json=keepCourseVm,proto3" json:"keep_course_vm,omitempty"` + User string `protobuf:"bytes,6,opt,name=user,proto3" json:"user,omitempty"` + VmClaim []string `protobuf:"bytes,7,rep,name=vm_claim,json=vmClaim,proto3" json:"vm_claim,omitempty"` + AccessCode string `protobuf:"bytes,8,opt,name=access_code,json=accessCode,proto3" json:"access_code,omitempty"` + Labels map[string]string `protobuf:"bytes,9,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Status *SessionStatus `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *Session) Reset() { + *x = Session{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Session) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Session) ProtoMessage() {} + +func (x *Session) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Session.ProtoReflect.Descriptor instead. +func (*Session) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{0} +} + +func (x *Session) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Session) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *Session) GetScenario() string { + if x != nil { + return x.Scenario + } + return "" +} + +func (x *Session) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *Session) GetKeepCourseVm() bool { + if x != nil { + return x.KeepCourseVm + } + return false +} + +func (x *Session) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *Session) GetVmClaim() []string { + if x != nil { + return x.VmClaim + } + return nil +} + +func (x *Session) GetAccessCode() string { + if x != nil { + return x.AccessCode + } + return "" +} + +func (x *Session) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Session) GetStatus() *SessionStatus { + if x != nil { + return x.Status + } + return nil +} + +type CreateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scenario string `protobuf:"bytes,1,opt,name=scenario,proto3" json:"scenario,omitempty"` + Course string `protobuf:"bytes,2,opt,name=course,proto3" json:"course,omitempty"` + KeepCourseVm bool `protobuf:"varint,3,opt,name=keep_course_vm,json=keepCourseVm,proto3" json:"keep_course_vm,omitempty"` + User string `protobuf:"bytes,4,opt,name=user,proto3" json:"user,omitempty"` + VmClaim []string `protobuf:"bytes,5,rep,name=vm_claim,json=vmClaim,proto3" json:"vm_claim,omitempty"` + AccessCode string `protobuf:"bytes,6,opt,name=access_code,json=accessCode,proto3" json:"access_code,omitempty"` + Labels map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CreateSessionRequest) Reset() { + *x = CreateSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSessionRequest) ProtoMessage() {} + +func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateSessionRequest.ProtoReflect.Descriptor instead. +func (*CreateSessionRequest) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateSessionRequest) GetScenario() string { + if x != nil { + return x.Scenario + } + return "" +} + +func (x *CreateSessionRequest) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *CreateSessionRequest) GetKeepCourseVm() bool { + if x != nil { + return x.KeepCourseVm + } + return false +} + +func (x *CreateSessionRequest) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *CreateSessionRequest) GetVmClaim() []string { + if x != nil { + return x.VmClaim + } + return nil +} + +func (x *CreateSessionRequest) GetAccessCode() string { + if x != nil { + return x.AccessCode + } + return "" +} + +func (x *CreateSessionRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +// Currently sessions are bound to a course, user and access code +// Thus, only the scenario for a session can be updated +type UpdateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Scenario string `protobuf:"bytes,2,opt,name=scenario,proto3" json:"scenario,omitempty"` +} + +func (x *UpdateSessionRequest) Reset() { + *x = UpdateSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionRequest) ProtoMessage() {} + +func (x *UpdateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSessionRequest.ProtoReflect.Descriptor instead. +func (*UpdateSessionRequest) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateSessionRequest) GetScenario() string { + if x != nil { + return x.Scenario + } + return "" +} + +type UpdateSessionStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Paused *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=paused,proto3" json:"paused,omitempty"` + PausedTime *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=paused_time,json=pausedTime,proto3" json:"paused_time,omitempty"` + Active *wrapperspb.BoolValue `protobuf:"bytes,4,opt,name=active,proto3" json:"active,omitempty"` + Finished *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=finished,proto3" json:"finished,omitempty"` + StartTime string `protobuf:"bytes,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + ExpirationTime string `protobuf:"bytes,7,opt,name=expiration_time,json=expirationTime,proto3" json:"expiration_time,omitempty"` +} + +func (x *UpdateSessionStatusRequest) Reset() { + *x = UpdateSessionStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSessionStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionStatusRequest) ProtoMessage() {} + +func (x *UpdateSessionStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSessionStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateSessionStatusRequest) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateSessionStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateSessionStatusRequest) GetPaused() *wrapperspb.BoolValue { + if x != nil { + return x.Paused + } + return nil +} + +func (x *UpdateSessionStatusRequest) GetPausedTime() *wrapperspb.StringValue { + if x != nil { + return x.PausedTime + } + return nil +} + +func (x *UpdateSessionStatusRequest) GetActive() *wrapperspb.BoolValue { + if x != nil { + return x.Active + } + return nil +} + +func (x *UpdateSessionStatusRequest) GetFinished() *wrapperspb.BoolValue { + if x != nil { + return x.Finished + } + return nil +} + +func (x *UpdateSessionStatusRequest) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *UpdateSessionStatusRequest) GetExpirationTime() string { + if x != nil { + return x.ExpirationTime + } + return "" +} + +type SessionStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Paused bool `protobuf:"varint,1,opt,name=paused,proto3" json:"paused,omitempty"` + PausedTime string `protobuf:"bytes,2,opt,name=paused_time,json=pausedTime,proto3" json:"paused_time,omitempty"` + Active bool `protobuf:"varint,3,opt,name=active,proto3" json:"active,omitempty"` + Finished bool `protobuf:"varint,4,opt,name=finished,proto3" json:"finished,omitempty"` + StartTime string `protobuf:"bytes,5,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + ExpirationTime string `protobuf:"bytes,6,opt,name=expiration_time,json=expirationTime,proto3" json:"expiration_time,omitempty"` +} + +func (x *SessionStatus) Reset() { + *x = SessionStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SessionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionStatus) ProtoMessage() {} + +func (x *SessionStatus) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionStatus.ProtoReflect.Descriptor instead. +func (*SessionStatus) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{4} +} + +func (x *SessionStatus) GetPaused() bool { + if x != nil { + return x.Paused + } + return false +} + +func (x *SessionStatus) GetPausedTime() string { + if x != nil { + return x.PausedTime + } + return "" +} + +func (x *SessionStatus) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +func (x *SessionStatus) GetFinished() bool { + if x != nil { + return x.Finished + } + return false +} + +func (x *SessionStatus) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *SessionStatus) GetExpirationTime() string { + if x != nil { + return x.ExpirationTime + } + return "" +} + +type ListSessionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sessions []*Session `protobuf:"bytes,1,rep,name=sessions,proto3" json:"sessions,omitempty"` +} + +func (x *ListSessionsResponse) Reset() { + *x = ListSessionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_session_session_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListSessionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSessionsResponse) ProtoMessage() {} + +func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_session_session_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListSessionsResponse.ProtoReflect.Descriptor instead. +func (*ListSessionsResponse) Descriptor() ([]byte, []int) { + return file_session_session_proto_rawDescGZIP(), []int{5} +} + +func (x *ListSessionsResponse) GetSessions() []*Session { + if x != nil { + return x.Sessions + } + return nil +} + +var File_session_session_proto protoreflect.FileDescriptor + +var file_session_session_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x02, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, 0x69, 0x6f, 0x12, 0x16, + 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x63, + 0x6f, 0x75, 0x72, 0x73, 0x65, 0x5f, 0x76, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x6b, 0x65, 0x65, 0x70, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x56, 0x6d, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x12, 0x19, 0x0a, 0x08, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x34, 0x0a, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x02, + 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65, + 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x5f, 0x76, 0x6d, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x56, 0x6d, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, + 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x41, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x42, + 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x65, 0x6e, 0x61, 0x72, + 0x69, 0x6f, 0x22, 0xd3, 0x02, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x32, 0x0a, 0x06, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, + 0x61, 0x75, 0x73, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x0b, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, + 0x75, 0x73, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x75, 0x73, + 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x75, 0x73, 0x65, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x66, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, + 0x44, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0xed, 0x03, 0x0a, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x76, 0x63, 0x12, 0x43, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x46, + 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1d, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x52, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x42, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1d, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, + 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x73, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_session_session_proto_rawDescOnce sync.Once + file_session_session_proto_rawDescData = file_session_session_proto_rawDesc +) + +func file_session_session_proto_rawDescGZIP() []byte { + file_session_session_proto_rawDescOnce.Do(func() { + file_session_session_proto_rawDescData = protoimpl.X.CompressGZIP(file_session_session_proto_rawDescData) + }) + return file_session_session_proto_rawDescData +} + +var file_session_session_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_session_session_proto_goTypes = []interface{}{ + (*Session)(nil), // 0: session.Session + (*CreateSessionRequest)(nil), // 1: session.CreateSessionRequest + (*UpdateSessionRequest)(nil), // 2: session.UpdateSessionRequest + (*UpdateSessionStatusRequest)(nil), // 3: session.UpdateSessionStatusRequest + (*SessionStatus)(nil), // 4: session.SessionStatus + (*ListSessionsResponse)(nil), // 5: session.ListSessionsResponse + nil, // 6: session.Session.LabelsEntry + nil, // 7: session.CreateSessionRequest.LabelsEntry + (*wrapperspb.BoolValue)(nil), // 8: google.protobuf.BoolValue + (*wrapperspb.StringValue)(nil), // 9: google.protobuf.StringValue + (*general.GetRequest)(nil), // 10: general.GetRequest + (*general.ResourceId)(nil), // 11: general.ResourceId + (*general.ListOptions)(nil), // 12: general.ListOptions + (*emptypb.Empty)(nil), // 13: google.protobuf.Empty +} +var file_session_session_proto_depIdxs = []int32{ + 6, // 0: session.Session.labels:type_name -> session.Session.LabelsEntry + 4, // 1: session.Session.status:type_name -> session.SessionStatus + 7, // 2: session.CreateSessionRequest.labels:type_name -> session.CreateSessionRequest.LabelsEntry + 8, // 3: session.UpdateSessionStatusRequest.paused:type_name -> google.protobuf.BoolValue + 9, // 4: session.UpdateSessionStatusRequest.paused_time:type_name -> google.protobuf.StringValue + 8, // 5: session.UpdateSessionStatusRequest.active:type_name -> google.protobuf.BoolValue + 8, // 6: session.UpdateSessionStatusRequest.finished:type_name -> google.protobuf.BoolValue + 0, // 7: session.ListSessionsResponse.sessions:type_name -> session.Session + 1, // 8: session.SessionSvc.CreateSession:input_type -> session.CreateSessionRequest + 10, // 9: session.SessionSvc.GetSession:input_type -> general.GetRequest + 2, // 10: session.SessionSvc.UpdateSession:input_type -> session.UpdateSessionRequest + 3, // 11: session.SessionSvc.UpdateSessionStatus:input_type -> session.UpdateSessionStatusRequest + 11, // 12: session.SessionSvc.DeleteSession:input_type -> general.ResourceId + 12, // 13: session.SessionSvc.DeleteCollectionSession:input_type -> general.ListOptions + 12, // 14: session.SessionSvc.ListSession:input_type -> general.ListOptions + 11, // 15: session.SessionSvc.CreateSession:output_type -> general.ResourceId + 0, // 16: session.SessionSvc.GetSession:output_type -> session.Session + 13, // 17: session.SessionSvc.UpdateSession:output_type -> google.protobuf.Empty + 13, // 18: session.SessionSvc.UpdateSessionStatus:output_type -> google.protobuf.Empty + 13, // 19: session.SessionSvc.DeleteSession:output_type -> google.protobuf.Empty + 13, // 20: session.SessionSvc.DeleteCollectionSession:output_type -> google.protobuf.Empty + 5, // 21: session.SessionSvc.ListSession:output_type -> session.ListSessionsResponse + 15, // [15:22] is the sub-list for method output_type + 8, // [8:15] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_session_session_proto_init() } +func file_session_session_proto_init() { + if File_session_session_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_session_session_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Session); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_session_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_session_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_session_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSessionStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_session_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SessionStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_session_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListSessionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_session_session_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_session_session_proto_goTypes, + DependencyIndexes: file_session_session_proto_depIdxs, + MessageInfos: file_session_session_proto_msgTypes, + }.Build() + File_session_session_proto = out.File + file_session_session_proto_rawDesc = nil + file_session_session_proto_goTypes = nil + file_session_session_proto_depIdxs = nil +} diff --git a/v3/protos/session/session.proto b/v3/protos/session/session.proto new file mode 100644 index 00000000..0c91223c --- /dev/null +++ b/v3/protos/session/session.proto @@ -0,0 +1,72 @@ +syntax = "proto3"; + +package session; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/session;sessionpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service SessionSvc { + rpc CreateSession (CreateSessionRequest) returns (general.ResourceId); + rpc GetSession (general.GetRequest) returns (Session); + rpc UpdateSession (UpdateSessionRequest) returns (google.protobuf.Empty); + rpc UpdateSessionStatus (UpdateSessionStatusRequest) returns (google.protobuf.Empty); + rpc DeleteSession (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionSession (general.ListOptions) returns (google.protobuf.Empty); + rpc ListSession (general.ListOptions) returns (ListSessionsResponse); +} + +message Session { + string id = 1; + string uid = 2; + string scenario = 3; + string course = 4; + bool keep_course_vm = 5; + string user = 6; + repeated string vm_claim = 7; + string access_code = 8; + map labels = 9; + SessionStatus status = 10; +} + +message CreateSessionRequest { + string scenario = 1; + string course = 2; + bool keep_course_vm = 3; + string user = 4; + repeated string vm_claim = 5; + string access_code = 6; + map labels = 7; +} + +// Currently sessions are bound to a course, user and access code +// Thus, only the scenario for a session can be updated +message UpdateSessionRequest { + string id = 1; + string scenario = 2; +} + +message UpdateSessionStatusRequest { + string id = 1; + google.protobuf.BoolValue paused = 2; + google.protobuf.StringValue paused_time = 3; + google.protobuf.BoolValue active = 4; + google.protobuf.BoolValue finished = 5; + string start_time = 6; + string expiration_time = 7; +} + +message SessionStatus { + bool paused = 1; + string paused_time = 2; + bool active = 3; + bool finished = 4; + string start_time = 5; + string expiration_time = 6; +} + +message ListSessionsResponse { + repeated Session sessions = 1; +} \ No newline at end of file diff --git a/v3/protos/session/session_grpc.pb.go b/v3/protos/session/session_grpc.pb.go new file mode 100644 index 00000000..06663855 --- /dev/null +++ b/v3/protos/session/session_grpc.pb.go @@ -0,0 +1,333 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: session/session.proto + +package sessionpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + SessionSvc_CreateSession_FullMethodName = "/session.SessionSvc/CreateSession" + SessionSvc_GetSession_FullMethodName = "/session.SessionSvc/GetSession" + SessionSvc_UpdateSession_FullMethodName = "/session.SessionSvc/UpdateSession" + SessionSvc_UpdateSessionStatus_FullMethodName = "/session.SessionSvc/UpdateSessionStatus" + SessionSvc_DeleteSession_FullMethodName = "/session.SessionSvc/DeleteSession" + SessionSvc_DeleteCollectionSession_FullMethodName = "/session.SessionSvc/DeleteCollectionSession" + SessionSvc_ListSession_FullMethodName = "/session.SessionSvc/ListSession" +) + +// SessionSvcClient is the client API for SessionSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SessionSvcClient interface { + CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetSession(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Session, error) + UpdateSession(ctx context.Context, in *UpdateSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateSessionStatus(ctx context.Context, in *UpdateSessionStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteSession(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionSession(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListSession(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListSessionsResponse, error) +} + +type sessionSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewSessionSvcClient(cc grpc.ClientConnInterface) SessionSvcClient { + return &sessionSvcClient{cc} +} + +func (c *sessionSvcClient) CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, SessionSvc_CreateSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) GetSession(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Session, error) { + out := new(Session) + err := c.cc.Invoke(ctx, SessionSvc_GetSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) UpdateSession(ctx context.Context, in *UpdateSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, SessionSvc_UpdateSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) UpdateSessionStatus(ctx context.Context, in *UpdateSessionStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, SessionSvc_UpdateSessionStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) DeleteSession(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, SessionSvc_DeleteSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) DeleteCollectionSession(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, SessionSvc_DeleteCollectionSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionSvcClient) ListSession(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListSessionsResponse, error) { + out := new(ListSessionsResponse) + err := c.cc.Invoke(ctx, SessionSvc_ListSession_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SessionSvcServer is the server API for SessionSvc service. +// All implementations must embed UnimplementedSessionSvcServer +// for forward compatibility +type SessionSvcServer interface { + CreateSession(context.Context, *CreateSessionRequest) (*general.ResourceId, error) + GetSession(context.Context, *general.GetRequest) (*Session, error) + UpdateSession(context.Context, *UpdateSessionRequest) (*emptypb.Empty, error) + UpdateSessionStatus(context.Context, *UpdateSessionStatusRequest) (*emptypb.Empty, error) + DeleteSession(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionSession(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListSession(context.Context, *general.ListOptions) (*ListSessionsResponse, error) + mustEmbedUnimplementedSessionSvcServer() +} + +// UnimplementedSessionSvcServer must be embedded to have forward compatible implementations. +type UnimplementedSessionSvcServer struct { +} + +func (UnimplementedSessionSvcServer) CreateSession(context.Context, *CreateSessionRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSession not implemented") +} +func (UnimplementedSessionSvcServer) GetSession(context.Context, *general.GetRequest) (*Session, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSession not implemented") +} +func (UnimplementedSessionSvcServer) UpdateSession(context.Context, *UpdateSessionRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSession not implemented") +} +func (UnimplementedSessionSvcServer) UpdateSessionStatus(context.Context, *UpdateSessionStatusRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSessionStatus not implemented") +} +func (UnimplementedSessionSvcServer) DeleteSession(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteSession not implemented") +} +func (UnimplementedSessionSvcServer) DeleteCollectionSession(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionSession not implemented") +} +func (UnimplementedSessionSvcServer) ListSession(context.Context, *general.ListOptions) (*ListSessionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListSession not implemented") +} +func (UnimplementedSessionSvcServer) mustEmbedUnimplementedSessionSvcServer() {} + +// UnsafeSessionSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SessionSvcServer will +// result in compilation errors. +type UnsafeSessionSvcServer interface { + mustEmbedUnimplementedSessionSvcServer() +} + +func RegisterSessionSvcServer(s grpc.ServiceRegistrar, srv SessionSvcServer) { + s.RegisterService(&SessionSvc_ServiceDesc, srv) +} + +func _SessionSvc_CreateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).CreateSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_CreateSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).CreateSession(ctx, req.(*CreateSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_GetSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).GetSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_GetSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).GetSession(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_UpdateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).UpdateSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_UpdateSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).UpdateSession(ctx, req.(*UpdateSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_UpdateSessionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSessionStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).UpdateSessionStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_UpdateSessionStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).UpdateSessionStatus(ctx, req.(*UpdateSessionStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_DeleteSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).DeleteSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_DeleteSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).DeleteSession(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_DeleteCollectionSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).DeleteCollectionSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_DeleteCollectionSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).DeleteCollectionSession(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionSvc_ListSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionSvcServer).ListSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SessionSvc_ListSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionSvcServer).ListSession(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// SessionSvc_ServiceDesc is the grpc.ServiceDesc for SessionSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SessionSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "session.SessionSvc", + HandlerType: (*SessionSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateSession", + Handler: _SessionSvc_CreateSession_Handler, + }, + { + MethodName: "GetSession", + Handler: _SessionSvc_GetSession_Handler, + }, + { + MethodName: "UpdateSession", + Handler: _SessionSvc_UpdateSession_Handler, + }, + { + MethodName: "UpdateSessionStatus", + Handler: _SessionSvc_UpdateSessionStatus_Handler, + }, + { + MethodName: "DeleteSession", + Handler: _SessionSvc_DeleteSession_Handler, + }, + { + MethodName: "DeleteCollectionSession", + Handler: _SessionSvc_DeleteCollectionSession_Handler, + }, + { + MethodName: "ListSession", + Handler: _SessionSvc_ListSession_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "session/session.proto", +} diff --git a/v3/protos/setting/setting.pb.go b/v3/protos/setting/setting.pb.go index a80bdee6..69bd6c67 100644 --- a/v3/protos/setting/setting.pb.go +++ b/v3/protos/setting/setting.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: setting/setting.proto -package setting +package settingpb import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -129,53 +130,6 @@ func (ValueType) EnumDescriptor() ([]byte, []int) { return file_setting_setting_proto_rawDescGZIP(), []int{1} } -type Id struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *Id) Reset() { - *x = Id{} - if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Id) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Id) ProtoMessage() {} - -func (x *Id) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Id.ProtoReflect.Descriptor instead. -func (*Id) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{0} -} - -func (x *Id) GetName() string { - if x != nil { - return x.Name - } - return "" -} - type CreateSettingRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -191,7 +145,7 @@ type CreateSettingRequest struct { func (x *CreateSettingRequest) Reset() { *x = CreateSettingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[1] + mi := &file_setting_setting_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -204,7 +158,7 @@ func (x *CreateSettingRequest) String() string { func (*CreateSettingRequest) ProtoMessage() {} func (x *CreateSettingRequest) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[1] + mi := &file_setting_setting_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -217,7 +171,7 @@ func (x *CreateSettingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSettingRequest.ProtoReflect.Descriptor instead. func (*CreateSettingRequest) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{1} + return file_setting_setting_proto_rawDescGZIP(), []int{0} } func (x *CreateSettingRequest) GetName() string { @@ -261,15 +215,16 @@ type Setting struct { unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Property *Property `protobuf:"bytes,2,opt,name=property,proto3" json:"property,omitempty"` - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` - Scope string `protobuf:"bytes,4,opt,name=scope,proto3" json:"scope,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Property *Property `protobuf:"bytes,3,opt,name=property,proto3" json:"property,omitempty"` + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + Scope string `protobuf:"bytes,5,opt,name=scope,proto3" json:"scope,omitempty"` } func (x *Setting) Reset() { *x = Setting{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[2] + mi := &file_setting_setting_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -282,7 +237,7 @@ func (x *Setting) String() string { func (*Setting) ProtoMessage() {} func (x *Setting) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[2] + mi := &file_setting_setting_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -295,7 +250,7 @@ func (x *Setting) ProtoReflect() protoreflect.Message { // Deprecated: Use Setting.ProtoReflect.Descriptor instead. func (*Setting) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{2} + return file_setting_setting_proto_rawDescGZIP(), []int{1} } func (x *Setting) GetName() string { @@ -305,6 +260,13 @@ func (x *Setting) GetName() string { return "" } +func (x *Setting) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *Setting) GetProperty() *Property { if x != nil { return x.Property @@ -343,7 +305,7 @@ type SettingValue struct { func (x *SettingValue) Reset() { *x = SettingValue{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[3] + mi := &file_setting_setting_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -356,7 +318,7 @@ func (x *SettingValue) String() string { func (*SettingValue) ProtoMessage() {} func (x *SettingValue) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[3] + mi := &file_setting_setting_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -369,7 +331,7 @@ func (x *SettingValue) ProtoReflect() protoreflect.Message { // Deprecated: Use SettingValue.ProtoReflect.Descriptor instead. func (*SettingValue) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{3} + return file_setting_setting_proto_rawDescGZIP(), []int{2} } func (m *SettingValue) GetValue() isSettingValue_Value { @@ -435,53 +397,6 @@ func (*SettingValue_Int64Value) isSettingValue_Value() {} func (*SettingValue_Float64Value) isSettingValue_Value() {} -type ListSettingsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Scope string `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"` -} - -func (x *ListSettingsRequest) Reset() { - *x = ListSettingsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListSettingsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListSettingsRequest) ProtoMessage() {} - -func (x *ListSettingsRequest) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListSettingsRequest.ProtoReflect.Descriptor instead. -func (*ListSettingsRequest) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{4} -} - -func (x *ListSettingsRequest) GetScope() string { - if x != nil { - return x.Scope - } - return "" -} - type ListSettingsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -493,7 +408,7 @@ type ListSettingsResponse struct { func (x *ListSettingsResponse) Reset() { *x = ListSettingsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[5] + mi := &file_setting_setting_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -506,7 +421,7 @@ func (x *ListSettingsResponse) String() string { func (*ListSettingsResponse) ProtoMessage() {} func (x *ListSettingsResponse) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[5] + mi := &file_setting_setting_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -519,7 +434,7 @@ func (x *ListSettingsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSettingsResponse.ProtoReflect.Descriptor instead. func (*ListSettingsResponse) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{5} + return file_setting_setting_proto_rawDescGZIP(), []int{3} } func (x *ListSettingsResponse) GetSettings() []*PreparedListSetting { @@ -535,17 +450,18 @@ type PreparedListSetting struct { unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Property *Property `protobuf:"bytes,2,opt,name=property,proto3" json:"property,omitempty"` - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` - Scope string `protobuf:"bytes,4,opt,name=scope,proto3" json:"scope,omitempty"` - Group string `protobuf:"bytes,5,opt,name=group,proto3" json:"group,omitempty"` - Weight int64 `protobuf:"varint,6,opt,name=weight,proto3" json:"weight,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Property *Property `protobuf:"bytes,3,opt,name=property,proto3" json:"property,omitempty"` + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + Scope string `protobuf:"bytes,5,opt,name=scope,proto3" json:"scope,omitempty"` + Group string `protobuf:"bytes,6,opt,name=group,proto3" json:"group,omitempty"` + Weight int64 `protobuf:"varint,7,opt,name=weight,proto3" json:"weight,omitempty"` } func (x *PreparedListSetting) Reset() { *x = PreparedListSetting{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[6] + mi := &file_setting_setting_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -558,7 +474,7 @@ func (x *PreparedListSetting) String() string { func (*PreparedListSetting) ProtoMessage() {} func (x *PreparedListSetting) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[6] + mi := &file_setting_setting_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -571,7 +487,7 @@ func (x *PreparedListSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use PreparedListSetting.ProtoReflect.Descriptor instead. func (*PreparedListSetting) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{6} + return file_setting_setting_proto_rawDescGZIP(), []int{4} } func (x *PreparedListSetting) GetName() string { @@ -581,6 +497,13 @@ func (x *PreparedListSetting) GetName() string { return "" } +func (x *PreparedListSetting) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *PreparedListSetting) GetProperty() *Property { if x != nil { return x.Property @@ -640,7 +563,7 @@ type Property struct { func (x *Property) Reset() { *x = Property{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[7] + mi := &file_setting_setting_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -653,7 +576,7 @@ func (x *Property) String() string { func (*Property) ProtoMessage() {} func (x *Property) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[7] + mi := &file_setting_setting_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -666,7 +589,7 @@ func (x *Property) ProtoReflect() protoreflect.Message { // Deprecated: Use Property.ProtoReflect.Descriptor instead. func (*Property) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{7} + return file_setting_setting_proto_rawDescGZIP(), []int{5} } func (x *Property) GetDataType() DataType { @@ -766,13 +689,14 @@ type Scope struct { unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - DisplayName string `protobuf:"bytes,2,opt,name=displayName,proto3" json:"displayName,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + DisplayName string `protobuf:"bytes,3,opt,name=displayName,proto3" json:"displayName,omitempty"` } func (x *Scope) Reset() { *x = Scope{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[8] + mi := &file_setting_setting_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -785,7 +709,7 @@ func (x *Scope) String() string { func (*Scope) ProtoMessage() {} func (x *Scope) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[8] + mi := &file_setting_setting_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -798,7 +722,7 @@ func (x *Scope) ProtoReflect() protoreflect.Message { // Deprecated: Use Scope.ProtoReflect.Descriptor instead. func (*Scope) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{8} + return file_setting_setting_proto_rawDescGZIP(), []int{6} } func (x *Scope) GetName() string { @@ -808,6 +732,13 @@ func (x *Scope) GetName() string { return "" } +func (x *Scope) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *Scope) GetDisplayName() string { if x != nil { return x.DisplayName @@ -826,7 +757,7 @@ type Scopes struct { func (x *Scopes) Reset() { *x = Scopes{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[9] + mi := &file_setting_setting_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -839,7 +770,7 @@ func (x *Scopes) String() string { func (*Scopes) ProtoMessage() {} func (x *Scopes) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[9] + mi := &file_setting_setting_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -852,7 +783,7 @@ func (x *Scopes) ProtoReflect() protoreflect.Message { // Deprecated: Use Scopes.ProtoReflect.Descriptor instead. func (*Scopes) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{9} + return file_setting_setting_proto_rawDescGZIP(), []int{7} } func (x *Scopes) GetScopes() []*Scope { @@ -875,7 +806,7 @@ type CreateScopeRequest struct { func (x *CreateScopeRequest) Reset() { *x = CreateScopeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_setting_setting_proto_msgTypes[10] + mi := &file_setting_setting_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -888,7 +819,7 @@ func (x *CreateScopeRequest) String() string { func (*CreateScopeRequest) ProtoMessage() {} func (x *CreateScopeRequest) ProtoReflect() protoreflect.Message { - mi := &file_setting_setting_proto_msgTypes[10] + mi := &file_setting_setting_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -901,7 +832,7 @@ func (x *CreateScopeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateScopeRequest.ProtoReflect.Descriptor instead. func (*CreateScopeRequest) Descriptor() ([]byte, []int) { - return file_setting_setting_proto_rawDescGZIP(), []int{10} + return file_setting_setting_proto_rawDescGZIP(), []int{8} } func (x *CreateScopeRequest) GetName() string { @@ -930,36 +861,37 @@ var File_setting_setting_proto protoreflect.FileDescriptor var file_setting_setting_proto_rawDesc = []byte{ 0x0a, 0x15, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x18, 0x0a, - 0x02, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8b, 0x02, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, - 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x78, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8b, 0x02, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x41, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x8a, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x72, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, @@ -970,127 +902,128 @@ var file_setting_setting_proto_rawDesc = []byte{ 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2b, 0x0a, 0x13, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x50, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, - 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, - 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x08, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x13, 0x50, 0x72, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xeb, 0x04, - 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x64, 0x61, - 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x08, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x09, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x61, 0x78, - 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, - 0x6d, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x39, 0x0a, 0x09, 0x6d, 0x61, 0x78, - 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x12, 0x39, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, - 0x34, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x50, 0x0a, 0x14, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x38, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xc4, 0x01, 0x0a, 0x13, + 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x08, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x22, 0xeb, 0x04, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, + 0x2d, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x11, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, + 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x12, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x36, + 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x36, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x65, 0x6e, 0x75, - 0x6d, 0x12, 0x36, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x69, - 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3d, 0x0a, 0x05, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x53, 0x63, - 0x6f, 0x70, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x22, 0x68, 0x0a, 0x12, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0x7a, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x41, 0x54, - 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, - 0x15, 0x0a, 0x11, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x45, 0x52, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, - 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, - 0x10, 0x04, 0x2a, 0x64, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x16, 0x0a, 0x12, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x41, 0x4c, 0x55, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, 0x01, 0x12, 0x14, - 0x0a, 0x10, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x52, 0x52, - 0x41, 0x59, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x50, 0x10, 0x03, 0x32, 0xe4, 0x03, 0x0a, 0x0a, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x53, 0x76, 0x63, 0x12, 0x46, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x2b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0b, 0x2e, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x64, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x35, 0x0a, 0x0f, - 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x0b, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x64, 0x1a, 0x15, 0x2e, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4b, - 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1c, - 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x27, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x0b, 0x2e, 0x73, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x64, 0x1a, 0x0e, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, - 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, - 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, - 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, - 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x73, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, + 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, + 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x39, + 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, + 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x39, 0x0a, 0x09, 0x6d, 0x69, 0x6e, + 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x36, 0x0a, 0x07, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x36, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, + 0x0a, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x22, 0x4f, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x30, 0x0a, 0x06, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, 0x6f, + 0x70, 0x65, 0x73, 0x22, 0x68, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, + 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0x7a, 0x0a, + 0x08, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x41, 0x54, + 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x14, 0x0a, 0x10, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, + 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x10, 0x02, 0x12, 0x13, 0x0a, + 0x0f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, + 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x04, 0x2a, 0x64, 0x0a, 0x09, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, + 0x0a, 0x11, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x43, 0x41, + 0x4c, 0x41, 0x52, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x56, + 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x50, 0x10, 0x03, 0x32, + 0xf2, 0x03, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x76, 0x63, 0x12, 0x46, + 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, + 0x1d, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x13, + 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x64, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0d, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x10, 0x2e, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1d, 0x2e, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2f, + 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0e, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, + 0x33, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x14, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x0f, 0x2e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x63, + 0x6f, 0x70, 0x65, 0x73, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, + 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1106,59 +1039,60 @@ func file_setting_setting_proto_rawDescGZIP() []byte { } var file_setting_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_setting_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_setting_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_setting_setting_proto_goTypes = []interface{}{ (DataType)(0), // 0: setting.DataType (ValueType)(0), // 1: setting.ValueType - (*Id)(nil), // 2: setting.Id - (*CreateSettingRequest)(nil), // 3: setting.CreateSettingRequest - (*Setting)(nil), // 4: setting.Setting - (*SettingValue)(nil), // 5: setting.SettingValue - (*ListSettingsRequest)(nil), // 6: setting.ListSettingsRequest - (*ListSettingsResponse)(nil), // 7: setting.ListSettingsResponse - (*PreparedListSetting)(nil), // 8: setting.PreparedListSetting - (*Property)(nil), // 9: setting.Property - (*Scope)(nil), // 10: setting.Scope - (*Scopes)(nil), // 11: setting.Scopes - (*CreateScopeRequest)(nil), // 12: setting.CreateScopeRequest - nil, // 13: setting.CreateSettingRequest.LabelsEntry - (*wrapperspb.DoubleValue)(nil), // 14: google.protobuf.DoubleValue - (*wrapperspb.Int64Value)(nil), // 15: google.protobuf.Int64Value - (*wrapperspb.StringValue)(nil), // 16: google.protobuf.StringValue - (*emptypb.Empty)(nil), // 17: google.protobuf.Empty + (*CreateSettingRequest)(nil), // 2: setting.CreateSettingRequest + (*Setting)(nil), // 3: setting.Setting + (*SettingValue)(nil), // 4: setting.SettingValue + (*ListSettingsResponse)(nil), // 5: setting.ListSettingsResponse + (*PreparedListSetting)(nil), // 6: setting.PreparedListSetting + (*Property)(nil), // 7: setting.Property + (*Scope)(nil), // 8: setting.Scope + (*Scopes)(nil), // 9: setting.Scopes + (*CreateScopeRequest)(nil), // 10: setting.CreateScopeRequest + nil, // 11: setting.CreateSettingRequest.LabelsEntry + (*wrapperspb.DoubleValue)(nil), // 12: google.protobuf.DoubleValue + (*wrapperspb.Int64Value)(nil), // 13: google.protobuf.Int64Value + (*wrapperspb.StringValue)(nil), // 14: google.protobuf.StringValue + (*general.GetRequest)(nil), // 15: general.GetRequest + (*general.ResourceId)(nil), // 16: general.ResourceId + (*general.ListOptions)(nil), // 17: general.ListOptions + (*emptypb.Empty)(nil), // 18: google.protobuf.Empty } var file_setting_setting_proto_depIdxs = []int32{ - 13, // 0: setting.CreateSettingRequest.labels:type_name -> setting.CreateSettingRequest.LabelsEntry - 9, // 1: setting.CreateSettingRequest.property:type_name -> setting.Property - 9, // 2: setting.Setting.property:type_name -> setting.Property - 8, // 3: setting.ListSettingsResponse.settings:type_name -> setting.PreparedListSetting - 9, // 4: setting.PreparedListSetting.property:type_name -> setting.Property + 11, // 0: setting.CreateSettingRequest.labels:type_name -> setting.CreateSettingRequest.LabelsEntry + 7, // 1: setting.CreateSettingRequest.property:type_name -> setting.Property + 7, // 2: setting.Setting.property:type_name -> setting.Property + 6, // 3: setting.ListSettingsResponse.settings:type_name -> setting.PreparedListSetting + 7, // 4: setting.PreparedListSetting.property:type_name -> setting.Property 0, // 5: setting.Property.dataType:type_name -> setting.DataType 1, // 6: setting.Property.valueType:type_name -> setting.ValueType - 14, // 7: setting.Property.maximum:type_name -> google.protobuf.DoubleValue - 14, // 8: setting.Property.minimum:type_name -> google.protobuf.DoubleValue - 15, // 9: setting.Property.maxLength:type_name -> google.protobuf.Int64Value - 15, // 10: setting.Property.minLength:type_name -> google.protobuf.Int64Value - 16, // 11: setting.Property.format:type_name -> google.protobuf.StringValue - 16, // 12: setting.Property.pattern:type_name -> google.protobuf.StringValue - 16, // 13: setting.Property.default:type_name -> google.protobuf.StringValue - 10, // 14: setting.Scopes.scopes:type_name -> setting.Scope - 3, // 15: setting.SettingSvc.CreateSetting:input_type -> setting.CreateSettingRequest - 2, // 16: setting.SettingSvc.GetSetting:input_type -> setting.Id - 2, // 17: setting.SettingSvc.GetSettingValue:input_type -> setting.Id - 4, // 18: setting.SettingSvc.UpdateSetting:input_type -> setting.Setting - 6, // 19: setting.SettingSvc.ListSettings:input_type -> setting.ListSettingsRequest - 12, // 20: setting.SettingSvc.CreateScope:input_type -> setting.CreateScopeRequest - 2, // 21: setting.SettingSvc.GetScope:input_type -> setting.Id - 17, // 22: setting.SettingSvc.ListScopes:input_type -> google.protobuf.Empty - 17, // 23: setting.SettingSvc.CreateSetting:output_type -> google.protobuf.Empty - 4, // 24: setting.SettingSvc.GetSetting:output_type -> setting.Setting - 5, // 25: setting.SettingSvc.GetSettingValue:output_type -> setting.SettingValue - 17, // 26: setting.SettingSvc.UpdateSetting:output_type -> google.protobuf.Empty - 7, // 27: setting.SettingSvc.ListSettings:output_type -> setting.ListSettingsResponse - 17, // 28: setting.SettingSvc.CreateScope:output_type -> google.protobuf.Empty - 10, // 29: setting.SettingSvc.GetScope:output_type -> setting.Scope - 11, // 30: setting.SettingSvc.ListScopes:output_type -> setting.Scopes + 12, // 7: setting.Property.maximum:type_name -> google.protobuf.DoubleValue + 12, // 8: setting.Property.minimum:type_name -> google.protobuf.DoubleValue + 13, // 9: setting.Property.maxLength:type_name -> google.protobuf.Int64Value + 13, // 10: setting.Property.minLength:type_name -> google.protobuf.Int64Value + 14, // 11: setting.Property.format:type_name -> google.protobuf.StringValue + 14, // 12: setting.Property.pattern:type_name -> google.protobuf.StringValue + 14, // 13: setting.Property.default:type_name -> google.protobuf.StringValue + 8, // 14: setting.Scopes.scopes:type_name -> setting.Scope + 2, // 15: setting.SettingSvc.CreateSetting:input_type -> setting.CreateSettingRequest + 15, // 16: setting.SettingSvc.GetSetting:input_type -> general.GetRequest + 16, // 17: setting.SettingSvc.GetSettingValue:input_type -> general.ResourceId + 3, // 18: setting.SettingSvc.UpdateSetting:input_type -> setting.Setting + 17, // 19: setting.SettingSvc.ListSettings:input_type -> general.ListOptions + 10, // 20: setting.SettingSvc.CreateScope:input_type -> setting.CreateScopeRequest + 15, // 21: setting.SettingSvc.GetScope:input_type -> general.GetRequest + 17, // 22: setting.SettingSvc.ListScopes:input_type -> general.ListOptions + 18, // 23: setting.SettingSvc.CreateSetting:output_type -> google.protobuf.Empty + 3, // 24: setting.SettingSvc.GetSetting:output_type -> setting.Setting + 4, // 25: setting.SettingSvc.GetSettingValue:output_type -> setting.SettingValue + 18, // 26: setting.SettingSvc.UpdateSetting:output_type -> google.protobuf.Empty + 5, // 27: setting.SettingSvc.ListSettings:output_type -> setting.ListSettingsResponse + 18, // 28: setting.SettingSvc.CreateScope:output_type -> google.protobuf.Empty + 8, // 29: setting.SettingSvc.GetScope:output_type -> setting.Scope + 9, // 30: setting.SettingSvc.ListScopes:output_type -> setting.Scopes 23, // [23:31] is the sub-list for method output_type 15, // [15:23] is the sub-list for method input_type 15, // [15:15] is the sub-list for extension type_name @@ -1173,18 +1107,6 @@ func file_setting_setting_proto_init() { } if !protoimpl.UnsafeEnabled { file_setting_setting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Id); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_setting_setting_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateSettingRequest); i { case 0: return &v.state @@ -1196,7 +1118,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Setting); i { case 0: return &v.state @@ -1208,7 +1130,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SettingValue); i { case 0: return &v.state @@ -1220,19 +1142,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSettingsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_setting_setting_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListSettingsResponse); i { case 0: return &v.state @@ -1244,7 +1154,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PreparedListSetting); i { case 0: return &v.state @@ -1256,7 +1166,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Property); i { case 0: return &v.state @@ -1268,7 +1178,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Scope); i { case 0: return &v.state @@ -1280,7 +1190,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Scopes); i { case 0: return &v.state @@ -1292,7 +1202,7 @@ func file_setting_setting_proto_init() { return nil } } - file_setting_setting_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_setting_setting_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateScopeRequest); i { case 0: return &v.state @@ -1305,7 +1215,7 @@ func file_setting_setting_proto_init() { } } } - file_setting_setting_proto_msgTypes[3].OneofWrappers = []interface{}{ + file_setting_setting_proto_msgTypes[2].OneofWrappers = []interface{}{ (*SettingValue_BoolValue)(nil), (*SettingValue_StringValue)(nil), (*SettingValue_Int64Value)(nil), @@ -1317,7 +1227,7 @@ func file_setting_setting_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_setting_setting_proto_rawDesc, NumEnums: 2, - NumMessages: 12, + NumMessages: 10, NumExtensions: 0, NumServices: 1, }, diff --git a/v3/protos/setting/setting.proto b/v3/protos/setting/setting.proto index 5d24aa29..a4996b2b 100644 --- a/v3/protos/setting/setting.proto +++ b/v3/protos/setting/setting.proto @@ -2,25 +2,22 @@ syntax = "proto3"; package setting; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/setting"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/setting;settingpb"; +import "general/general.proto"; import "google/protobuf/wrappers.proto"; import "google/protobuf/empty.proto"; service SettingSvc { rpc CreateSetting(CreateSettingRequest) returns (google.protobuf.Empty); - rpc GetSetting (Id) returns (Setting); - rpc GetSettingValue(Id) returns (SettingValue); + rpc GetSetting (general.GetRequest) returns (Setting); + rpc GetSettingValue(general.ResourceId) returns (SettingValue); rpc UpdateSetting (Setting) returns (google.protobuf.Empty); - // rpc DeleteSetting (Id) returns (google.protobuf.Empty); TODO - rpc ListSettings(ListSettingsRequest) returns (ListSettingsResponse); + // rpc DeleteSetting (general.ResourceId) returns (google.protobuf.Empty); TODO + rpc ListSettings(general.ListOptions) returns (ListSettingsResponse); rpc CreateScope (CreateScopeRequest) returns (google.protobuf.Empty); - rpc GetScope (Id) returns (Scope); - rpc ListScopes (google.protobuf.Empty) returns (Scopes); -} - -message Id { - string name = 1; + rpc GetScope (general.GetRequest) returns (Scope); + rpc ListScopes (general.ListOptions) returns (Scopes); } message CreateSettingRequest { @@ -33,9 +30,10 @@ message CreateSettingRequest { message Setting { string name = 1; - Property property = 2; - string value = 3; - string scope = 4; + string uid = 2; + Property property = 3; + string value = 4; + string scope = 5; } message SettingValue { @@ -47,21 +45,18 @@ message SettingValue { } } -message ListSettingsRequest { - string scope = 1; -} - message ListSettingsResponse { repeated PreparedListSetting settings = 1; } message PreparedListSetting { string name = 1; - Property property = 2; - string value = 3; - string scope = 4; - string group = 5; - int64 weight = 6; + string uid = 2; + Property property = 3; + string value = 4; + string scope = 5; + string group = 6; + int64 weight = 7; } message Property { @@ -84,7 +79,8 @@ message Property { message Scope { string name = 1; - string displayName = 2; + string uid = 2; + string displayName = 3; } message Scopes { diff --git a/v3/protos/setting/setting_grpc.pb.go b/v3/protos/setting/setting_grpc.pb.go index acb65629..bf9239a1 100644 --- a/v3/protos/setting/setting_grpc.pb.go +++ b/v3/protos/setting/setting_grpc.pb.go @@ -4,10 +4,11 @@ // - protoc v3.21.12 // source: setting/setting.proto -package setting +package settingpb import ( context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -35,14 +36,14 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type SettingSvcClient interface { CreateSetting(ctx context.Context, in *CreateSettingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - GetSetting(ctx context.Context, in *Id, opts ...grpc.CallOption) (*Setting, error) - GetSettingValue(ctx context.Context, in *Id, opts ...grpc.CallOption) (*SettingValue, error) + GetSetting(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Setting, error) + GetSettingValue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*SettingValue, error) UpdateSetting(ctx context.Context, in *Setting, opts ...grpc.CallOption) (*emptypb.Empty, error) - // rpc DeleteSetting (Id) returns (google.protobuf.Empty); TODO - ListSettings(ctx context.Context, in *ListSettingsRequest, opts ...grpc.CallOption) (*ListSettingsResponse, error) + // rpc DeleteSetting (general.ResourceId) returns (google.protobuf.Empty); TODO + ListSettings(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListSettingsResponse, error) CreateScope(ctx context.Context, in *CreateScopeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - GetScope(ctx context.Context, in *Id, opts ...grpc.CallOption) (*Scope, error) - ListScopes(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Scopes, error) + GetScope(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Scope, error) + ListScopes(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*Scopes, error) } type settingSvcClient struct { @@ -62,7 +63,7 @@ func (c *settingSvcClient) CreateSetting(ctx context.Context, in *CreateSettingR return out, nil } -func (c *settingSvcClient) GetSetting(ctx context.Context, in *Id, opts ...grpc.CallOption) (*Setting, error) { +func (c *settingSvcClient) GetSetting(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Setting, error) { out := new(Setting) err := c.cc.Invoke(ctx, SettingSvc_GetSetting_FullMethodName, in, out, opts...) if err != nil { @@ -71,7 +72,7 @@ func (c *settingSvcClient) GetSetting(ctx context.Context, in *Id, opts ...grpc. return out, nil } -func (c *settingSvcClient) GetSettingValue(ctx context.Context, in *Id, opts ...grpc.CallOption) (*SettingValue, error) { +func (c *settingSvcClient) GetSettingValue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*SettingValue, error) { out := new(SettingValue) err := c.cc.Invoke(ctx, SettingSvc_GetSettingValue_FullMethodName, in, out, opts...) if err != nil { @@ -89,7 +90,7 @@ func (c *settingSvcClient) UpdateSetting(ctx context.Context, in *Setting, opts return out, nil } -func (c *settingSvcClient) ListSettings(ctx context.Context, in *ListSettingsRequest, opts ...grpc.CallOption) (*ListSettingsResponse, error) { +func (c *settingSvcClient) ListSettings(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListSettingsResponse, error) { out := new(ListSettingsResponse) err := c.cc.Invoke(ctx, SettingSvc_ListSettings_FullMethodName, in, out, opts...) if err != nil { @@ -107,7 +108,7 @@ func (c *settingSvcClient) CreateScope(ctx context.Context, in *CreateScopeReque return out, nil } -func (c *settingSvcClient) GetScope(ctx context.Context, in *Id, opts ...grpc.CallOption) (*Scope, error) { +func (c *settingSvcClient) GetScope(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Scope, error) { out := new(Scope) err := c.cc.Invoke(ctx, SettingSvc_GetScope_FullMethodName, in, out, opts...) if err != nil { @@ -116,7 +117,7 @@ func (c *settingSvcClient) GetScope(ctx context.Context, in *Id, opts ...grpc.Ca return out, nil } -func (c *settingSvcClient) ListScopes(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Scopes, error) { +func (c *settingSvcClient) ListScopes(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*Scopes, error) { out := new(Scopes) err := c.cc.Invoke(ctx, SettingSvc_ListScopes_FullMethodName, in, out, opts...) if err != nil { @@ -130,14 +131,14 @@ func (c *settingSvcClient) ListScopes(ctx context.Context, in *emptypb.Empty, op // for forward compatibility type SettingSvcServer interface { CreateSetting(context.Context, *CreateSettingRequest) (*emptypb.Empty, error) - GetSetting(context.Context, *Id) (*Setting, error) - GetSettingValue(context.Context, *Id) (*SettingValue, error) + GetSetting(context.Context, *general.GetRequest) (*Setting, error) + GetSettingValue(context.Context, *general.ResourceId) (*SettingValue, error) UpdateSetting(context.Context, *Setting) (*emptypb.Empty, error) - // rpc DeleteSetting (Id) returns (google.protobuf.Empty); TODO - ListSettings(context.Context, *ListSettingsRequest) (*ListSettingsResponse, error) + // rpc DeleteSetting (general.ResourceId) returns (google.protobuf.Empty); TODO + ListSettings(context.Context, *general.ListOptions) (*ListSettingsResponse, error) CreateScope(context.Context, *CreateScopeRequest) (*emptypb.Empty, error) - GetScope(context.Context, *Id) (*Scope, error) - ListScopes(context.Context, *emptypb.Empty) (*Scopes, error) + GetScope(context.Context, *general.GetRequest) (*Scope, error) + ListScopes(context.Context, *general.ListOptions) (*Scopes, error) mustEmbedUnimplementedSettingSvcServer() } @@ -148,25 +149,25 @@ type UnimplementedSettingSvcServer struct { func (UnimplementedSettingSvcServer) CreateSetting(context.Context, *CreateSettingRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateSetting not implemented") } -func (UnimplementedSettingSvcServer) GetSetting(context.Context, *Id) (*Setting, error) { +func (UnimplementedSettingSvcServer) GetSetting(context.Context, *general.GetRequest) (*Setting, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSetting not implemented") } -func (UnimplementedSettingSvcServer) GetSettingValue(context.Context, *Id) (*SettingValue, error) { +func (UnimplementedSettingSvcServer) GetSettingValue(context.Context, *general.ResourceId) (*SettingValue, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSettingValue not implemented") } func (UnimplementedSettingSvcServer) UpdateSetting(context.Context, *Setting) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateSetting not implemented") } -func (UnimplementedSettingSvcServer) ListSettings(context.Context, *ListSettingsRequest) (*ListSettingsResponse, error) { +func (UnimplementedSettingSvcServer) ListSettings(context.Context, *general.ListOptions) (*ListSettingsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListSettings not implemented") } func (UnimplementedSettingSvcServer) CreateScope(context.Context, *CreateScopeRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateScope not implemented") } -func (UnimplementedSettingSvcServer) GetScope(context.Context, *Id) (*Scope, error) { +func (UnimplementedSettingSvcServer) GetScope(context.Context, *general.GetRequest) (*Scope, error) { return nil, status.Errorf(codes.Unimplemented, "method GetScope not implemented") } -func (UnimplementedSettingSvcServer) ListScopes(context.Context, *emptypb.Empty) (*Scopes, error) { +func (UnimplementedSettingSvcServer) ListScopes(context.Context, *general.ListOptions) (*Scopes, error) { return nil, status.Errorf(codes.Unimplemented, "method ListScopes not implemented") } func (UnimplementedSettingSvcServer) mustEmbedUnimplementedSettingSvcServer() {} @@ -201,7 +202,7 @@ func _SettingSvc_CreateSetting_Handler(srv interface{}, ctx context.Context, dec } func _SettingSvc_GetSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Id) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -213,13 +214,13 @@ func _SettingSvc_GetSetting_Handler(srv interface{}, ctx context.Context, dec fu FullMethod: SettingSvc_GetSetting_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SettingSvcServer).GetSetting(ctx, req.(*Id)) + return srv.(SettingSvcServer).GetSetting(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } func _SettingSvc_GetSettingValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Id) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -231,7 +232,7 @@ func _SettingSvc_GetSettingValue_Handler(srv interface{}, ctx context.Context, d FullMethod: SettingSvc_GetSettingValue_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SettingSvcServer).GetSettingValue(ctx, req.(*Id)) + return srv.(SettingSvcServer).GetSettingValue(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } @@ -255,7 +256,7 @@ func _SettingSvc_UpdateSetting_Handler(srv interface{}, ctx context.Context, dec } func _SettingSvc_ListSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListSettingsRequest) + in := new(general.ListOptions) if err := dec(in); err != nil { return nil, err } @@ -267,7 +268,7 @@ func _SettingSvc_ListSettings_Handler(srv interface{}, ctx context.Context, dec FullMethod: SettingSvc_ListSettings_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SettingSvcServer).ListSettings(ctx, req.(*ListSettingsRequest)) + return srv.(SettingSvcServer).ListSettings(ctx, req.(*general.ListOptions)) } return interceptor(ctx, in, info, handler) } @@ -291,7 +292,7 @@ func _SettingSvc_CreateScope_Handler(srv interface{}, ctx context.Context, dec f } func _SettingSvc_GetScope_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Id) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -303,13 +304,13 @@ func _SettingSvc_GetScope_Handler(srv interface{}, ctx context.Context, dec func FullMethod: SettingSvc_GetScope_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SettingSvcServer).GetScope(ctx, req.(*Id)) + return srv.(SettingSvcServer).GetScope(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } func _SettingSvc_ListScopes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(general.ListOptions) if err := dec(in); err != nil { return nil, err } @@ -321,7 +322,7 @@ func _SettingSvc_ListScopes_Handler(srv interface{}, ctx context.Context, dec fu FullMethod: SettingSvc_ListScopes_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SettingSvcServer).ListScopes(ctx, req.(*emptypb.Empty)) + return srv.(SettingSvcServer).ListScopes(ctx, req.(*general.ListOptions)) } return interceptor(ctx, in, info, handler) } diff --git a/v3/protos/terraform/terraform.pb.go b/v3/protos/terraform/terraform.pb.go new file mode 100644 index 00000000..d9729327 --- /dev/null +++ b/v3/protos/terraform/terraform.pb.go @@ -0,0 +1,1426 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: terraform/terraform.proto + +package terraformpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Condition_ConditionStatus int32 + +const ( + Condition_True Condition_ConditionStatus = 0 + Condition_False Condition_ConditionStatus = 1 + Condition_Unknown Condition_ConditionStatus = 2 +) + +// Enum value maps for Condition_ConditionStatus. +var ( + Condition_ConditionStatus_name = map[int32]string{ + 0: "True", + 1: "False", + 2: "Unknown", + } + Condition_ConditionStatus_value = map[string]int32{ + "True": 0, + "False": 1, + "Unknown": 2, + } +) + +func (x Condition_ConditionStatus) Enum() *Condition_ConditionStatus { + p := new(Condition_ConditionStatus) + *p = x + return p +} + +func (x Condition_ConditionStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Condition_ConditionStatus) Descriptor() protoreflect.EnumDescriptor { + return file_terraform_terraform_proto_enumTypes[0].Descriptor() +} + +func (Condition_ConditionStatus) Type() protoreflect.EnumType { + return &file_terraform_terraform_proto_enumTypes[0] +} + +func (x Condition_ConditionStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Condition_ConditionStatus.Descriptor instead. +func (Condition_ConditionStatus) EnumDescriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{8, 0} +} + +type CreateStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VmId string `protobuf:"bytes,1,opt,name=vm_id,json=vmId,proto3" json:"vm_id,omitempty"` + Image string `protobuf:"bytes,2,opt,name=image,proto3" json:"image,omitempty"` + Variables *Variables `protobuf:"bytes,3,opt,name=variables,proto3" json:"variables,omitempty"` + ModuleName string `protobuf:"bytes,4,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + Data map[string]string `protobuf:"bytes,5,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AutoConfirm bool `protobuf:"varint,6,opt,name=auto_confirm,json=autoConfirm,proto3" json:"auto_confirm,omitempty"` + DestroyOnDelete bool `protobuf:"varint,7,opt,name=destroy_on_delete,json=destroyOnDelete,proto3" json:"destroy_on_delete,omitempty"` + Version int32 `protobuf:"varint,8,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *CreateStateRequest) Reset() { + *x = CreateStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateStateRequest) ProtoMessage() {} + +func (x *CreateStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateStateRequest.ProtoReflect.Descriptor instead. +func (*CreateStateRequest) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateStateRequest) GetVmId() string { + if x != nil { + return x.VmId + } + return "" +} + +func (x *CreateStateRequest) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *CreateStateRequest) GetVariables() *Variables { + if x != nil { + return x.Variables + } + return nil +} + +func (x *CreateStateRequest) GetModuleName() string { + if x != nil { + return x.ModuleName + } + return "" +} + +func (x *CreateStateRequest) GetData() map[string]string { + if x != nil { + return x.Data + } + return nil +} + +func (x *CreateStateRequest) GetAutoConfirm() bool { + if x != nil { + return x.AutoConfirm + } + return false +} + +func (x *CreateStateRequest) GetDestroyOnDelete() bool { + if x != nil { + return x.DestroyOnDelete + } + return false +} + +func (x *CreateStateRequest) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +type State struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Image string `protobuf:"bytes,2,opt,name=image,proto3" json:"image,omitempty"` + Variables *Variables `protobuf:"bytes,3,opt,name=variables,proto3" json:"variables,omitempty"` + ModuleName string `protobuf:"bytes,4,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + Data map[string]string `protobuf:"bytes,5,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AutoConfirm bool `protobuf:"varint,6,opt,name=auto_confirm,json=autoConfirm,proto3" json:"auto_confirm,omitempty"` + DestroyOnDelete bool `protobuf:"varint,7,opt,name=destroy_on_delete,json=destroyOnDelete,proto3" json:"destroy_on_delete,omitempty"` + Version int32 `protobuf:"varint,8,opt,name=version,proto3" json:"version,omitempty"` + Status *StateStatus `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + CreationTimestamp *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` +} + +func (x *State) Reset() { + *x = State{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *State) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*State) ProtoMessage() {} + +func (x *State) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use State.ProtoReflect.Descriptor instead. +func (*State) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{1} +} + +func (x *State) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *State) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *State) GetVariables() *Variables { + if x != nil { + return x.Variables + } + return nil +} + +func (x *State) GetModuleName() string { + if x != nil { + return x.ModuleName + } + return "" +} + +func (x *State) GetData() map[string]string { + if x != nil { + return x.Data + } + return nil +} + +func (x *State) GetAutoConfirm() bool { + if x != nil { + return x.AutoConfirm + } + return false +} + +func (x *State) GetDestroyOnDelete() bool { + if x != nil { + return x.DestroyOnDelete + } + return false +} + +func (x *State) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *State) GetStatus() *StateStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *State) GetCreationTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.CreationTimestamp + } + return nil +} + +type StateStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conditions []*Condition `protobuf:"bytes,1,rep,name=conditions,proto3" json:"conditions,omitempty"` + LastRunHash string `protobuf:"bytes,2,opt,name=last_run_hash,json=lastRunHash,proto3" json:"last_run_hash,omitempty"` + ExecutionName string `protobuf:"bytes,3,opt,name=execution_name,json=executionName,proto3" json:"execution_name,omitempty"` + ExecutionPlanName string `protobuf:"bytes,4,opt,name=execution_plan_name,json=executionPlanName,proto3" json:"execution_plan_name,omitempty"` +} + +func (x *StateStatus) Reset() { + *x = StateStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateStatus) ProtoMessage() {} + +func (x *StateStatus) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StateStatus.ProtoReflect.Descriptor instead. +func (*StateStatus) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{2} +} + +func (x *StateStatus) GetConditions() []*Condition { + if x != nil { + return x.Conditions + } + return nil +} + +func (x *StateStatus) GetLastRunHash() string { + if x != nil { + return x.LastRunHash + } + return "" +} + +func (x *StateStatus) GetExecutionName() string { + if x != nil { + return x.ExecutionName + } + return "" +} + +func (x *StateStatus) GetExecutionPlanName() string { + if x != nil { + return x.ExecutionPlanName + } + return "" +} + +type ListStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + States []*State `protobuf:"bytes,1,rep,name=states,proto3" json:"states,omitempty"` +} + +func (x *ListStateResponse) Reset() { + *x = ListStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListStateResponse) ProtoMessage() {} + +func (x *ListStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListStateResponse.ProtoReflect.Descriptor instead. +func (*ListStateResponse) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{3} +} + +func (x *ListStateResponse) GetStates() []*State { + if x != nil { + return x.States + } + return nil +} + +type Execution struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + AutoConfirm bool `protobuf:"varint,2,opt,name=auto_confirm,json=autoConfirm,proto3" json:"auto_confirm,omitempty"` + Content *ModuleContent `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` + ContentHash string `protobuf:"bytes,4,opt,name=content_hash,json=contentHash,proto3" json:"content_hash,omitempty"` + RunHash string `protobuf:"bytes,5,opt,name=run_hash,json=runHash,proto3" json:"run_hash,omitempty"` + Data map[string]string `protobuf:"bytes,6,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ExecutionName string `protobuf:"bytes,7,opt,name=execution_name,json=executionName,proto3" json:"execution_name,omitempty"` + ExecutionVersion int32 `protobuf:"varint,8,opt,name=execution_version,json=executionVersion,proto3" json:"execution_version,omitempty"` + SecretName string `protobuf:"bytes,9,opt,name=secret_name,json=secretName,proto3" json:"secret_name,omitempty"` + Status *ExecutionStatus `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"` + CreationTimestamp *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` +} + +func (x *Execution) Reset() { + *x = Execution{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Execution) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Execution) ProtoMessage() {} + +func (x *Execution) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Execution.ProtoReflect.Descriptor instead. +func (*Execution) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{4} +} + +func (x *Execution) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Execution) GetAutoConfirm() bool { + if x != nil { + return x.AutoConfirm + } + return false +} + +func (x *Execution) GetContent() *ModuleContent { + if x != nil { + return x.Content + } + return nil +} + +func (x *Execution) GetContentHash() string { + if x != nil { + return x.ContentHash + } + return "" +} + +func (x *Execution) GetRunHash() string { + if x != nil { + return x.RunHash + } + return "" +} + +func (x *Execution) GetData() map[string]string { + if x != nil { + return x.Data + } + return nil +} + +func (x *Execution) GetExecutionName() string { + if x != nil { + return x.ExecutionName + } + return "" +} + +func (x *Execution) GetExecutionVersion() int32 { + if x != nil { + return x.ExecutionVersion + } + return 0 +} + +func (x *Execution) GetSecretName() string { + if x != nil { + return x.SecretName + } + return "" +} + +func (x *Execution) GetStatus() *ExecutionStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *Execution) GetCreationTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.CreationTimestamp + } + return nil +} + +type ExecutionStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conditions []*Condition `protobuf:"bytes,1,rep,name=conditions,proto3" json:"conditions,omitempty"` + JobName string `protobuf:"bytes,2,opt,name=job_name,json=jobName,proto3" json:"job_name,omitempty"` + JobLogs string `protobuf:"bytes,3,opt,name=job_logs,json=jobLogs,proto3" json:"job_logs,omitempty"` + PlanOutput string `protobuf:"bytes,4,opt,name=plan_output,json=planOutput,proto3" json:"plan_output,omitempty"` + PlanConfirmed bool `protobuf:"varint,5,opt,name=plan_confirmed,json=planConfirmed,proto3" json:"plan_confirmed,omitempty"` + ApplyOutput string `protobuf:"bytes,6,opt,name=apply_output,json=applyOutput,proto3" json:"apply_output,omitempty"` + Outputs string `protobuf:"bytes,7,opt,name=outputs,proto3" json:"outputs,omitempty"` +} + +func (x *ExecutionStatus) Reset() { + *x = ExecutionStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionStatus) ProtoMessage() {} + +func (x *ExecutionStatus) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionStatus.ProtoReflect.Descriptor instead. +func (*ExecutionStatus) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{5} +} + +func (x *ExecutionStatus) GetConditions() []*Condition { + if x != nil { + return x.Conditions + } + return nil +} + +func (x *ExecutionStatus) GetJobName() string { + if x != nil { + return x.JobName + } + return "" +} + +func (x *ExecutionStatus) GetJobLogs() string { + if x != nil { + return x.JobLogs + } + return "" +} + +func (x *ExecutionStatus) GetPlanOutput() string { + if x != nil { + return x.PlanOutput + } + return "" +} + +func (x *ExecutionStatus) GetPlanConfirmed() bool { + if x != nil { + return x.PlanConfirmed + } + return false +} + +func (x *ExecutionStatus) GetApplyOutput() string { + if x != nil { + return x.ApplyOutput + } + return "" +} + +func (x *ExecutionStatus) GetOutputs() string { + if x != nil { + return x.Outputs + } + return "" +} + +type ListExecutionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions,proto3" json:"executions,omitempty"` +} + +func (x *ListExecutionResponse) Reset() { + *x = ListExecutionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListExecutionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExecutionResponse) ProtoMessage() {} + +func (x *ListExecutionResponse) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListExecutionResponse.ProtoReflect.Descriptor instead. +func (*ListExecutionResponse) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{6} +} + +func (x *ListExecutionResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +type Variables struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EnvConfigNames []string `protobuf:"bytes,1,rep,name=env_config_names,json=envConfigNames,proto3" json:"env_config_names,omitempty"` + EnvSecretNames []string `protobuf:"bytes,2,rep,name=env_secret_names,json=envSecretNames,proto3" json:"env_secret_names,omitempty"` + ConfigNames []string `protobuf:"bytes,3,rep,name=config_names,json=configNames,proto3" json:"config_names,omitempty"` + SecretNames []string `protobuf:"bytes,4,rep,name=secret_names,json=secretNames,proto3" json:"secret_names,omitempty"` +} + +func (x *Variables) Reset() { + *x = Variables{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Variables) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Variables) ProtoMessage() {} + +func (x *Variables) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Variables.ProtoReflect.Descriptor instead. +func (*Variables) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{7} +} + +func (x *Variables) GetEnvConfigNames() []string { + if x != nil { + return x.EnvConfigNames + } + return nil +} + +func (x *Variables) GetEnvSecretNames() []string { + if x != nil { + return x.EnvSecretNames + } + return nil +} + +func (x *Variables) GetConfigNames() []string { + if x != nil { + return x.ConfigNames + } + return nil +} + +func (x *Variables) GetSecretNames() []string { + if x != nil { + return x.SecretNames + } + return nil +} + +type Condition struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + LastUpdateTime string `protobuf:"bytes,3,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"` + LastTransitionTime string `protobuf:"bytes,4,opt,name=last_transition_time,json=lastTransitionTime,proto3" json:"last_transition_time,omitempty"` + Reason string `protobuf:"bytes,5,opt,name=reason,proto3" json:"reason,omitempty"` + Message string `protobuf:"bytes,6,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *Condition) Reset() { + *x = Condition{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Condition) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Condition) ProtoMessage() {} + +func (x *Condition) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Condition.ProtoReflect.Descriptor instead. +func (*Condition) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{8} +} + +func (x *Condition) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Condition) GetLastUpdateTime() string { + if x != nil { + return x.LastUpdateTime + } + return "" +} + +func (x *Condition) GetLastTransitionTime() string { + if x != nil { + return x.LastTransitionTime + } + return "" +} + +func (x *Condition) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Condition) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type ModuleContent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content map[string]string `protobuf:"bytes,1,rep,name=content,proto3" json:"content,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Git *GitLocation `protobuf:"bytes,2,opt,name=git,proto3" json:"git,omitempty"` +} + +func (x *ModuleContent) Reset() { + *x = ModuleContent{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ModuleContent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModuleContent) ProtoMessage() {} + +func (x *ModuleContent) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModuleContent.ProtoReflect.Descriptor instead. +func (*ModuleContent) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{9} +} + +func (x *ModuleContent) GetContent() map[string]string { + if x != nil { + return x.Content + } + return nil +} + +func (x *ModuleContent) GetGit() *GitLocation { + if x != nil { + return x.Git + } + return nil +} + +type GitLocation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + Branch string `protobuf:"bytes,2,opt,name=branch,proto3" json:"branch,omitempty"` + Tag string `protobuf:"bytes,3,opt,name=tag,proto3" json:"tag,omitempty"` + Commit string `protobuf:"bytes,4,opt,name=commit,proto3" json:"commit,omitempty"` + SecretName string `protobuf:"bytes,5,opt,name=secret_name,json=secretName,proto3" json:"secret_name,omitempty"` + IntervalSeconds int64 `protobuf:"varint,6,opt,name=interval_seconds,json=intervalSeconds,proto3" json:"interval_seconds,omitempty"` +} + +func (x *GitLocation) Reset() { + *x = GitLocation{} + if protoimpl.UnsafeEnabled { + mi := &file_terraform_terraform_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GitLocation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GitLocation) ProtoMessage() {} + +func (x *GitLocation) ProtoReflect() protoreflect.Message { + mi := &file_terraform_terraform_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GitLocation.ProtoReflect.Descriptor instead. +func (*GitLocation) Descriptor() ([]byte, []int) { + return file_terraform_terraform_proto_rawDescGZIP(), []int{10} +} + +func (x *GitLocation) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *GitLocation) GetBranch() string { + if x != nil { + return x.Branch + } + return "" +} + +func (x *GitLocation) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *GitLocation) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +func (x *GitLocation) GetSecretName() string { + if x != nil { + return x.SecretName + } + return "" +} + +func (x *GitLocation) GetIntervalSeconds() int64 { + if x != nil { + return x.IntervalSeconds + } + return 0 +} + +var File_terraform_terraform_proto protoreflect.FileDescriptor + +var file_terraform_terraform_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x72, + 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x02, 0x0a, 0x12, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x76, 0x6d, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, + 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, + 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xcf, 0x03, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x12, 0x32, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, + 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x75, + 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x73, + 0x74, 0x72, 0x6f, 0x79, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x4f, 0x6e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x49, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xbe, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, + 0x6f, 0x72, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x75, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, + 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x73, 0x22, 0x91, 0x04, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x12, 0x32, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, + 0x6d, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x72, + 0x75, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, + 0x75, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x12, 0x32, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x32, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x49, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x11, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x37, + 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x82, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6a, 0x6f, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x6a, 0x6f, 0x62, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6a, 0x6f, 0x62, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x5f, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, + 0x61, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x6e, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x4f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x15, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, + 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa5, 0x01, 0x0a, 0x09, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x65, 0x6e, 0x76, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x65, 0x6e, 0x76, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, + 0x6e, 0x76, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x22, 0xe2, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, + 0x61, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x33, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x72, 0x75, 0x65, 0x10, 0x00, + 0x12, 0x09, 0x0a, 0x05, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x02, 0x22, 0xb6, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, + 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x03, 0x67, + 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, + 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x47, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x03, 0x67, 0x69, 0x74, 0x1a, 0x3a, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xad, 0x01, 0x0a, 0x0b, 0x47, 0x69, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x74, + 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x16, 0x0a, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x32, 0xcc, 0x03, 0x0a, 0x0c, 0x54, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x53, + 0x76, 0x63, 0x12, 0x41, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x1d, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, + 0x72, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x09, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1c, + 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x20, + 0x2e, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, + 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, + 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x65, 0x72, + 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x3b, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_terraform_terraform_proto_rawDescOnce sync.Once + file_terraform_terraform_proto_rawDescData = file_terraform_terraform_proto_rawDesc +) + +func file_terraform_terraform_proto_rawDescGZIP() []byte { + file_terraform_terraform_proto_rawDescOnce.Do(func() { + file_terraform_terraform_proto_rawDescData = protoimpl.X.CompressGZIP(file_terraform_terraform_proto_rawDescData) + }) + return file_terraform_terraform_proto_rawDescData +} + +var file_terraform_terraform_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_terraform_terraform_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_terraform_terraform_proto_goTypes = []interface{}{ + (Condition_ConditionStatus)(0), // 0: terraform.Condition.ConditionStatus + (*CreateStateRequest)(nil), // 1: terraform.CreateStateRequest + (*State)(nil), // 2: terraform.State + (*StateStatus)(nil), // 3: terraform.StateStatus + (*ListStateResponse)(nil), // 4: terraform.ListStateResponse + (*Execution)(nil), // 5: terraform.Execution + (*ExecutionStatus)(nil), // 6: terraform.ExecutionStatus + (*ListExecutionResponse)(nil), // 7: terraform.ListExecutionResponse + (*Variables)(nil), // 8: terraform.Variables + (*Condition)(nil), // 9: terraform.Condition + (*ModuleContent)(nil), // 10: terraform.ModuleContent + (*GitLocation)(nil), // 11: terraform.GitLocation + nil, // 12: terraform.CreateStateRequest.DataEntry + nil, // 13: terraform.State.DataEntry + nil, // 14: terraform.Execution.DataEntry + nil, // 15: terraform.ModuleContent.ContentEntry + (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*general.GetRequest)(nil), // 17: general.GetRequest + (*general.ResourceId)(nil), // 18: general.ResourceId + (*general.ListOptions)(nil), // 19: general.ListOptions + (*emptypb.Empty)(nil), // 20: google.protobuf.Empty +} +var file_terraform_terraform_proto_depIdxs = []int32{ + 8, // 0: terraform.CreateStateRequest.variables:type_name -> terraform.Variables + 12, // 1: terraform.CreateStateRequest.data:type_name -> terraform.CreateStateRequest.DataEntry + 8, // 2: terraform.State.variables:type_name -> terraform.Variables + 13, // 3: terraform.State.data:type_name -> terraform.State.DataEntry + 3, // 4: terraform.State.status:type_name -> terraform.StateStatus + 16, // 5: terraform.State.creation_timestamp:type_name -> google.protobuf.Timestamp + 9, // 6: terraform.StateStatus.conditions:type_name -> terraform.Condition + 2, // 7: terraform.ListStateResponse.states:type_name -> terraform.State + 10, // 8: terraform.Execution.content:type_name -> terraform.ModuleContent + 14, // 9: terraform.Execution.data:type_name -> terraform.Execution.DataEntry + 6, // 10: terraform.Execution.status:type_name -> terraform.ExecutionStatus + 16, // 11: terraform.Execution.creation_timestamp:type_name -> google.protobuf.Timestamp + 9, // 12: terraform.ExecutionStatus.conditions:type_name -> terraform.Condition + 5, // 13: terraform.ListExecutionResponse.executions:type_name -> terraform.Execution + 15, // 14: terraform.ModuleContent.content:type_name -> terraform.ModuleContent.ContentEntry + 11, // 15: terraform.ModuleContent.git:type_name -> terraform.GitLocation + 1, // 16: terraform.TerraformSvc.CreateState:input_type -> terraform.CreateStateRequest + 17, // 17: terraform.TerraformSvc.GetState:input_type -> general.GetRequest + 18, // 18: terraform.TerraformSvc.DeleteState:input_type -> general.ResourceId + 19, // 19: terraform.TerraformSvc.DeleteCollectionState:input_type -> general.ListOptions + 19, // 20: terraform.TerraformSvc.ListState:input_type -> general.ListOptions + 17, // 21: terraform.TerraformSvc.GetExecution:input_type -> general.GetRequest + 19, // 22: terraform.TerraformSvc.ListExecution:input_type -> general.ListOptions + 18, // 23: terraform.TerraformSvc.CreateState:output_type -> general.ResourceId + 2, // 24: terraform.TerraformSvc.GetState:output_type -> terraform.State + 20, // 25: terraform.TerraformSvc.DeleteState:output_type -> google.protobuf.Empty + 20, // 26: terraform.TerraformSvc.DeleteCollectionState:output_type -> google.protobuf.Empty + 4, // 27: terraform.TerraformSvc.ListState:output_type -> terraform.ListStateResponse + 5, // 28: terraform.TerraformSvc.GetExecution:output_type -> terraform.Execution + 7, // 29: terraform.TerraformSvc.ListExecution:output_type -> terraform.ListExecutionResponse + 23, // [23:30] is the sub-list for method output_type + 16, // [16:23] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name +} + +func init() { file_terraform_terraform_proto_init() } +func file_terraform_terraform_proto_init() { + if File_terraform_terraform_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_terraform_terraform_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*State); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Execution); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListExecutionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Variables); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Condition); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ModuleContent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_terraform_terraform_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GitLocation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_terraform_terraform_proto_rawDesc, + NumEnums: 1, + NumMessages: 15, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_terraform_terraform_proto_goTypes, + DependencyIndexes: file_terraform_terraform_proto_depIdxs, + EnumInfos: file_terraform_terraform_proto_enumTypes, + MessageInfos: file_terraform_terraform_proto_msgTypes, + }.Build() + File_terraform_terraform_proto = out.File + file_terraform_terraform_proto_rawDesc = nil + file_terraform_terraform_proto_goTypes = nil + file_terraform_terraform_proto_depIdxs = nil +} diff --git a/v3/protos/terraform/terraform.proto b/v3/protos/terraform/terraform.proto new file mode 100644 index 00000000..4dca33e8 --- /dev/null +++ b/v3/protos/terraform/terraform.proto @@ -0,0 +1,116 @@ +syntax = "proto3"; + +package terraform; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/terraform;terraformpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; + +service TerraformSvc { + rpc CreateState (CreateStateRequest) returns (general.ResourceId); + rpc GetState (general.GetRequest) returns (State); + rpc DeleteState (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionState (general.ListOptions) returns (google.protobuf.Empty); + rpc ListState (general.ListOptions) returns (ListStateResponse); + rpc GetExecution (general.GetRequest) returns (Execution); + rpc ListExecution (general.ListOptions) returns (ListExecutionResponse); +} + +message CreateStateRequest { + string vm_id = 1; + string image = 2; + Variables variables = 3; + string module_name = 4; + map data = 5; + bool auto_confirm = 6; + bool destroy_on_delete = 7; + int32 version = 8; +} + +message State { + string id = 1; + string image = 2; + Variables variables = 3; + string module_name = 4; + map data = 5; + bool auto_confirm = 6; + bool destroy_on_delete = 7; + int32 version = 8; + StateStatus status = 9; + google.protobuf.Timestamp creation_timestamp = 10; +} + +message StateStatus { + repeated Condition conditions = 1; + string last_run_hash = 2; + string execution_name = 3; + string execution_plan_name = 4; +} + +message ListStateResponse { + repeated State states = 1; +} + +message Execution { + string id = 1; + bool auto_confirm = 2; + ModuleContent content = 3; + string content_hash = 4; + string run_hash = 5; + map data = 6; + string execution_name = 7; + int32 execution_version = 8; + string secret_name = 9; + ExecutionStatus status = 10; + google.protobuf.Timestamp creation_timestamp = 11; +} + +message ExecutionStatus { + repeated Condition conditions = 1; + string job_name = 2; + string job_logs = 3; + string plan_output = 4; + bool plan_confirmed = 5; + string apply_output = 6; + string outputs = 7; +} + +message ListExecutionResponse { + repeated Execution executions = 1; +} + +message Variables { + repeated string env_config_names = 1; + repeated string env_secret_names = 2; + repeated string config_names = 3; + repeated string secret_names = 4; +} + +message Condition { + string type = 1; + enum ConditionStatus { + True = 0; + False = 1; + Unknown = 2; + } + string last_update_time = 3; + string last_transition_time = 4; + string reason = 5; + string message = 6; +} + +message ModuleContent { + map content = 1; + GitLocation git = 2; +} + +message GitLocation { + string url = 1; + string branch = 2; + string tag = 3; + string commit = 4; + string secret_name = 5; + int64 interval_seconds = 6; +} \ No newline at end of file diff --git a/v3/protos/terraform/terraform_grpc.pb.go b/v3/protos/terraform/terraform_grpc.pb.go new file mode 100644 index 00000000..73422b3c --- /dev/null +++ b/v3/protos/terraform/terraform_grpc.pb.go @@ -0,0 +1,333 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: terraform/terraform.proto + +package terraformpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + TerraformSvc_CreateState_FullMethodName = "/terraform.TerraformSvc/CreateState" + TerraformSvc_GetState_FullMethodName = "/terraform.TerraformSvc/GetState" + TerraformSvc_DeleteState_FullMethodName = "/terraform.TerraformSvc/DeleteState" + TerraformSvc_DeleteCollectionState_FullMethodName = "/terraform.TerraformSvc/DeleteCollectionState" + TerraformSvc_ListState_FullMethodName = "/terraform.TerraformSvc/ListState" + TerraformSvc_GetExecution_FullMethodName = "/terraform.TerraformSvc/GetExecution" + TerraformSvc_ListExecution_FullMethodName = "/terraform.TerraformSvc/ListExecution" +) + +// TerraformSvcClient is the client API for TerraformSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type TerraformSvcClient interface { + CreateState(ctx context.Context, in *CreateStateRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetState(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*State, error) + DeleteState(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionState(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListState(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListStateResponse, error) + GetExecution(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Execution, error) + ListExecution(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListExecutionResponse, error) +} + +type terraformSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewTerraformSvcClient(cc grpc.ClientConnInterface) TerraformSvcClient { + return &terraformSvcClient{cc} +} + +func (c *terraformSvcClient) CreateState(ctx context.Context, in *CreateStateRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, TerraformSvc_CreateState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) GetState(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*State, error) { + out := new(State) + err := c.cc.Invoke(ctx, TerraformSvc_GetState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) DeleteState(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, TerraformSvc_DeleteState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) DeleteCollectionState(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, TerraformSvc_DeleteCollectionState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) ListState(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListStateResponse, error) { + out := new(ListStateResponse) + err := c.cc.Invoke(ctx, TerraformSvc_ListState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) GetExecution(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*Execution, error) { + out := new(Execution) + err := c.cc.Invoke(ctx, TerraformSvc_GetExecution_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *terraformSvcClient) ListExecution(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListExecutionResponse, error) { + out := new(ListExecutionResponse) + err := c.cc.Invoke(ctx, TerraformSvc_ListExecution_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TerraformSvcServer is the server API for TerraformSvc service. +// All implementations must embed UnimplementedTerraformSvcServer +// for forward compatibility +type TerraformSvcServer interface { + CreateState(context.Context, *CreateStateRequest) (*general.ResourceId, error) + GetState(context.Context, *general.GetRequest) (*State, error) + DeleteState(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionState(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListState(context.Context, *general.ListOptions) (*ListStateResponse, error) + GetExecution(context.Context, *general.GetRequest) (*Execution, error) + ListExecution(context.Context, *general.ListOptions) (*ListExecutionResponse, error) + mustEmbedUnimplementedTerraformSvcServer() +} + +// UnimplementedTerraformSvcServer must be embedded to have forward compatible implementations. +type UnimplementedTerraformSvcServer struct { +} + +func (UnimplementedTerraformSvcServer) CreateState(context.Context, *CreateStateRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateState not implemented") +} +func (UnimplementedTerraformSvcServer) GetState(context.Context, *general.GetRequest) (*State, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetState not implemented") +} +func (UnimplementedTerraformSvcServer) DeleteState(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteState not implemented") +} +func (UnimplementedTerraformSvcServer) DeleteCollectionState(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionState not implemented") +} +func (UnimplementedTerraformSvcServer) ListState(context.Context, *general.ListOptions) (*ListStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListState not implemented") +} +func (UnimplementedTerraformSvcServer) GetExecution(context.Context, *general.GetRequest) (*Execution, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecution not implemented") +} +func (UnimplementedTerraformSvcServer) ListExecution(context.Context, *general.ListOptions) (*ListExecutionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListExecution not implemented") +} +func (UnimplementedTerraformSvcServer) mustEmbedUnimplementedTerraformSvcServer() {} + +// UnsafeTerraformSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to TerraformSvcServer will +// result in compilation errors. +type UnsafeTerraformSvcServer interface { + mustEmbedUnimplementedTerraformSvcServer() +} + +func RegisterTerraformSvcServer(s grpc.ServiceRegistrar, srv TerraformSvcServer) { + s.RegisterService(&TerraformSvc_ServiceDesc, srv) +} + +func _TerraformSvc_CreateState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).CreateState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_CreateState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).CreateState(ctx, req.(*CreateStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_GetState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).GetState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_GetState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).GetState(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_DeleteState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).DeleteState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_DeleteState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).DeleteState(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_DeleteCollectionState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).DeleteCollectionState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_DeleteCollectionState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).DeleteCollectionState(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_ListState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).ListState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_ListState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).ListState(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_GetExecution_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).GetExecution(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_GetExecution_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).GetExecution(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TerraformSvc_ListExecution_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TerraformSvcServer).ListExecution(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TerraformSvc_ListExecution_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TerraformSvcServer).ListExecution(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// TerraformSvc_ServiceDesc is the grpc.ServiceDesc for TerraformSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var TerraformSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "terraform.TerraformSvc", + HandlerType: (*TerraformSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateState", + Handler: _TerraformSvc_CreateState_Handler, + }, + { + MethodName: "GetState", + Handler: _TerraformSvc_GetState_Handler, + }, + { + MethodName: "DeleteState", + Handler: _TerraformSvc_DeleteState_Handler, + }, + { + MethodName: "DeleteCollectionState", + Handler: _TerraformSvc_DeleteCollectionState_Handler, + }, + { + MethodName: "ListState", + Handler: _TerraformSvc_ListState_Handler, + }, + { + MethodName: "GetExecution", + Handler: _TerraformSvc_GetExecution_Handler, + }, + { + MethodName: "ListExecution", + Handler: _TerraformSvc_ListExecution_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "terraform/terraform.proto", +} diff --git a/v3/protos/user/user.pb.go b/v3/protos/user/user.pb.go index 599789d2..d59dbae4 100644 --- a/v3/protos/user/user.pb.go +++ b/v3/protos/user/user.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: user/user.proto -package user +package userpb import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -131,53 +132,6 @@ func (x *UpdateAccessCodesRequest) GetAccessCodes() []string { return nil } -type UserId struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *UserId) Reset() { - *x = UserId{} - if protoimpl.UnsafeEnabled { - mi := &file_user_user_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UserId) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserId) ProtoMessage() {} - -func (x *UserId) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UserId.ProtoReflect.Descriptor instead. -func (*UserId) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{2} -} - -func (x *UserId) GetId() string { - if x != nil { - return x.Id - } - return "" -} - type GetUserByEmailRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -189,7 +143,7 @@ type GetUserByEmailRequest struct { func (x *GetUserByEmailRequest) Reset() { *x = GetUserByEmailRequest{} if protoimpl.UnsafeEnabled { - mi := &file_user_user_proto_msgTypes[3] + mi := &file_user_user_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -202,7 +156,7 @@ func (x *GetUserByEmailRequest) String() string { func (*GetUserByEmailRequest) ProtoMessage() {} func (x *GetUserByEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[3] + mi := &file_user_user_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -215,7 +169,7 @@ func (x *GetUserByEmailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUserByEmailRequest.ProtoReflect.Descriptor instead. func (*GetUserByEmailRequest) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{3} + return file_user_user_proto_rawDescGZIP(), []int{2} } func (x *GetUserByEmailRequest) GetEmail() string { @@ -231,18 +185,19 @@ type User struct { unknownFields protoimpl.UnknownFields Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` - AccessCodes []string `protobuf:"bytes,4,rep,name=access_codes,json=accessCodes,proto3" json:"access_codes,omitempty"` - Settings map[string]string `protobuf:"bytes,5,rep,name=settings,proto3" json:"settings,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - LastLoginTimestamp string `protobuf:"bytes,6,opt,name=last_login_timestamp,json=lastLoginTimestamp,proto3" json:"last_login_timestamp,omitempty"` - RegisteredTimestamp string `protobuf:"bytes,7,opt,name=registered_timestamp,json=registeredTimestamp,proto3" json:"registered_timestamp,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + AccessCodes []string `protobuf:"bytes,5,rep,name=access_codes,json=accessCodes,proto3" json:"access_codes,omitempty"` + Settings map[string]string `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + LastLoginTimestamp string `protobuf:"bytes,7,opt,name=last_login_timestamp,json=lastLoginTimestamp,proto3" json:"last_login_timestamp,omitempty"` + RegisteredTimestamp string `protobuf:"bytes,8,opt,name=registered_timestamp,json=registeredTimestamp,proto3" json:"registered_timestamp,omitempty"` } func (x *User) Reset() { *x = User{} if protoimpl.UnsafeEnabled { - mi := &file_user_user_proto_msgTypes[4] + mi := &file_user_user_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -255,7 +210,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[4] + mi := &file_user_user_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -268,7 +223,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{4} + return file_user_user_proto_rawDescGZIP(), []int{3} } func (x *User) GetId() string { @@ -278,6 +233,13 @@ func (x *User) GetId() string { return "" } +func (x *User) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + func (x *User) GetEmail() string { if x != nil { return x.Email @@ -331,7 +293,7 @@ type ListUsersResponse struct { func (x *ListUsersResponse) Reset() { *x = ListUsersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_user_user_proto_msgTypes[5] + mi := &file_user_user_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -344,7 +306,7 @@ func (x *ListUsersResponse) String() string { func (*ListUsersResponse) ProtoMessage() {} func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[5] + mi := &file_user_user_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -357,7 +319,7 @@ func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUsersResponse.ProtoReflect.Descriptor instead. func (*ListUsersResponse) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{5} + return file_user_user_proto_rawDescGZIP(), []int{4} } func (x *ListUsersResponse) GetUsers() []*User { @@ -371,77 +333,80 @@ var File_user_user_proto protoreflect.FileDescriptor var file_user_user_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x18, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x06, 0x55, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, - 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x22, 0xc3, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x04, + 0x6f, 0x12, 0x04, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x11, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, + 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x12, 0x34, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x3b, 0x0a, 0x0d, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x35, 0x0a, 0x11, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, - 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x32, 0xb9, 0x03, 0x0a, 0x07, 0x55, 0x73, 0x65, 0x72, 0x53, 0x76, 0x63, 0x12, 0x33, 0x0a, 0x0a, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x49, 0x64, - 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x0a, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1b, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x45, 0x6d, 0x61, - 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, - 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x15, 0x53, - 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0xd5, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, + 0x12, 0x34, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6c, + 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x3b, 0x0a, 0x0d, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x35, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, + 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x32, + 0xd3, 0x03, 0x0a, 0x07, 0x55, 0x73, 0x65, 0x72, 0x53, 0x76, 0x63, 0x12, 0x3a, 0x0a, 0x0a, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x42, 0x79, 0x49, 0x64, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1b, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x12, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x0a, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x4c, + 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, + 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, + 0x64, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, + 0x39, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x11, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, - 0x1e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x0a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x0a, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0c, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x3b, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2f, 0x5a, 0x2d, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, - 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, - 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x08, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x17, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, + 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } @@ -457,36 +422,38 @@ func file_user_user_proto_rawDescGZIP() []byte { return file_user_user_proto_rawDescData } -var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_user_user_proto_goTypes = []interface{}{ (*CreateUserRequest)(nil), // 0: user.CreateUserRequest (*UpdateAccessCodesRequest)(nil), // 1: user.UpdateAccessCodesRequest - (*UserId)(nil), // 2: user.UserId - (*GetUserByEmailRequest)(nil), // 3: user.GetUserByEmailRequest - (*User)(nil), // 4: user.User - (*ListUsersResponse)(nil), // 5: user.ListUsersResponse - nil, // 6: user.User.SettingsEntry - (*emptypb.Empty)(nil), // 7: google.protobuf.Empty + (*GetUserByEmailRequest)(nil), // 2: user.GetUserByEmailRequest + (*User)(nil), // 3: user.User + (*ListUsersResponse)(nil), // 4: user.ListUsersResponse + nil, // 5: user.User.SettingsEntry + (*general.GetRequest)(nil), // 6: general.GetRequest + (*general.ResourceId)(nil), // 7: general.ResourceId + (*general.ListOptions)(nil), // 8: general.ListOptions + (*emptypb.Empty)(nil), // 9: google.protobuf.Empty } var file_user_user_proto_depIdxs = []int32{ - 6, // 0: user.User.settings:type_name -> user.User.SettingsEntry - 4, // 1: user.ListUsersResponse.users:type_name -> user.User + 5, // 0: user.User.settings:type_name -> user.User.SettingsEntry + 3, // 1: user.ListUsersResponse.users:type_name -> user.User 0, // 2: user.UserSvc.CreateUser:input_type -> user.CreateUserRequest - 2, // 3: user.UserSvc.GetUserById:input_type -> user.UserId - 3, // 4: user.UserSvc.GetUserByEmail:input_type -> user.GetUserByEmailRequest - 4, // 5: user.UserSvc.UpdateUser:input_type -> user.User - 2, // 6: user.UserSvc.SetLastLoginTimestamp:input_type -> user.UserId + 6, // 3: user.UserSvc.GetUserById:input_type -> general.GetRequest + 2, // 4: user.UserSvc.GetUserByEmail:input_type -> user.GetUserByEmailRequest + 3, // 5: user.UserSvc.UpdateUser:input_type -> user.User + 7, // 6: user.UserSvc.SetLastLoginTimestamp:input_type -> general.ResourceId 1, // 7: user.UserSvc.UpdateAccessCodes:input_type -> user.UpdateAccessCodesRequest - 2, // 8: user.UserSvc.DeleteUser:input_type -> user.UserId - 7, // 9: user.UserSvc.ListUser:input_type -> google.protobuf.Empty - 2, // 10: user.UserSvc.CreateUser:output_type -> user.UserId - 4, // 11: user.UserSvc.GetUserById:output_type -> user.User - 4, // 12: user.UserSvc.GetUserByEmail:output_type -> user.User - 4, // 13: user.UserSvc.UpdateUser:output_type -> user.User - 7, // 14: user.UserSvc.SetLastLoginTimestamp:output_type -> google.protobuf.Empty - 4, // 15: user.UserSvc.UpdateAccessCodes:output_type -> user.User - 7, // 16: user.UserSvc.DeleteUser:output_type -> google.protobuf.Empty - 5, // 17: user.UserSvc.ListUser:output_type -> user.ListUsersResponse + 7, // 8: user.UserSvc.DeleteUser:input_type -> general.ResourceId + 8, // 9: user.UserSvc.ListUser:input_type -> general.ListOptions + 7, // 10: user.UserSvc.CreateUser:output_type -> general.ResourceId + 3, // 11: user.UserSvc.GetUserById:output_type -> user.User + 3, // 12: user.UserSvc.GetUserByEmail:output_type -> user.User + 3, // 13: user.UserSvc.UpdateUser:output_type -> user.User + 9, // 14: user.UserSvc.SetLastLoginTimestamp:output_type -> google.protobuf.Empty + 3, // 15: user.UserSvc.UpdateAccessCodes:output_type -> user.User + 9, // 16: user.UserSvc.DeleteUser:output_type -> google.protobuf.Empty + 4, // 17: user.UserSvc.ListUser:output_type -> user.ListUsersResponse 10, // [10:18] is the sub-list for method output_type 2, // [2:10] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name @@ -525,18 +492,6 @@ func file_user_user_proto_init() { } } file_user_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserId); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_user_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetUserByEmailRequest); i { case 0: return &v.state @@ -548,7 +503,7 @@ func file_user_user_proto_init() { return nil } } - file_user_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_user_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*User); i { case 0: return &v.state @@ -560,7 +515,7 @@ func file_user_user_proto_init() { return nil } } - file_user_user_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_user_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListUsersResponse); i { case 0: return &v.state @@ -579,7 +534,7 @@ func file_user_user_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_user_user_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/v3/protos/user/user.proto b/v3/protos/user/user.proto index d4d0603a..fe580483 100644 --- a/v3/protos/user/user.proto +++ b/v3/protos/user/user.proto @@ -2,20 +2,21 @@ syntax = "proto3"; package user; -option go_package = "github.com/hobbyfarm/gargantua/v3/protos/user"; +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/user;userpb"; +import "general/general.proto"; import "google/protobuf/empty.proto"; // Service definition service UserSvc { - rpc CreateUser (CreateUserRequest) returns (UserId); - rpc GetUserById (UserId) returns (User); + rpc CreateUser (CreateUserRequest) returns (general.ResourceId); + rpc GetUserById (general.GetRequest) returns (User); rpc GetUserByEmail (GetUserByEmailRequest) returns (User); rpc UpdateUser (User) returns (User); - rpc SetLastLoginTimestamp (UserId) returns (google.protobuf.Empty); + rpc SetLastLoginTimestamp (general.ResourceId) returns (google.protobuf.Empty); rpc UpdateAccessCodes (UpdateAccessCodesRequest) returns (User); - rpc DeleteUser (UserId) returns (google.protobuf.Empty); - rpc ListUser (google.protobuf.Empty) returns (ListUsersResponse); + rpc DeleteUser (general.ResourceId) returns (google.protobuf.Empty); + rpc ListUser (general.ListOptions) returns (ListUsersResponse); } message CreateUserRequest { @@ -28,22 +29,19 @@ message UpdateAccessCodesRequest { repeated string access_codes = 2; } -message UserId { - string id = 1; -} - message GetUserByEmailRequest { string email = 1; } message User { string id = 1; - string email = 2; - string password = 3; - repeated string access_codes = 4; - map settings = 5; - string last_login_timestamp = 6; - string registered_timestamp = 7; + string uid = 2; + string email = 3; + string password = 4; + repeated string access_codes = 5; + map settings = 6; + string last_login_timestamp = 7; + string registered_timestamp = 8; } message ListUsersResponse { diff --git a/v3/protos/user/user_grpc.pb.go b/v3/protos/user/user_grpc.pb.go index 5f95f62f..eee73830 100644 --- a/v3/protos/user/user_grpc.pb.go +++ b/v3/protos/user/user_grpc.pb.go @@ -4,10 +4,11 @@ // - protoc v3.21.12 // source: user/user.proto -package user +package userpb import ( context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -34,14 +35,14 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UserSvcClient interface { - CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*UserId, error) - GetUserById(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*User, error) + CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetUserById(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*User, error) GetUserByEmail(ctx context.Context, in *GetUserByEmailRequest, opts ...grpc.CallOption) (*User, error) UpdateUser(ctx context.Context, in *User, opts ...grpc.CallOption) (*User, error) - SetLastLoginTimestamp(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*emptypb.Empty, error) + SetLastLoginTimestamp(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) UpdateAccessCodes(ctx context.Context, in *UpdateAccessCodesRequest, opts ...grpc.CallOption) (*User, error) - DeleteUser(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*emptypb.Empty, error) - ListUser(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListUsersResponse, error) + DeleteUser(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListUser(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListUsersResponse, error) } type userSvcClient struct { @@ -52,8 +53,8 @@ func NewUserSvcClient(cc grpc.ClientConnInterface) UserSvcClient { return &userSvcClient{cc} } -func (c *userSvcClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*UserId, error) { - out := new(UserId) +func (c *userSvcClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) err := c.cc.Invoke(ctx, UserSvc_CreateUser_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -61,7 +62,7 @@ func (c *userSvcClient) CreateUser(ctx context.Context, in *CreateUserRequest, o return out, nil } -func (c *userSvcClient) GetUserById(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*User, error) { +func (c *userSvcClient) GetUserById(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*User, error) { out := new(User) err := c.cc.Invoke(ctx, UserSvc_GetUserById_FullMethodName, in, out, opts...) if err != nil { @@ -88,7 +89,7 @@ func (c *userSvcClient) UpdateUser(ctx context.Context, in *User, opts ...grpc.C return out, nil } -func (c *userSvcClient) SetLastLoginTimestamp(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *userSvcClient) SetLastLoginTimestamp(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, UserSvc_SetLastLoginTimestamp_FullMethodName, in, out, opts...) if err != nil { @@ -106,7 +107,7 @@ func (c *userSvcClient) UpdateAccessCodes(ctx context.Context, in *UpdateAccessC return out, nil } -func (c *userSvcClient) DeleteUser(ctx context.Context, in *UserId, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *userSvcClient) DeleteUser(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, UserSvc_DeleteUser_FullMethodName, in, out, opts...) if err != nil { @@ -115,7 +116,7 @@ func (c *userSvcClient) DeleteUser(ctx context.Context, in *UserId, opts ...grpc return out, nil } -func (c *userSvcClient) ListUser(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListUsersResponse, error) { +func (c *userSvcClient) ListUser(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListUsersResponse, error) { out := new(ListUsersResponse) err := c.cc.Invoke(ctx, UserSvc_ListUser_FullMethodName, in, out, opts...) if err != nil { @@ -128,14 +129,14 @@ func (c *userSvcClient) ListUser(ctx context.Context, in *emptypb.Empty, opts .. // All implementations must embed UnimplementedUserSvcServer // for forward compatibility type UserSvcServer interface { - CreateUser(context.Context, *CreateUserRequest) (*UserId, error) - GetUserById(context.Context, *UserId) (*User, error) + CreateUser(context.Context, *CreateUserRequest) (*general.ResourceId, error) + GetUserById(context.Context, *general.GetRequest) (*User, error) GetUserByEmail(context.Context, *GetUserByEmailRequest) (*User, error) UpdateUser(context.Context, *User) (*User, error) - SetLastLoginTimestamp(context.Context, *UserId) (*emptypb.Empty, error) + SetLastLoginTimestamp(context.Context, *general.ResourceId) (*emptypb.Empty, error) UpdateAccessCodes(context.Context, *UpdateAccessCodesRequest) (*User, error) - DeleteUser(context.Context, *UserId) (*emptypb.Empty, error) - ListUser(context.Context, *emptypb.Empty) (*ListUsersResponse, error) + DeleteUser(context.Context, *general.ResourceId) (*emptypb.Empty, error) + ListUser(context.Context, *general.ListOptions) (*ListUsersResponse, error) mustEmbedUnimplementedUserSvcServer() } @@ -143,10 +144,10 @@ type UserSvcServer interface { type UnimplementedUserSvcServer struct { } -func (UnimplementedUserSvcServer) CreateUser(context.Context, *CreateUserRequest) (*UserId, error) { +func (UnimplementedUserSvcServer) CreateUser(context.Context, *CreateUserRequest) (*general.ResourceId, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented") } -func (UnimplementedUserSvcServer) GetUserById(context.Context, *UserId) (*User, error) { +func (UnimplementedUserSvcServer) GetUserById(context.Context, *general.GetRequest) (*User, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUserById not implemented") } func (UnimplementedUserSvcServer) GetUserByEmail(context.Context, *GetUserByEmailRequest) (*User, error) { @@ -155,16 +156,16 @@ func (UnimplementedUserSvcServer) GetUserByEmail(context.Context, *GetUserByEmai func (UnimplementedUserSvcServer) UpdateUser(context.Context, *User) (*User, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented") } -func (UnimplementedUserSvcServer) SetLastLoginTimestamp(context.Context, *UserId) (*emptypb.Empty, error) { +func (UnimplementedUserSvcServer) SetLastLoginTimestamp(context.Context, *general.ResourceId) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetLastLoginTimestamp not implemented") } func (UnimplementedUserSvcServer) UpdateAccessCodes(context.Context, *UpdateAccessCodesRequest) (*User, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateAccessCodes not implemented") } -func (UnimplementedUserSvcServer) DeleteUser(context.Context, *UserId) (*emptypb.Empty, error) { +func (UnimplementedUserSvcServer) DeleteUser(context.Context, *general.ResourceId) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented") } -func (UnimplementedUserSvcServer) ListUser(context.Context, *emptypb.Empty) (*ListUsersResponse, error) { +func (UnimplementedUserSvcServer) ListUser(context.Context, *general.ListOptions) (*ListUsersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListUser not implemented") } func (UnimplementedUserSvcServer) mustEmbedUnimplementedUserSvcServer() {} @@ -199,7 +200,7 @@ func _UserSvc_CreateUser_Handler(srv interface{}, ctx context.Context, dec func( } func _UserSvc_GetUserById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UserId) + in := new(general.GetRequest) if err := dec(in); err != nil { return nil, err } @@ -211,7 +212,7 @@ func _UserSvc_GetUserById_Handler(srv interface{}, ctx context.Context, dec func FullMethod: UserSvc_GetUserById_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserSvcServer).GetUserById(ctx, req.(*UserId)) + return srv.(UserSvcServer).GetUserById(ctx, req.(*general.GetRequest)) } return interceptor(ctx, in, info, handler) } @@ -253,7 +254,7 @@ func _UserSvc_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func( } func _UserSvc_SetLastLoginTimestamp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UserId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -265,7 +266,7 @@ func _UserSvc_SetLastLoginTimestamp_Handler(srv interface{}, ctx context.Context FullMethod: UserSvc_SetLastLoginTimestamp_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserSvcServer).SetLastLoginTimestamp(ctx, req.(*UserId)) + return srv.(UserSvcServer).SetLastLoginTimestamp(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } @@ -289,7 +290,7 @@ func _UserSvc_UpdateAccessCodes_Handler(srv interface{}, ctx context.Context, de } func _UserSvc_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UserId) + in := new(general.ResourceId) if err := dec(in); err != nil { return nil, err } @@ -301,13 +302,13 @@ func _UserSvc_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func( FullMethod: UserSvc_DeleteUser_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserSvcServer).DeleteUser(ctx, req.(*UserId)) + return srv.(UserSvcServer).DeleteUser(ctx, req.(*general.ResourceId)) } return interceptor(ctx, in, info, handler) } func _UserSvc_ListUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) + in := new(general.ListOptions) if err := dec(in); err != nil { return nil, err } @@ -319,7 +320,7 @@ func _UserSvc_ListUser_Handler(srv interface{}, ctx context.Context, dec func(in FullMethod: UserSvc_ListUser_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserSvcServer).ListUser(ctx, req.(*emptypb.Empty)) + return srv.(UserSvcServer).ListUser(ctx, req.(*general.ListOptions)) } return interceptor(ctx, in, info, handler) } diff --git a/v3/protos/vm/vm.pb.go b/v3/protos/vm/vm.pb.go new file mode 100644 index 00000000..310d2c77 --- /dev/null +++ b/v3/protos/vm/vm.pb.go @@ -0,0 +1,1038 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: vm/vm.proto + +package vmpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VM struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + VmTemplateId string `protobuf:"bytes,3,opt,name=vm_template_id,json=vmTemplateId,proto3" json:"vm_template_id,omitempty"` + SshUsername string `protobuf:"bytes,4,opt,name=ssh_username,json=sshUsername,proto3" json:"ssh_username,omitempty"` + Protocol string `protobuf:"bytes,5,opt,name=protocol,proto3" json:"protocol,omitempty"` + SecretName string `protobuf:"bytes,6,opt,name=secret_name,json=secretName,proto3" json:"secret_name,omitempty"` + VmClaimId string `protobuf:"bytes,7,opt,name=vm_claim_id,json=vmClaimId,proto3" json:"vm_claim_id,omitempty"` + User string `protobuf:"bytes,8,opt,name=user,proto3" json:"user,omitempty"` + Provision bool `protobuf:"varint,9,opt,name=provision,proto3" json:"provision,omitempty"` + VmSetId string `protobuf:"bytes,10,opt,name=vm_set_id,json=vmSetId,proto3" json:"vm_set_id,omitempty"` + Labels map[string]string `protobuf:"bytes,11,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Finalizers []string `protobuf:"bytes,12,rep,name=finalizers,proto3" json:"finalizers,omitempty"` + Status *VMStatus `protobuf:"bytes,13,opt,name=status,proto3" json:"status,omitempty"` + Annotations map[string]string `protobuf:"bytes,14,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DeletionTimestamp *timestamppb.Timestamp `protobuf:"bytes,15,opt,name=deletion_timestamp,json=deletionTimestamp,proto3" json:"deletion_timestamp,omitempty"` +} + +func (x *VM) Reset() { + *x = VM{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VM) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VM) ProtoMessage() {} + +func (x *VM) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VM.ProtoReflect.Descriptor instead. +func (*VM) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{0} +} + +func (x *VM) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *VM) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *VM) GetVmTemplateId() string { + if x != nil { + return x.VmTemplateId + } + return "" +} + +func (x *VM) GetSshUsername() string { + if x != nil { + return x.SshUsername + } + return "" +} + +func (x *VM) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *VM) GetSecretName() string { + if x != nil { + return x.SecretName + } + return "" +} + +func (x *VM) GetVmClaimId() string { + if x != nil { + return x.VmClaimId + } + return "" +} + +func (x *VM) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *VM) GetProvision() bool { + if x != nil { + return x.Provision + } + return false +} + +func (x *VM) GetVmSetId() string { + if x != nil { + return x.VmSetId + } + return "" +} + +func (x *VM) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *VM) GetFinalizers() []string { + if x != nil { + return x.Finalizers + } + return nil +} + +func (x *VM) GetStatus() *VMStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *VM) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *VM) GetDeletionTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.DeletionTimestamp + } + return nil +} + +type CreateVMRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + VmTemplateId string `protobuf:"bytes,2,opt,name=vm_template_id,json=vmTemplateId,proto3" json:"vm_template_id,omitempty"` + SshUsername string `protobuf:"bytes,3,opt,name=ssh_username,json=sshUsername,proto3" json:"ssh_username,omitempty"` + Protocol string `protobuf:"bytes,4,opt,name=protocol,proto3" json:"protocol,omitempty"` + SecretName string `protobuf:"bytes,5,opt,name=secret_name,json=secretName,proto3" json:"secret_name,omitempty"` + VmClaimId string `protobuf:"bytes,6,opt,name=vm_claim_id,json=vmClaimId,proto3" json:"vm_claim_id,omitempty"` + VmClaimUid string `protobuf:"bytes,7,opt,name=vm_claim_uid,json=vmClaimUid,proto3" json:"vm_claim_uid,omitempty"` + User string `protobuf:"bytes,8,opt,name=user,proto3" json:"user,omitempty"` + Provision bool `protobuf:"varint,9,opt,name=provision,proto3" json:"provision,omitempty"` + VmSetId string `protobuf:"bytes,10,opt,name=vm_set_id,json=vmSetId,proto3" json:"vm_set_id,omitempty"` + VmSetUid string `protobuf:"bytes,11,opt,name=vm_set_uid,json=vmSetUid,proto3" json:"vm_set_uid,omitempty"` + Labels map[string]string `protobuf:"bytes,12,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Finalizers []string `protobuf:"bytes,13,rep,name=finalizers,proto3" json:"finalizers,omitempty"` +} + +func (x *CreateVMRequest) Reset() { + *x = CreateVMRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVMRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVMRequest) ProtoMessage() {} + +func (x *CreateVMRequest) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVMRequest.ProtoReflect.Descriptor instead. +func (*CreateVMRequest) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateVMRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *CreateVMRequest) GetVmTemplateId() string { + if x != nil { + return x.VmTemplateId + } + return "" +} + +func (x *CreateVMRequest) GetSshUsername() string { + if x != nil { + return x.SshUsername + } + return "" +} + +func (x *CreateVMRequest) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *CreateVMRequest) GetSecretName() string { + if x != nil { + return x.SecretName + } + return "" +} + +func (x *CreateVMRequest) GetVmClaimId() string { + if x != nil { + return x.VmClaimId + } + return "" +} + +func (x *CreateVMRequest) GetVmClaimUid() string { + if x != nil { + return x.VmClaimUid + } + return "" +} + +func (x *CreateVMRequest) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *CreateVMRequest) GetProvision() bool { + if x != nil { + return x.Provision + } + return false +} + +func (x *CreateVMRequest) GetVmSetId() string { + if x != nil { + return x.VmSetId + } + return "" +} + +func (x *CreateVMRequest) GetVmSetUid() string { + if x != nil { + return x.VmSetUid + } + return "" +} + +func (x *CreateVMRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *CreateVMRequest) GetFinalizers() []string { + if x != nil { + return x.Finalizers + } + return nil +} + +type UpdateVMRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Bound string `protobuf:"bytes,2,opt,name=bound,proto3" json:"bound,omitempty"` + VmClaimId *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=vm_claim_id,json=vmClaimId,proto3" json:"vm_claim_id,omitempty"` + User *wrapperspb.StringValue `protobuf:"bytes,4,opt,name=user,proto3" json:"user,omitempty"` + SecretName string `protobuf:"bytes,5,opt,name=secret_name,json=secretName,proto3" json:"secret_name,omitempty"` + Finalizers *general.StringArray `protobuf:"bytes,6,opt,name=finalizers,proto3" json:"finalizers,omitempty"` +} + +func (x *UpdateVMRequest) Reset() { + *x = UpdateVMRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMRequest) ProtoMessage() {} + +func (x *UpdateVMRequest) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMRequest) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateVMRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMRequest) GetBound() string { + if x != nil { + return x.Bound + } + return "" +} + +func (x *UpdateVMRequest) GetVmClaimId() *wrapperspb.StringValue { + if x != nil { + return x.VmClaimId + } + return nil +} + +func (x *UpdateVMRequest) GetUser() *wrapperspb.StringValue { + if x != nil { + return x.User + } + return nil +} + +func (x *UpdateVMRequest) GetSecretName() string { + if x != nil { + return x.SecretName + } + return "" +} + +func (x *UpdateVMRequest) GetFinalizers() *general.StringArray { + if x != nil { + return x.Finalizers + } + return nil +} + +type UpdateVMStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + Allocated *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=allocated,proto3" json:"allocated,omitempty"` + Tainted *wrapperspb.BoolValue `protobuf:"bytes,4,opt,name=tainted,proto3" json:"tainted,omitempty"` + PublicIp *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=public_ip,json=publicIp,proto3" json:"public_ip,omitempty"` + PrivateIp *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=private_ip,json=privateIp,proto3" json:"private_ip,omitempty"` + Hostname *wrapperspb.StringValue `protobuf:"bytes,7,opt,name=hostname,proto3" json:"hostname,omitempty"` + EnvironmentId string `protobuf:"bytes,8,opt,name=environment_id,json=environmentId,proto3" json:"environment_id,omitempty"` + Tfstate string `protobuf:"bytes,9,opt,name=tfstate,proto3" json:"tfstate,omitempty"` + WsEndpoint string `protobuf:"bytes,10,opt,name=ws_endpoint,json=wsEndpoint,proto3" json:"ws_endpoint,omitempty"` +} + +func (x *UpdateVMStatusRequest) Reset() { + *x = UpdateVMStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMStatusRequest) ProtoMessage() {} + +func (x *UpdateVMStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMStatusRequest) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateVMStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMStatusRequest) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *UpdateVMStatusRequest) GetAllocated() *wrapperspb.BoolValue { + if x != nil { + return x.Allocated + } + return nil +} + +func (x *UpdateVMStatusRequest) GetTainted() *wrapperspb.BoolValue { + if x != nil { + return x.Tainted + } + return nil +} + +func (x *UpdateVMStatusRequest) GetPublicIp() *wrapperspb.StringValue { + if x != nil { + return x.PublicIp + } + return nil +} + +func (x *UpdateVMStatusRequest) GetPrivateIp() *wrapperspb.StringValue { + if x != nil { + return x.PrivateIp + } + return nil +} + +func (x *UpdateVMStatusRequest) GetHostname() *wrapperspb.StringValue { + if x != nil { + return x.Hostname + } + return nil +} + +func (x *UpdateVMStatusRequest) GetEnvironmentId() string { + if x != nil { + return x.EnvironmentId + } + return "" +} + +func (x *UpdateVMStatusRequest) GetTfstate() string { + if x != nil { + return x.Tfstate + } + return "" +} + +func (x *UpdateVMStatusRequest) GetWsEndpoint() string { + if x != nil { + return x.WsEndpoint + } + return "" +} + +type VMStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + Allocated bool `protobuf:"varint,2,opt,name=allocated,proto3" json:"allocated,omitempty"` + Tainted bool `protobuf:"varint,3,opt,name=tainted,proto3" json:"tainted,omitempty"` + PublicIp string `protobuf:"bytes,4,opt,name=public_ip,json=publicIp,proto3" json:"public_ip,omitempty"` + PrivateIp string `protobuf:"bytes,5,opt,name=private_ip,json=privateIp,proto3" json:"private_ip,omitempty"` + Hostname string `protobuf:"bytes,6,opt,name=hostname,proto3" json:"hostname,omitempty"` + EnvironmentId string `protobuf:"bytes,7,opt,name=environment_id,json=environmentId,proto3" json:"environment_id,omitempty"` + Tfstate string `protobuf:"bytes,8,opt,name=tfstate,proto3" json:"tfstate,omitempty"` + WsEndpoint string `protobuf:"bytes,9,opt,name=ws_endpoint,json=wsEndpoint,proto3" json:"ws_endpoint,omitempty"` +} + +func (x *VMStatus) Reset() { + *x = VMStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMStatus) ProtoMessage() {} + +func (x *VMStatus) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMStatus.ProtoReflect.Descriptor instead. +func (*VMStatus) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{4} +} + +func (x *VMStatus) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *VMStatus) GetAllocated() bool { + if x != nil { + return x.Allocated + } + return false +} + +func (x *VMStatus) GetTainted() bool { + if x != nil { + return x.Tainted + } + return false +} + +func (x *VMStatus) GetPublicIp() string { + if x != nil { + return x.PublicIp + } + return "" +} + +func (x *VMStatus) GetPrivateIp() string { + if x != nil { + return x.PrivateIp + } + return "" +} + +func (x *VMStatus) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *VMStatus) GetEnvironmentId() string { + if x != nil { + return x.EnvironmentId + } + return "" +} + +func (x *VMStatus) GetTfstate() string { + if x != nil { + return x.Tfstate + } + return "" +} + +func (x *VMStatus) GetWsEndpoint() string { + if x != nil { + return x.WsEndpoint + } + return "" +} + +type ListVMsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vms []*VM `protobuf:"bytes,1,rep,name=vms,proto3" json:"vms,omitempty"` +} + +func (x *ListVMsResponse) Reset() { + *x = ListVMsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVMsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVMsResponse) ProtoMessage() {} + +func (x *ListVMsResponse) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVMsResponse.ProtoReflect.Descriptor instead. +func (*ListVMsResponse) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{5} +} + +func (x *ListVMsResponse) GetVms() []*VM { + if x != nil { + return x.Vms + } + return nil +} + +var File_vm_vm_proto protoreflect.FileDescriptor + +var file_vm_vm_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x76, + 0x6d, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x05, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x24, 0x0a, 0x0e, 0x76, 0x6d, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x73, 0x68, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x73, 0x68, + 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6d, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x09, 0x76, 0x6d, 0x5f, 0x73, 0x65, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x53, 0x65, + 0x74, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0b, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x4d, 0x2e, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x12, + 0x24, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x6d, 0x2e, + 0x56, 0x4d, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x49, 0x0a, 0x12, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe9, 0x03, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x56, 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x76, 0x6d, + 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x73, 0x68, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x73, 0x68, 0x55, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1e, 0x0a, 0x0b, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, + 0x12, 0x20, 0x0a, 0x0c, 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x75, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x55, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x09, 0x76, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x53, 0x65, 0x74, 0x49, 0x64, + 0x12, 0x1c, 0x0a, 0x0a, 0x76, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x6d, 0x53, 0x65, 0x74, 0x55, 0x69, 0x64, 0x12, 0x37, + 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0xfe, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x3c, 0x0a, 0x0b, + 0x76, 0x6d, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x09, 0x76, 0x6d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, + 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x72, 0x73, 0x22, 0xc3, 0x03, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x34, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, 0x61, + 0x69, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, + 0x12, 0x3b, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x70, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x09, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x49, 0x70, 0x12, 0x38, 0x0a, + 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x74, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x74, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x73, 0x5f, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, + 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x94, 0x02, 0x0a, 0x08, 0x56, 0x4d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, + 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x49, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x69, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x49, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x66, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x77, 0x73, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x73, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x22, 0x2b, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x03, 0x76, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x06, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x4d, 0x52, 0x03, 0x76, 0x6d, 0x73, 0x32, 0x96, 0x03, + 0x0a, 0x05, 0x56, 0x4d, 0x53, 0x76, 0x63, 0x12, 0x37, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x56, 0x4d, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x24, 0x0a, 0x05, 0x47, 0x65, 0x74, 0x56, 0x4d, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, + 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x4d, 0x12, 0x37, 0x0a, 0x08, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x4d, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x19, 0x2e, 0x76, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x08, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x4d, + 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, + 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x56, 0x4d, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x33, 0x0a, 0x06, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x12, 0x14, 0x2e, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, + 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x73, 0x2f, 0x76, 0x6d, 0x3b, 0x76, 0x6d, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_vm_vm_proto_rawDescOnce sync.Once + file_vm_vm_proto_rawDescData = file_vm_vm_proto_rawDesc +) + +func file_vm_vm_proto_rawDescGZIP() []byte { + file_vm_vm_proto_rawDescOnce.Do(func() { + file_vm_vm_proto_rawDescData = protoimpl.X.CompressGZIP(file_vm_vm_proto_rawDescData) + }) + return file_vm_vm_proto_rawDescData +} + +var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_vm_vm_proto_goTypes = []interface{}{ + (*VM)(nil), // 0: vm.VM + (*CreateVMRequest)(nil), // 1: vm.CreateVMRequest + (*UpdateVMRequest)(nil), // 2: vm.UpdateVMRequest + (*UpdateVMStatusRequest)(nil), // 3: vm.UpdateVMStatusRequest + (*VMStatus)(nil), // 4: vm.VMStatus + (*ListVMsResponse)(nil), // 5: vm.ListVMsResponse + nil, // 6: vm.VM.LabelsEntry + nil, // 7: vm.VM.AnnotationsEntry + nil, // 8: vm.CreateVMRequest.LabelsEntry + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp + (*wrapperspb.StringValue)(nil), // 10: google.protobuf.StringValue + (*general.StringArray)(nil), // 11: general.StringArray + (*wrapperspb.BoolValue)(nil), // 12: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 13: general.GetRequest + (*general.ResourceId)(nil), // 14: general.ResourceId + (*general.ListOptions)(nil), // 15: general.ListOptions + (*emptypb.Empty)(nil), // 16: google.protobuf.Empty +} +var file_vm_vm_proto_depIdxs = []int32{ + 6, // 0: vm.VM.labels:type_name -> vm.VM.LabelsEntry + 4, // 1: vm.VM.status:type_name -> vm.VMStatus + 7, // 2: vm.VM.annotations:type_name -> vm.VM.AnnotationsEntry + 9, // 3: vm.VM.deletion_timestamp:type_name -> google.protobuf.Timestamp + 8, // 4: vm.CreateVMRequest.labels:type_name -> vm.CreateVMRequest.LabelsEntry + 10, // 5: vm.UpdateVMRequest.vm_claim_id:type_name -> google.protobuf.StringValue + 10, // 6: vm.UpdateVMRequest.user:type_name -> google.protobuf.StringValue + 11, // 7: vm.UpdateVMRequest.finalizers:type_name -> general.StringArray + 12, // 8: vm.UpdateVMStatusRequest.allocated:type_name -> google.protobuf.BoolValue + 12, // 9: vm.UpdateVMStatusRequest.tainted:type_name -> google.protobuf.BoolValue + 10, // 10: vm.UpdateVMStatusRequest.public_ip:type_name -> google.protobuf.StringValue + 10, // 11: vm.UpdateVMStatusRequest.private_ip:type_name -> google.protobuf.StringValue + 10, // 12: vm.UpdateVMStatusRequest.hostname:type_name -> google.protobuf.StringValue + 0, // 13: vm.ListVMsResponse.vms:type_name -> vm.VM + 1, // 14: vm.VMSvc.CreateVM:input_type -> vm.CreateVMRequest + 13, // 15: vm.VMSvc.GetVM:input_type -> general.GetRequest + 2, // 16: vm.VMSvc.UpdateVM:input_type -> vm.UpdateVMRequest + 3, // 17: vm.VMSvc.UpdateVMStatus:input_type -> vm.UpdateVMStatusRequest + 14, // 18: vm.VMSvc.DeleteVM:input_type -> general.ResourceId + 15, // 19: vm.VMSvc.DeleteCollectionVM:input_type -> general.ListOptions + 15, // 20: vm.VMSvc.ListVM:input_type -> general.ListOptions + 16, // 21: vm.VMSvc.CreateVM:output_type -> google.protobuf.Empty + 0, // 22: vm.VMSvc.GetVM:output_type -> vm.VM + 16, // 23: vm.VMSvc.UpdateVM:output_type -> google.protobuf.Empty + 16, // 24: vm.VMSvc.UpdateVMStatus:output_type -> google.protobuf.Empty + 16, // 25: vm.VMSvc.DeleteVM:output_type -> google.protobuf.Empty + 16, // 26: vm.VMSvc.DeleteCollectionVM:output_type -> google.protobuf.Empty + 5, // 27: vm.VMSvc.ListVM:output_type -> vm.ListVMsResponse + 21, // [21:28] is the sub-list for method output_type + 14, // [14:21] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name +} + +func init() { file_vm_vm_proto_init() } +func file_vm_vm_proto_init() { + if File_vm_vm_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_vm_vm_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VM); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateVMRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVMsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_vm_vm_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_vm_vm_proto_goTypes, + DependencyIndexes: file_vm_vm_proto_depIdxs, + MessageInfos: file_vm_vm_proto_msgTypes, + }.Build() + File_vm_vm_proto = out.File + file_vm_vm_proto_rawDesc = nil + file_vm_vm_proto_goTypes = nil + file_vm_vm_proto_depIdxs = nil +} diff --git a/v3/protos/vm/vm.proto b/v3/protos/vm/vm.proto new file mode 100644 index 00000000..dfc72d89 --- /dev/null +++ b/v3/protos/vm/vm.proto @@ -0,0 +1,92 @@ +syntax = "proto3"; + +package vm; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/vm;vmpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/timestamp.proto"; + +service VMSvc { + rpc CreateVM (CreateVMRequest) returns (google.protobuf.Empty); + rpc GetVM (general.GetRequest) returns (VM); + rpc UpdateVM (UpdateVMRequest) returns (google.protobuf.Empty); + rpc UpdateVMStatus (UpdateVMStatusRequest) returns (google.protobuf.Empty); + rpc DeleteVM (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionVM (general.ListOptions) returns (google.protobuf.Empty); + rpc ListVM (general.ListOptions) returns (ListVMsResponse); +} + +message VM { + string id = 1; + string uid = 2; + string vm_template_id = 3; + string ssh_username = 4; + string protocol = 5; + string secret_name = 6; + string vm_claim_id = 7; + string user = 8; + bool provision = 9; + string vm_set_id = 10; + map labels = 11; + repeated string finalizers = 12; + VMStatus status = 13; + map annotations = 14; + google.protobuf.Timestamp deletion_timestamp = 15; +} + +message CreateVMRequest { + string id = 1; + string vm_template_id = 2; + string ssh_username = 3; + string protocol = 4; + string secret_name = 5; + string vm_claim_id = 6; + string vm_claim_uid = 7; + string user = 8; + bool provision = 9; + string vm_set_id = 10; + string vm_set_uid = 11; + map labels = 12; + repeated string finalizers = 13; +} + +message UpdateVMRequest { + string id = 1; + string bound = 2; + google.protobuf.StringValue vm_claim_id = 3; + google.protobuf.StringValue user = 4; + string secret_name = 5; + general.StringArray finalizers = 6; +} + +message UpdateVMStatusRequest { + string id = 1; + string status = 2; + google.protobuf.BoolValue allocated = 3; + google.protobuf.BoolValue tainted = 4; + google.protobuf.StringValue public_ip = 5; + google.protobuf.StringValue private_ip = 6; + google.protobuf.StringValue hostname = 7; + string environment_id = 8; + string tfstate = 9; + string ws_endpoint = 10; +} + +message VMStatus { + string status = 1; + bool allocated = 2; + bool tainted = 3; + string public_ip = 4; + string private_ip = 5; + string hostname = 6; + string environment_id = 7; + string tfstate = 8; + string ws_endpoint = 9; +} + +message ListVMsResponse { + repeated VM vms = 1; +} \ No newline at end of file diff --git a/v3/protos/vm/vm_grpc.pb.go b/v3/protos/vm/vm_grpc.pb.go new file mode 100644 index 00000000..9bda6934 --- /dev/null +++ b/v3/protos/vm/vm_grpc.pb.go @@ -0,0 +1,333 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: vm/vm.proto + +package vmpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + VMSvc_CreateVM_FullMethodName = "/vm.VMSvc/CreateVM" + VMSvc_GetVM_FullMethodName = "/vm.VMSvc/GetVM" + VMSvc_UpdateVM_FullMethodName = "/vm.VMSvc/UpdateVM" + VMSvc_UpdateVMStatus_FullMethodName = "/vm.VMSvc/UpdateVMStatus" + VMSvc_DeleteVM_FullMethodName = "/vm.VMSvc/DeleteVM" + VMSvc_DeleteCollectionVM_FullMethodName = "/vm.VMSvc/DeleteCollectionVM" + VMSvc_ListVM_FullMethodName = "/vm.VMSvc/ListVM" +) + +// VMSvcClient is the client API for VMSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type VMSvcClient interface { + CreateVM(ctx context.Context, in *CreateVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + GetVM(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VM, error) + UpdateVM(ctx context.Context, in *UpdateVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateVMStatus(ctx context.Context, in *UpdateVMStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteVM(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionVM(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListVM(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMsResponse, error) +} + +type vMSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewVMSvcClient(cc grpc.ClientConnInterface) VMSvcClient { + return &vMSvcClient{cc} +} + +func (c *vMSvcClient) CreateVM(ctx context.Context, in *CreateVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSvc_CreateVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) GetVM(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VM, error) { + out := new(VM) + err := c.cc.Invoke(ctx, VMSvc_GetVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) UpdateVM(ctx context.Context, in *UpdateVMRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSvc_UpdateVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) UpdateVMStatus(ctx context.Context, in *UpdateVMStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSvc_UpdateVMStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) DeleteVM(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSvc_DeleteVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) DeleteCollectionVM(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSvc_DeleteCollectionVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSvcClient) ListVM(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMsResponse, error) { + out := new(ListVMsResponse) + err := c.cc.Invoke(ctx, VMSvc_ListVM_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VMSvcServer is the server API for VMSvc service. +// All implementations must embed UnimplementedVMSvcServer +// for forward compatibility +type VMSvcServer interface { + CreateVM(context.Context, *CreateVMRequest) (*emptypb.Empty, error) + GetVM(context.Context, *general.GetRequest) (*VM, error) + UpdateVM(context.Context, *UpdateVMRequest) (*emptypb.Empty, error) + UpdateVMStatus(context.Context, *UpdateVMStatusRequest) (*emptypb.Empty, error) + DeleteVM(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionVM(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListVM(context.Context, *general.ListOptions) (*ListVMsResponse, error) + mustEmbedUnimplementedVMSvcServer() +} + +// UnimplementedVMSvcServer must be embedded to have forward compatible implementations. +type UnimplementedVMSvcServer struct { +} + +func (UnimplementedVMSvcServer) CreateVM(context.Context, *CreateVMRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVM not implemented") +} +func (UnimplementedVMSvcServer) GetVM(context.Context, *general.GetRequest) (*VM, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVM not implemented") +} +func (UnimplementedVMSvcServer) UpdateVM(context.Context, *UpdateVMRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVM not implemented") +} +func (UnimplementedVMSvcServer) UpdateVMStatus(context.Context, *UpdateVMStatusRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMStatus not implemented") +} +func (UnimplementedVMSvcServer) DeleteVM(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteVM not implemented") +} +func (UnimplementedVMSvcServer) DeleteCollectionVM(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionVM not implemented") +} +func (UnimplementedVMSvcServer) ListVM(context.Context, *general.ListOptions) (*ListVMsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVM not implemented") +} +func (UnimplementedVMSvcServer) mustEmbedUnimplementedVMSvcServer() {} + +// UnsafeVMSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VMSvcServer will +// result in compilation errors. +type UnsafeVMSvcServer interface { + mustEmbedUnimplementedVMSvcServer() +} + +func RegisterVMSvcServer(s grpc.ServiceRegistrar, srv VMSvcServer) { + s.RegisterService(&VMSvc_ServiceDesc, srv) +} + +func _VMSvc_CreateVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVMRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).CreateVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_CreateVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).CreateVM(ctx, req.(*CreateVMRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_GetVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).GetVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_GetVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).GetVM(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_UpdateVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).UpdateVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_UpdateVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).UpdateVM(ctx, req.(*UpdateVMRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_UpdateVMStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).UpdateVMStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_UpdateVMStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).UpdateVMStatus(ctx, req.(*UpdateVMStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_DeleteVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).DeleteVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_DeleteVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).DeleteVM(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_DeleteCollectionVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).DeleteCollectionVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_DeleteCollectionVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).DeleteCollectionVM(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSvc_ListVM_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSvcServer).ListVM(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSvc_ListVM_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSvcServer).ListVM(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// VMSvc_ServiceDesc is the grpc.ServiceDesc for VMSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VMSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "vm.VMSvc", + HandlerType: (*VMSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateVM", + Handler: _VMSvc_CreateVM_Handler, + }, + { + MethodName: "GetVM", + Handler: _VMSvc_GetVM_Handler, + }, + { + MethodName: "UpdateVM", + Handler: _VMSvc_UpdateVM_Handler, + }, + { + MethodName: "UpdateVMStatus", + Handler: _VMSvc_UpdateVMStatus_Handler, + }, + { + MethodName: "DeleteVM", + Handler: _VMSvc_DeleteVM_Handler, + }, + { + MethodName: "DeleteCollectionVM", + Handler: _VMSvc_DeleteCollectionVM_Handler, + }, + { + MethodName: "ListVM", + Handler: _VMSvc_ListVM_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vm/vm.proto", +} diff --git a/v3/protos/vmclaim/virtualmachineclaim.pb.go b/v3/protos/vmclaim/virtualmachineclaim.pb.go new file mode 100644 index 00000000..f7a514ef --- /dev/null +++ b/v3/protos/vmclaim/virtualmachineclaim.pb.go @@ -0,0 +1,936 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: vmclaim/virtualmachineclaim.proto + +package vmclaimpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VMClaim struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + RestrictedBind bool `protobuf:"varint,4,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,5,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + Vms map[string]*VMClaimVM `protobuf:"bytes,6,rep,name=vms,proto3" json:"vms,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DynamicCapable bool `protobuf:"varint,7,opt,name=dynamic_capable,json=dynamicCapable,proto3" json:"dynamic_capable,omitempty"` + BaseName string `protobuf:"bytes,8,opt,name=base_name,json=baseName,proto3" json:"base_name,omitempty"` + Labels map[string]string `protobuf:"bytes,9,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Status *VMClaimStatus `protobuf:"bytes,10,opt,name=status,proto3" json:"status,omitempty"` + DeletionTimestamp *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=deletion_timestamp,json=deletionTimestamp,proto3" json:"deletion_timestamp,omitempty"` +} + +func (x *VMClaim) Reset() { + *x = VMClaim{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMClaim) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMClaim) ProtoMessage() {} + +func (x *VMClaim) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMClaim.ProtoReflect.Descriptor instead. +func (*VMClaim) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{0} +} + +func (x *VMClaim) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *VMClaim) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *VMClaim) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *VMClaim) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *VMClaim) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *VMClaim) GetVms() map[string]*VMClaimVM { + if x != nil { + return x.Vms + } + return nil +} + +func (x *VMClaim) GetDynamicCapable() bool { + if x != nil { + return x.DynamicCapable + } + return false +} + +func (x *VMClaim) GetBaseName() string { + if x != nil { + return x.BaseName + } + return "" +} + +func (x *VMClaim) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *VMClaim) GetStatus() *VMClaimStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *VMClaim) GetDeletionTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.DeletionTimestamp + } + return nil +} + +type CreateVMClaimRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + UserName string `protobuf:"bytes,2,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + Vmset map[string]string `protobuf:"bytes,3,rep,name=vmset,proto3" json:"vmset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + RestrictedBind bool `protobuf:"varint,4,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,5,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + DynamicCapable bool `protobuf:"varint,6,opt,name=dynamic_capable,json=dynamicCapable,proto3" json:"dynamic_capable,omitempty"` + Labels map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CreateVMClaimRequest) Reset() { + *x = CreateVMClaimRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVMClaimRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVMClaimRequest) ProtoMessage() {} + +func (x *CreateVMClaimRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVMClaimRequest.ProtoReflect.Descriptor instead. +func (*CreateVMClaimRequest) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateVMClaimRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *CreateVMClaimRequest) GetUserName() string { + if x != nil { + return x.UserName + } + return "" +} + +func (x *CreateVMClaimRequest) GetVmset() map[string]string { + if x != nil { + return x.Vmset + } + return nil +} + +func (x *CreateVMClaimRequest) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *CreateVMClaimRequest) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *CreateVMClaimRequest) GetDynamicCapable() bool { + if x != nil { + return x.DynamicCapable + } + return false +} + +func (x *CreateVMClaimRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type UpdateVMClaimRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Vmset map[string]*VMClaimVM `protobuf:"bytes,2,rep,name=vmset,proto3" json:"vmset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + RestrictedBind *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` +} + +func (x *UpdateVMClaimRequest) Reset() { + *x = UpdateVMClaimRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMClaimRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMClaimRequest) ProtoMessage() {} + +func (x *UpdateVMClaimRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMClaimRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMClaimRequest) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateVMClaimRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMClaimRequest) GetVmset() map[string]*VMClaimVM { + if x != nil { + return x.Vmset + } + return nil +} + +func (x *UpdateVMClaimRequest) GetRestrictedBind() *wrapperspb.BoolValue { + if x != nil { + return x.RestrictedBind + } + return nil +} + +type UpdateVMClaimStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + BindMode string `protobuf:"bytes,2,opt,name=bind_mode,json=bindMode,proto3" json:"bind_mode,omitempty"` + StaticBindAttempts *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=static_bind_attempts,json=staticBindAttempts,proto3" json:"static_bind_attempts,omitempty"` + Bound *wrapperspb.BoolValue `protobuf:"bytes,4,opt,name=bound,proto3" json:"bound,omitempty"` + Ready *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=ready,proto3" json:"ready,omitempty"` + Tainted *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=tainted,proto3" json:"tainted,omitempty"` +} + +func (x *UpdateVMClaimStatusRequest) Reset() { + *x = UpdateVMClaimStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMClaimStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMClaimStatusRequest) ProtoMessage() {} + +func (x *UpdateVMClaimStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMClaimStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMClaimStatusRequest) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateVMClaimStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMClaimStatusRequest) GetBindMode() string { + if x != nil { + return x.BindMode + } + return "" +} + +func (x *UpdateVMClaimStatusRequest) GetStaticBindAttempts() *wrapperspb.UInt32Value { + if x != nil { + return x.StaticBindAttempts + } + return nil +} + +func (x *UpdateVMClaimStatusRequest) GetBound() *wrapperspb.BoolValue { + if x != nil { + return x.Bound + } + return nil +} + +func (x *UpdateVMClaimStatusRequest) GetReady() *wrapperspb.BoolValue { + if x != nil { + return x.Ready + } + return nil +} + +func (x *UpdateVMClaimStatusRequest) GetTainted() *wrapperspb.BoolValue { + if x != nil { + return x.Tainted + } + return nil +} + +type VMClaimStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BindMode string `protobuf:"bytes,1,opt,name=bind_mode,json=bindMode,proto3" json:"bind_mode,omitempty"` + StaticBindAttempts uint32 `protobuf:"varint,2,opt,name=static_bind_attempts,json=staticBindAttempts,proto3" json:"static_bind_attempts,omitempty"` + Bound bool `protobuf:"varint,3,opt,name=bound,proto3" json:"bound,omitempty"` + Ready bool `protobuf:"varint,4,opt,name=ready,proto3" json:"ready,omitempty"` + Tainted bool `protobuf:"varint,5,opt,name=tainted,proto3" json:"tainted,omitempty"` +} + +func (x *VMClaimStatus) Reset() { + *x = VMClaimStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMClaimStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMClaimStatus) ProtoMessage() {} + +func (x *VMClaimStatus) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMClaimStatus.ProtoReflect.Descriptor instead. +func (*VMClaimStatus) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{4} +} + +func (x *VMClaimStatus) GetBindMode() string { + if x != nil { + return x.BindMode + } + return "" +} + +func (x *VMClaimStatus) GetStaticBindAttempts() uint32 { + if x != nil { + return x.StaticBindAttempts + } + return 0 +} + +func (x *VMClaimStatus) GetBound() bool { + if x != nil { + return x.Bound + } + return false +} + +func (x *VMClaimStatus) GetReady() bool { + if x != nil { + return x.Ready + } + return false +} + +func (x *VMClaimStatus) GetTainted() bool { + if x != nil { + return x.Tainted + } + return false +} + +type VMClaimVM struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Template string `protobuf:"bytes,1,opt,name=template,proto3" json:"template,omitempty"` + VmId string `protobuf:"bytes,2,opt,name=vm_id,json=vmId,proto3" json:"vm_id,omitempty"` +} + +func (x *VMClaimVM) Reset() { + *x = VMClaimVM{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMClaimVM) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMClaimVM) ProtoMessage() {} + +func (x *VMClaimVM) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMClaimVM.ProtoReflect.Descriptor instead. +func (*VMClaimVM) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{5} +} + +func (x *VMClaimVM) GetTemplate() string { + if x != nil { + return x.Template + } + return "" +} + +func (x *VMClaimVM) GetVmId() string { + if x != nil { + return x.VmId + } + return "" +} + +type ListVMClaimsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vmclaims []*VMClaim `protobuf:"bytes,1,rep,name=vmclaims,proto3" json:"vmclaims,omitempty"` +} + +func (x *ListVMClaimsResponse) Reset() { + *x = ListVMClaimsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVMClaimsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVMClaimsResponse) ProtoMessage() {} + +func (x *ListVMClaimsResponse) ProtoReflect() protoreflect.Message { + mi := &file_vmclaim_virtualmachineclaim_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVMClaimsResponse.ProtoReflect.Descriptor instead. +func (*ListVMClaimsResponse) Descriptor() ([]byte, []int) { + return file_vmclaim_virtualmachineclaim_proto_rawDescGZIP(), []int{6} +} + +func (x *ListVMClaimsResponse) GetVmclaims() []*VMClaim { + if x != nil { + return x.Vmclaims + } + return nil +} + +var File_vmclaim_virtualmachineclaim_proto protoreflect.FileDescriptor + +var file_vmclaim_virtualmachineclaim_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x1a, 0x15, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xcc, 0x04, 0x0a, 0x07, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, + 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x0a, 0x03, 0x76, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x56, 0x4d, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x56, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x76, + 0x6d, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x43, 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x62, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x2e, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2e, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x49, + 0x0a, 0x12, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x1a, 0x4a, 0x0a, 0x08, 0x56, 0x6d, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x2e, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x4d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xc1, 0x03, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, + 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x6d, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x05, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, + 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, + 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x63, + 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x61, 0x70, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, + 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, + 0x38, 0x0a, 0x0a, 0x56, 0x6d, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf9, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3e, 0x0a, + 0x05, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, + 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x6d, 0x73, 0x65, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x12, 0x43, 0x0a, + 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, + 0x6e, 0x64, 0x1a, 0x4c, 0x0a, 0x0a, 0x56, 0x6d, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x56, 0x4d, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x56, 0x4d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xb3, 0x02, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, + 0x69, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x14, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x42, 0x69, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x05, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, + 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x30, + 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x12, 0x34, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x74, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x56, 0x4d, 0x43, 0x6c, 0x61, + 0x69, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x69, 0x6e, + 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x42, 0x69, 0x6e, 0x64, 0x41, + 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x22, 0x3c, 0x0a, + 0x09, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x4d, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x76, 0x6d, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x6d, 0x49, 0x64, 0x22, 0x44, 0x0a, 0x14, 0x4c, + 0x69, 0x73, 0x74, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, + 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x08, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x73, 0x32, 0xaf, 0x04, 0x0a, 0x0a, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x53, 0x76, 0x63, + 0x12, 0x46, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, + 0x6d, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, + 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x76, 0x6d, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x46, 0x0a, + 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x1d, + 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x52, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x76, + 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x4d, 0x43, 0x6c, 0x61, + 0x69, 0x6d, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x42, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, + 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x54, 0x6f, 0x57, 0x6f, 0x72, + 0x6b, 0x71, 0x75, 0x65, 0x75, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, + 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, + 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x3b, 0x76, 0x6d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_vmclaim_virtualmachineclaim_proto_rawDescOnce sync.Once + file_vmclaim_virtualmachineclaim_proto_rawDescData = file_vmclaim_virtualmachineclaim_proto_rawDesc +) + +func file_vmclaim_virtualmachineclaim_proto_rawDescGZIP() []byte { + file_vmclaim_virtualmachineclaim_proto_rawDescOnce.Do(func() { + file_vmclaim_virtualmachineclaim_proto_rawDescData = protoimpl.X.CompressGZIP(file_vmclaim_virtualmachineclaim_proto_rawDescData) + }) + return file_vmclaim_virtualmachineclaim_proto_rawDescData +} + +var file_vmclaim_virtualmachineclaim_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_vmclaim_virtualmachineclaim_proto_goTypes = []interface{}{ + (*VMClaim)(nil), // 0: vmclaim.VMClaim + (*CreateVMClaimRequest)(nil), // 1: vmclaim.CreateVMClaimRequest + (*UpdateVMClaimRequest)(nil), // 2: vmclaim.UpdateVMClaimRequest + (*UpdateVMClaimStatusRequest)(nil), // 3: vmclaim.UpdateVMClaimStatusRequest + (*VMClaimStatus)(nil), // 4: vmclaim.VMClaimStatus + (*VMClaimVM)(nil), // 5: vmclaim.VMClaimVM + (*ListVMClaimsResponse)(nil), // 6: vmclaim.ListVMClaimsResponse + nil, // 7: vmclaim.VMClaim.VmsEntry + nil, // 8: vmclaim.VMClaim.LabelsEntry + nil, // 9: vmclaim.CreateVMClaimRequest.VmsetEntry + nil, // 10: vmclaim.CreateVMClaimRequest.LabelsEntry + nil, // 11: vmclaim.UpdateVMClaimRequest.VmsetEntry + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp + (*wrapperspb.BoolValue)(nil), // 13: google.protobuf.BoolValue + (*wrapperspb.UInt32Value)(nil), // 14: google.protobuf.UInt32Value + (*general.GetRequest)(nil), // 15: general.GetRequest + (*general.ResourceId)(nil), // 16: general.ResourceId + (*general.ListOptions)(nil), // 17: general.ListOptions + (*emptypb.Empty)(nil), // 18: google.protobuf.Empty +} +var file_vmclaim_virtualmachineclaim_proto_depIdxs = []int32{ + 7, // 0: vmclaim.VMClaim.vms:type_name -> vmclaim.VMClaim.VmsEntry + 8, // 1: vmclaim.VMClaim.labels:type_name -> vmclaim.VMClaim.LabelsEntry + 4, // 2: vmclaim.VMClaim.status:type_name -> vmclaim.VMClaimStatus + 12, // 3: vmclaim.VMClaim.deletion_timestamp:type_name -> google.protobuf.Timestamp + 9, // 4: vmclaim.CreateVMClaimRequest.vmset:type_name -> vmclaim.CreateVMClaimRequest.VmsetEntry + 10, // 5: vmclaim.CreateVMClaimRequest.labels:type_name -> vmclaim.CreateVMClaimRequest.LabelsEntry + 11, // 6: vmclaim.UpdateVMClaimRequest.vmset:type_name -> vmclaim.UpdateVMClaimRequest.VmsetEntry + 13, // 7: vmclaim.UpdateVMClaimRequest.restricted_bind:type_name -> google.protobuf.BoolValue + 14, // 8: vmclaim.UpdateVMClaimStatusRequest.static_bind_attempts:type_name -> google.protobuf.UInt32Value + 13, // 9: vmclaim.UpdateVMClaimStatusRequest.bound:type_name -> google.protobuf.BoolValue + 13, // 10: vmclaim.UpdateVMClaimStatusRequest.ready:type_name -> google.protobuf.BoolValue + 13, // 11: vmclaim.UpdateVMClaimStatusRequest.tainted:type_name -> google.protobuf.BoolValue + 0, // 12: vmclaim.ListVMClaimsResponse.vmclaims:type_name -> vmclaim.VMClaim + 5, // 13: vmclaim.VMClaim.VmsEntry.value:type_name -> vmclaim.VMClaimVM + 5, // 14: vmclaim.UpdateVMClaimRequest.VmsetEntry.value:type_name -> vmclaim.VMClaimVM + 1, // 15: vmclaim.VMClaimSvc.CreateVMClaim:input_type -> vmclaim.CreateVMClaimRequest + 15, // 16: vmclaim.VMClaimSvc.GetVMClaim:input_type -> general.GetRequest + 2, // 17: vmclaim.VMClaimSvc.UpdateVMClaim:input_type -> vmclaim.UpdateVMClaimRequest + 3, // 18: vmclaim.VMClaimSvc.UpdateVMClaimStatus:input_type -> vmclaim.UpdateVMClaimStatusRequest + 16, // 19: vmclaim.VMClaimSvc.DeleteVMClaim:input_type -> general.ResourceId + 17, // 20: vmclaim.VMClaimSvc.DeleteCollectionVMClaim:input_type -> general.ListOptions + 17, // 21: vmclaim.VMClaimSvc.ListVMClaim:input_type -> general.ListOptions + 16, // 22: vmclaim.VMClaimSvc.AddToWorkqueue:input_type -> general.ResourceId + 18, // 23: vmclaim.VMClaimSvc.CreateVMClaim:output_type -> google.protobuf.Empty + 0, // 24: vmclaim.VMClaimSvc.GetVMClaim:output_type -> vmclaim.VMClaim + 18, // 25: vmclaim.VMClaimSvc.UpdateVMClaim:output_type -> google.protobuf.Empty + 18, // 26: vmclaim.VMClaimSvc.UpdateVMClaimStatus:output_type -> google.protobuf.Empty + 18, // 27: vmclaim.VMClaimSvc.DeleteVMClaim:output_type -> google.protobuf.Empty + 18, // 28: vmclaim.VMClaimSvc.DeleteCollectionVMClaim:output_type -> google.protobuf.Empty + 6, // 29: vmclaim.VMClaimSvc.ListVMClaim:output_type -> vmclaim.ListVMClaimsResponse + 18, // 30: vmclaim.VMClaimSvc.AddToWorkqueue:output_type -> google.protobuf.Empty + 23, // [23:31] is the sub-list for method output_type + 15, // [15:23] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name +} + +func init() { file_vmclaim_virtualmachineclaim_proto_init() } +func file_vmclaim_virtualmachineclaim_proto_init() { + if File_vmclaim_virtualmachineclaim_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_vmclaim_virtualmachineclaim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMClaim); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateVMClaimRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMClaimRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMClaimStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMClaimStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMClaimVM); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmclaim_virtualmachineclaim_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVMClaimsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_vmclaim_virtualmachineclaim_proto_rawDesc, + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_vmclaim_virtualmachineclaim_proto_goTypes, + DependencyIndexes: file_vmclaim_virtualmachineclaim_proto_depIdxs, + MessageInfos: file_vmclaim_virtualmachineclaim_proto_msgTypes, + }.Build() + File_vmclaim_virtualmachineclaim_proto = out.File + file_vmclaim_virtualmachineclaim_proto_rawDesc = nil + file_vmclaim_virtualmachineclaim_proto_goTypes = nil + file_vmclaim_virtualmachineclaim_proto_depIdxs = nil +} diff --git a/v3/protos/vmclaim/virtualmachineclaim.proto b/v3/protos/vmclaim/virtualmachineclaim.proto new file mode 100644 index 00000000..24d02850 --- /dev/null +++ b/v3/protos/vmclaim/virtualmachineclaim.proto @@ -0,0 +1,77 @@ +syntax = "proto3"; + +package vmclaim; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/vmclaim;vmclaimpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/timestamp.proto"; + +service VMClaimSvc { + rpc CreateVMClaim (CreateVMClaimRequest) returns (google.protobuf.Empty); + rpc GetVMClaim (general.GetRequest) returns (VMClaim); + rpc UpdateVMClaim (UpdateVMClaimRequest) returns (google.protobuf.Empty); + rpc UpdateVMClaimStatus (UpdateVMClaimStatusRequest) returns (google.protobuf.Empty); + rpc DeleteVMClaim (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionVMClaim (general.ListOptions) returns (google.protobuf.Empty); + rpc ListVMClaim (general.ListOptions) returns (ListVMClaimsResponse); + rpc AddToWorkqueue (general.ResourceId) returns (google.protobuf.Empty); +} + +message VMClaim { + string id = 1; + string uid = 2; + string user_id = 3; + bool restricted_bind = 4; + string restricted_bind_value = 5; + map vms = 6; + bool dynamic_capable = 7; + string base_name = 8; + map labels = 9; + VMClaimStatus status = 10; + google.protobuf.Timestamp deletion_timestamp = 11; +} + +message CreateVMClaimRequest { + string id = 1; + string user_name = 2; + map vmset = 3; + bool restricted_bind = 4; + string restricted_bind_value = 5; + bool dynamic_capable = 6; + map labels = 7; +} + +message UpdateVMClaimRequest { + string id = 1; + map vmset = 2; + google.protobuf.BoolValue restricted_bind = 3; +} + +message UpdateVMClaimStatusRequest { + string id = 1; + string bind_mode = 2; + google.protobuf.UInt32Value static_bind_attempts = 3; + google.protobuf.BoolValue bound = 4; + google.protobuf.BoolValue ready = 5; + google.protobuf.BoolValue tainted = 6; +} + +message VMClaimStatus { + string bind_mode = 1; + uint32 static_bind_attempts = 2; + bool bound = 3; + bool ready = 4; + bool tainted = 5; +} + +message VMClaimVM { + string template = 1; + string vm_id = 2; +} + +message ListVMClaimsResponse { + repeated VMClaim vmclaims = 1; +} \ No newline at end of file diff --git a/v3/protos/vmclaim/virtualmachineclaim_grpc.pb.go b/v3/protos/vmclaim/virtualmachineclaim_grpc.pb.go new file mode 100644 index 00000000..8712655a --- /dev/null +++ b/v3/protos/vmclaim/virtualmachineclaim_grpc.pb.go @@ -0,0 +1,370 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: vmclaim/virtualmachineclaim.proto + +package vmclaimpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + VMClaimSvc_CreateVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/CreateVMClaim" + VMClaimSvc_GetVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/GetVMClaim" + VMClaimSvc_UpdateVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/UpdateVMClaim" + VMClaimSvc_UpdateVMClaimStatus_FullMethodName = "/vmclaim.VMClaimSvc/UpdateVMClaimStatus" + VMClaimSvc_DeleteVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/DeleteVMClaim" + VMClaimSvc_DeleteCollectionVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/DeleteCollectionVMClaim" + VMClaimSvc_ListVMClaim_FullMethodName = "/vmclaim.VMClaimSvc/ListVMClaim" + VMClaimSvc_AddToWorkqueue_FullMethodName = "/vmclaim.VMClaimSvc/AddToWorkqueue" +) + +// VMClaimSvcClient is the client API for VMClaimSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type VMClaimSvcClient interface { + CreateVMClaim(ctx context.Context, in *CreateVMClaimRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + GetVMClaim(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMClaim, error) + UpdateVMClaim(ctx context.Context, in *UpdateVMClaimRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateVMClaimStatus(ctx context.Context, in *UpdateVMClaimStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteVMClaim(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionVMClaim(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListVMClaim(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMClaimsResponse, error) + AddToWorkqueue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type vMClaimSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewVMClaimSvcClient(cc grpc.ClientConnInterface) VMClaimSvcClient { + return &vMClaimSvcClient{cc} +} + +func (c *vMClaimSvcClient) CreateVMClaim(ctx context.Context, in *CreateVMClaimRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_CreateVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) GetVMClaim(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMClaim, error) { + out := new(VMClaim) + err := c.cc.Invoke(ctx, VMClaimSvc_GetVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) UpdateVMClaim(ctx context.Context, in *UpdateVMClaimRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_UpdateVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) UpdateVMClaimStatus(ctx context.Context, in *UpdateVMClaimStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_UpdateVMClaimStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) DeleteVMClaim(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_DeleteVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) DeleteCollectionVMClaim(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_DeleteCollectionVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) ListVMClaim(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMClaimsResponse, error) { + out := new(ListVMClaimsResponse) + err := c.cc.Invoke(ctx, VMClaimSvc_ListVMClaim_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClaimSvcClient) AddToWorkqueue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMClaimSvc_AddToWorkqueue_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VMClaimSvcServer is the server API for VMClaimSvc service. +// All implementations must embed UnimplementedVMClaimSvcServer +// for forward compatibility +type VMClaimSvcServer interface { + CreateVMClaim(context.Context, *CreateVMClaimRequest) (*emptypb.Empty, error) + GetVMClaim(context.Context, *general.GetRequest) (*VMClaim, error) + UpdateVMClaim(context.Context, *UpdateVMClaimRequest) (*emptypb.Empty, error) + UpdateVMClaimStatus(context.Context, *UpdateVMClaimStatusRequest) (*emptypb.Empty, error) + DeleteVMClaim(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionVMClaim(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListVMClaim(context.Context, *general.ListOptions) (*ListVMClaimsResponse, error) + AddToWorkqueue(context.Context, *general.ResourceId) (*emptypb.Empty, error) + mustEmbedUnimplementedVMClaimSvcServer() +} + +// UnimplementedVMClaimSvcServer must be embedded to have forward compatible implementations. +type UnimplementedVMClaimSvcServer struct { +} + +func (UnimplementedVMClaimSvcServer) CreateVMClaim(context.Context, *CreateVMClaimRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) GetVMClaim(context.Context, *general.GetRequest) (*VMClaim, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) UpdateVMClaim(context.Context, *UpdateVMClaimRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) UpdateVMClaimStatus(context.Context, *UpdateVMClaimStatusRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMClaimStatus not implemented") +} +func (UnimplementedVMClaimSvcServer) DeleteVMClaim(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) DeleteCollectionVMClaim(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) ListVMClaim(context.Context, *general.ListOptions) (*ListVMClaimsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVMClaim not implemented") +} +func (UnimplementedVMClaimSvcServer) AddToWorkqueue(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddToWorkqueue not implemented") +} +func (UnimplementedVMClaimSvcServer) mustEmbedUnimplementedVMClaimSvcServer() {} + +// UnsafeVMClaimSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VMClaimSvcServer will +// result in compilation errors. +type UnsafeVMClaimSvcServer interface { + mustEmbedUnimplementedVMClaimSvcServer() +} + +func RegisterVMClaimSvcServer(s grpc.ServiceRegistrar, srv VMClaimSvcServer) { + s.RegisterService(&VMClaimSvc_ServiceDesc, srv) +} + +func _VMClaimSvc_CreateVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVMClaimRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).CreateVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_CreateVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).CreateVMClaim(ctx, req.(*CreateVMClaimRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_GetVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).GetVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_GetVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).GetVMClaim(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_UpdateVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMClaimRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).UpdateVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_UpdateVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).UpdateVMClaim(ctx, req.(*UpdateVMClaimRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_UpdateVMClaimStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMClaimStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).UpdateVMClaimStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_UpdateVMClaimStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).UpdateVMClaimStatus(ctx, req.(*UpdateVMClaimStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_DeleteVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).DeleteVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_DeleteVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).DeleteVMClaim(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_DeleteCollectionVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).DeleteCollectionVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_DeleteCollectionVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).DeleteCollectionVMClaim(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_ListVMClaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).ListVMClaim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_ListVMClaim_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).ListVMClaim(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMClaimSvc_AddToWorkqueue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMClaimSvcServer).AddToWorkqueue(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMClaimSvc_AddToWorkqueue_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMClaimSvcServer).AddToWorkqueue(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +// VMClaimSvc_ServiceDesc is the grpc.ServiceDesc for VMClaimSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VMClaimSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "vmclaim.VMClaimSvc", + HandlerType: (*VMClaimSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateVMClaim", + Handler: _VMClaimSvc_CreateVMClaim_Handler, + }, + { + MethodName: "GetVMClaim", + Handler: _VMClaimSvc_GetVMClaim_Handler, + }, + { + MethodName: "UpdateVMClaim", + Handler: _VMClaimSvc_UpdateVMClaim_Handler, + }, + { + MethodName: "UpdateVMClaimStatus", + Handler: _VMClaimSvc_UpdateVMClaimStatus_Handler, + }, + { + MethodName: "DeleteVMClaim", + Handler: _VMClaimSvc_DeleteVMClaim_Handler, + }, + { + MethodName: "DeleteCollectionVMClaim", + Handler: _VMClaimSvc_DeleteCollectionVMClaim_Handler, + }, + { + MethodName: "ListVMClaim", + Handler: _VMClaimSvc_ListVMClaim_Handler, + }, + { + MethodName: "AddToWorkqueue", + Handler: _VMClaimSvc_AddToWorkqueue_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vmclaim/virtualmachineclaim.proto", +} diff --git a/v3/protos/vmset/virtualmachineset.pb.go b/v3/protos/vmset/virtualmachineset.pb.go new file mode 100644 index 00000000..972b221c --- /dev/null +++ b/v3/protos/vmset/virtualmachineset.pb.go @@ -0,0 +1,907 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: vmset/virtualmachineset.proto + +package vmsetpb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VMSet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Count uint32 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"` + Environment string `protobuf:"bytes,4,opt,name=environment,proto3" json:"environment,omitempty"` + VmTemplate string `protobuf:"bytes,5,opt,name=vm_template,json=vmTemplate,proto3" json:"vm_template,omitempty"` + BaseName string `protobuf:"bytes,6,opt,name=base_name,json=baseName,proto3" json:"base_name,omitempty"` + RestrictedBind bool `protobuf:"varint,7,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,8,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + Status *VMSetStatus `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + Labels map[string]string `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *VMSet) Reset() { + *x = VMSet{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMSet) ProtoMessage() {} + +func (x *VMSet) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMSet.ProtoReflect.Descriptor instead. +func (*VMSet) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{0} +} + +func (x *VMSet) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *VMSet) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *VMSet) GetCount() uint32 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *VMSet) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *VMSet) GetVmTemplate() string { + if x != nil { + return x.VmTemplate + } + return "" +} + +func (x *VMSet) GetBaseName() string { + if x != nil { + return x.BaseName + } + return "" +} + +func (x *VMSet) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *VMSet) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *VMSet) GetStatus() *VMSetStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *VMSet) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type CreateVMSetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Count uint32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` + Environment string `protobuf:"bytes,3,opt,name=environment,proto3" json:"environment,omitempty"` + VmTemplate string `protobuf:"bytes,4,opt,name=vm_template,json=vmTemplate,proto3" json:"vm_template,omitempty"` + BaseName string `protobuf:"bytes,5,opt,name=base_name,json=baseName,proto3" json:"base_name,omitempty"` + RestrictedBind bool `protobuf:"varint,6,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` + RestrictedBindValue string `protobuf:"bytes,7,opt,name=restricted_bind_value,json=restrictedBindValue,proto3" json:"restricted_bind_value,omitempty"` + SeName string `protobuf:"bytes,8,opt,name=se_name,json=seName,proto3" json:"se_name,omitempty"` + SeUid string `protobuf:"bytes,9,opt,name=se_uid,json=seUid,proto3" json:"se_uid,omitempty"` + Labels map[string]string `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CreateVMSetRequest) Reset() { + *x = CreateVMSetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVMSetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVMSetRequest) ProtoMessage() {} + +func (x *CreateVMSetRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVMSetRequest.ProtoReflect.Descriptor instead. +func (*CreateVMSetRequest) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateVMSetRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *CreateVMSetRequest) GetCount() uint32 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *CreateVMSetRequest) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *CreateVMSetRequest) GetVmTemplate() string { + if x != nil { + return x.VmTemplate + } + return "" +} + +func (x *CreateVMSetRequest) GetBaseName() string { + if x != nil { + return x.BaseName + } + return "" +} + +func (x *CreateVMSetRequest) GetRestrictedBind() bool { + if x != nil { + return x.RestrictedBind + } + return false +} + +func (x *CreateVMSetRequest) GetRestrictedBindValue() string { + if x != nil { + return x.RestrictedBindValue + } + return "" +} + +func (x *CreateVMSetRequest) GetSeName() string { + if x != nil { + return x.SeName + } + return "" +} + +func (x *CreateVMSetRequest) GetSeUid() string { + if x != nil { + return x.SeUid + } + return "" +} + +func (x *CreateVMSetRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type VMSetStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Machines []*VMProvision `protobuf:"bytes,1,rep,name=machines,proto3" json:"machines,omitempty"` + Available uint32 `protobuf:"varint,2,opt,name=available,proto3" json:"available,omitempty"` + Provisioned uint32 `protobuf:"varint,3,opt,name=provisioned,proto3" json:"provisioned,omitempty"` +} + +func (x *VMSetStatus) Reset() { + *x = VMSetStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMSetStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMSetStatus) ProtoMessage() {} + +func (x *VMSetStatus) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMSetStatus.ProtoReflect.Descriptor instead. +func (*VMSetStatus) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{2} +} + +func (x *VMSetStatus) GetMachines() []*VMProvision { + if x != nil { + return x.Machines + } + return nil +} + +func (x *VMSetStatus) GetAvailable() uint32 { + if x != nil { + return x.Available + } + return 0 +} + +func (x *VMSetStatus) GetProvisioned() uint32 { + if x != nil { + return x.Provisioned + } + return 0 +} + +type UpdateVMSetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Count *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=count,proto3" json:"count,omitempty"` + Environment string `protobuf:"bytes,3,opt,name=environment,proto3" json:"environment,omitempty"` + VmTemplate string `protobuf:"bytes,4,opt,name=vm_template,json=vmTemplate,proto3" json:"vm_template,omitempty"` + RestrictedBind *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=restricted_bind,json=restrictedBind,proto3" json:"restricted_bind,omitempty"` +} + +func (x *UpdateVMSetRequest) Reset() { + *x = UpdateVMSetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMSetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMSetRequest) ProtoMessage() {} + +func (x *UpdateVMSetRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMSetRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMSetRequest) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateVMSetRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMSetRequest) GetCount() *wrapperspb.UInt32Value { + if x != nil { + return x.Count + } + return nil +} + +func (x *UpdateVMSetRequest) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *UpdateVMSetRequest) GetVmTemplate() string { + if x != nil { + return x.VmTemplate + } + return "" +} + +func (x *UpdateVMSetRequest) GetRestrictedBind() *wrapperspb.BoolValue { + if x != nil { + return x.RestrictedBind + } + return nil +} + +type VMProvision struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VmName string `protobuf:"bytes,1,opt,name=vm_name,json=vmName,proto3" json:"vm_name,omitempty"` + TfcState string `protobuf:"bytes,2,opt,name=tfc_state,json=tfcState,proto3" json:"tfc_state,omitempty"` + TfcCm string `protobuf:"bytes,3,opt,name=tfc_cm,json=tfcCm,proto3" json:"tfc_cm,omitempty"` +} + +func (x *VMProvision) Reset() { + *x = VMProvision{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMProvision) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMProvision) ProtoMessage() {} + +func (x *VMProvision) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMProvision.ProtoReflect.Descriptor instead. +func (*VMProvision) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{4} +} + +func (x *VMProvision) GetVmName() string { + if x != nil { + return x.VmName + } + return "" +} + +func (x *VMProvision) GetTfcState() string { + if x != nil { + return x.TfcState + } + return "" +} + +func (x *VMProvision) GetTfcCm() string { + if x != nil { + return x.TfcCm + } + return "" +} + +type UpdateVMSetStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Machines []*VMProvision `protobuf:"bytes,2,rep,name=machines,proto3" json:"machines,omitempty"` + Available *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=available,proto3" json:"available,omitempty"` + Provisioned *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=provisioned,proto3" json:"provisioned,omitempty"` +} + +func (x *UpdateVMSetStatusRequest) Reset() { + *x = UpdateVMSetStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMSetStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMSetStatusRequest) ProtoMessage() {} + +func (x *UpdateVMSetStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMSetStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMSetStatusRequest) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{5} +} + +func (x *UpdateVMSetStatusRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMSetStatusRequest) GetMachines() []*VMProvision { + if x != nil { + return x.Machines + } + return nil +} + +func (x *UpdateVMSetStatusRequest) GetAvailable() *wrapperspb.UInt32Value { + if x != nil { + return x.Available + } + return nil +} + +func (x *UpdateVMSetStatusRequest) GetProvisioned() *wrapperspb.UInt32Value { + if x != nil { + return x.Provisioned + } + return nil +} + +type ListVMSetsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vmsets []*VMSet `protobuf:"bytes,1,rep,name=vmsets,proto3" json:"vmsets,omitempty"` +} + +func (x *ListVMSetsResponse) Reset() { + *x = ListVMSetsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vmset_virtualmachineset_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVMSetsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVMSetsResponse) ProtoMessage() {} + +func (x *ListVMSetsResponse) ProtoReflect() protoreflect.Message { + mi := &file_vmset_virtualmachineset_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVMSetsResponse.ProtoReflect.Descriptor instead. +func (*ListVMSetsResponse) Descriptor() ([]byte, []int) { + return file_vmset_virtualmachineset_proto_rawDescGZIP(), []int{6} +} + +func (x *ListVMSetsResponse) GetVmsets() []*VMSet { + if x != nil { + return x.Vmsets + } + return nil +} + +var File_vmset_virtualmachineset_proto protoreflect.FileDescriptor + +var file_vmset_virtualmachineset_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x05, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2f, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, 0x03, 0x0a, 0x05, 0x56, + 0x4d, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x76, 0x6d, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, + 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, + 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x73, 0x65, + 0x74, 0x2e, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x56, 0x4d, + 0x53, 0x65, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0xa1, 0x03, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6d, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, + 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x73, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x5f, 0x75, 0x69, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x65, 0x55, 0x69, 0x64, 0x12, 0x3d, 0x0a, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, + 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7d, 0x0a, 0x0b, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, + 0x56, 0x4d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x22, 0xe0, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x4d, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x32, 0x0a, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6d, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x6d, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, + 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, 0x22, 0x5a, 0x0a, 0x0b, 0x56, 0x4d, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x76, 0x6d, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x6d, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x66, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x66, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, + 0x06, 0x74, 0x66, 0x63, 0x5f, 0x63, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x66, 0x63, 0x43, 0x6d, 0x22, 0xd6, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x2e, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x56, 0x4d, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x73, 0x12, 0x3a, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x3e, 0x0a, + 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x22, 0x3a, 0x0a, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x56, 0x4d, 0x53, 0x65, + 0x74, 0x52, 0x06, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x32, 0x8b, 0x04, 0x0a, 0x08, 0x56, 0x4d, + 0x53, 0x65, 0x74, 0x53, 0x76, 0x63, 0x12, 0x40, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x56, + 0x4d, 0x53, 0x65, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x76, 0x6d, 0x73, 0x65, + 0x74, 0x2e, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x11, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, + 0x2e, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x53, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x14, 0x2e, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3c, 0x0a, 0x09, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x19, 0x2e, + 0x76, 0x6d, 0x73, 0x65, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x53, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x54, + 0x6f, 0x57, 0x6f, 0x72, 0x6b, 0x71, 0x75, 0x65, 0x75, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, + 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x3b, 0x76, 0x6d, 0x73, 0x65, 0x74, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_vmset_virtualmachineset_proto_rawDescOnce sync.Once + file_vmset_virtualmachineset_proto_rawDescData = file_vmset_virtualmachineset_proto_rawDesc +) + +func file_vmset_virtualmachineset_proto_rawDescGZIP() []byte { + file_vmset_virtualmachineset_proto_rawDescOnce.Do(func() { + file_vmset_virtualmachineset_proto_rawDescData = protoimpl.X.CompressGZIP(file_vmset_virtualmachineset_proto_rawDescData) + }) + return file_vmset_virtualmachineset_proto_rawDescData +} + +var file_vmset_virtualmachineset_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_vmset_virtualmachineset_proto_goTypes = []interface{}{ + (*VMSet)(nil), // 0: vmset.VMSet + (*CreateVMSetRequest)(nil), // 1: vmset.CreateVMSetRequest + (*VMSetStatus)(nil), // 2: vmset.VMSetStatus + (*UpdateVMSetRequest)(nil), // 3: vmset.UpdateVMSetRequest + (*VMProvision)(nil), // 4: vmset.VMProvision + (*UpdateVMSetStatusRequest)(nil), // 5: vmset.UpdateVMSetStatusRequest + (*ListVMSetsResponse)(nil), // 6: vmset.ListVMSetsResponse + nil, // 7: vmset.VMSet.LabelsEntry + nil, // 8: vmset.CreateVMSetRequest.LabelsEntry + (*wrapperspb.UInt32Value)(nil), // 9: google.protobuf.UInt32Value + (*wrapperspb.BoolValue)(nil), // 10: google.protobuf.BoolValue + (*general.GetRequest)(nil), // 11: general.GetRequest + (*general.ResourceId)(nil), // 12: general.ResourceId + (*general.ListOptions)(nil), // 13: general.ListOptions + (*emptypb.Empty)(nil), // 14: google.protobuf.Empty +} +var file_vmset_virtualmachineset_proto_depIdxs = []int32{ + 2, // 0: vmset.VMSet.status:type_name -> vmset.VMSetStatus + 7, // 1: vmset.VMSet.labels:type_name -> vmset.VMSet.LabelsEntry + 8, // 2: vmset.CreateVMSetRequest.labels:type_name -> vmset.CreateVMSetRequest.LabelsEntry + 4, // 3: vmset.VMSetStatus.machines:type_name -> vmset.VMProvision + 9, // 4: vmset.UpdateVMSetRequest.count:type_name -> google.protobuf.UInt32Value + 10, // 5: vmset.UpdateVMSetRequest.restricted_bind:type_name -> google.protobuf.BoolValue + 4, // 6: vmset.UpdateVMSetStatusRequest.machines:type_name -> vmset.VMProvision + 9, // 7: vmset.UpdateVMSetStatusRequest.available:type_name -> google.protobuf.UInt32Value + 9, // 8: vmset.UpdateVMSetStatusRequest.provisioned:type_name -> google.protobuf.UInt32Value + 0, // 9: vmset.ListVMSetsResponse.vmsets:type_name -> vmset.VMSet + 1, // 10: vmset.VMSetSvc.CreateVMSet:input_type -> vmset.CreateVMSetRequest + 11, // 11: vmset.VMSetSvc.GetVMSet:input_type -> general.GetRequest + 3, // 12: vmset.VMSetSvc.UpdateVMSet:input_type -> vmset.UpdateVMSetRequest + 5, // 13: vmset.VMSetSvc.UpdateVMSetStatus:input_type -> vmset.UpdateVMSetStatusRequest + 12, // 14: vmset.VMSetSvc.DeleteVMSet:input_type -> general.ResourceId + 13, // 15: vmset.VMSetSvc.DeleteCollectionVMSet:input_type -> general.ListOptions + 13, // 16: vmset.VMSetSvc.ListVMSet:input_type -> general.ListOptions + 12, // 17: vmset.VMSetSvc.AddToWorkqueue:input_type -> general.ResourceId + 14, // 18: vmset.VMSetSvc.CreateVMSet:output_type -> google.protobuf.Empty + 0, // 19: vmset.VMSetSvc.GetVMSet:output_type -> vmset.VMSet + 14, // 20: vmset.VMSetSvc.UpdateVMSet:output_type -> google.protobuf.Empty + 14, // 21: vmset.VMSetSvc.UpdateVMSetStatus:output_type -> google.protobuf.Empty + 14, // 22: vmset.VMSetSvc.DeleteVMSet:output_type -> google.protobuf.Empty + 14, // 23: vmset.VMSetSvc.DeleteCollectionVMSet:output_type -> google.protobuf.Empty + 6, // 24: vmset.VMSetSvc.ListVMSet:output_type -> vmset.ListVMSetsResponse + 14, // 25: vmset.VMSetSvc.AddToWorkqueue:output_type -> google.protobuf.Empty + 18, // [18:26] is the sub-list for method output_type + 10, // [10:18] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_vmset_virtualmachineset_proto_init() } +func file_vmset_virtualmachineset_proto_init() { + if File_vmset_virtualmachineset_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_vmset_virtualmachineset_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMSet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateVMSetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMSetStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMSetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMProvision); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMSetStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmset_virtualmachineset_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVMSetsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_vmset_virtualmachineset_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_vmset_virtualmachineset_proto_goTypes, + DependencyIndexes: file_vmset_virtualmachineset_proto_depIdxs, + MessageInfos: file_vmset_virtualmachineset_proto_msgTypes, + }.Build() + File_vmset_virtualmachineset_proto = out.File + file_vmset_virtualmachineset_proto_rawDesc = nil + file_vmset_virtualmachineset_proto_goTypes = nil + file_vmset_virtualmachineset_proto_depIdxs = nil +} diff --git a/v3/protos/vmset/virtualmachineset.proto b/v3/protos/vmset/virtualmachineset.proto new file mode 100644 index 00000000..3bf1e47f --- /dev/null +++ b/v3/protos/vmset/virtualmachineset.proto @@ -0,0 +1,77 @@ +syntax = "proto3"; + +package vmset; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/vmset;vmsetpb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service VMSetSvc { + rpc CreateVMSet (CreateVMSetRequest) returns (google.protobuf.Empty); + rpc GetVMSet (general.GetRequest) returns (VMSet); + rpc UpdateVMSet (UpdateVMSetRequest) returns (google.protobuf.Empty); + rpc UpdateVMSetStatus (UpdateVMSetStatusRequest) returns (google.protobuf.Empty); + rpc DeleteVMSet (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionVMSet (general.ListOptions) returns (google.protobuf.Empty); + rpc ListVMSet (general.ListOptions) returns (ListVMSetsResponse); + rpc AddToWorkqueue (general.ResourceId) returns (google.protobuf.Empty); +} + +message VMSet { + string id = 1; + string uid = 2; + uint32 count = 3; + string environment = 4; + string vm_template = 5; + string base_name = 6; + bool restricted_bind = 7; + string restricted_bind_value = 8; + VMSetStatus status = 9; + map labels = 10; +} + +message CreateVMSetRequest { + string id = 1; + uint32 count = 2; + string environment = 3; + string vm_template = 4; + string base_name = 5; + bool restricted_bind = 6; + string restricted_bind_value = 7; + string se_name = 8; + string se_uid = 9; + map labels = 10; +} + +message VMSetStatus { + repeated VMProvision machines = 1; + uint32 available = 2; + uint32 provisioned = 3; +} + +message UpdateVMSetRequest { + string id = 1; + google.protobuf.UInt32Value count = 2; + string environment = 3; + string vm_template = 4; + google.protobuf.BoolValue restricted_bind = 5; +} + +message VMProvision { + string vm_name = 1; + string tfc_state = 2; + string tfc_cm = 3; +} + +message UpdateVMSetStatusRequest { + string id = 1; + repeated VMProvision machines = 2; + google.protobuf.UInt32Value available = 3; + google.protobuf.UInt32Value provisioned = 4; +} + +message ListVMSetsResponse { + repeated VMSet vmsets = 1; +} diff --git a/v3/protos/vmset/virtualmachineset_grpc.pb.go b/v3/protos/vmset/virtualmachineset_grpc.pb.go new file mode 100644 index 00000000..acd0fac1 --- /dev/null +++ b/v3/protos/vmset/virtualmachineset_grpc.pb.go @@ -0,0 +1,370 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: vmset/virtualmachineset.proto + +package vmsetpb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + VMSetSvc_CreateVMSet_FullMethodName = "/vmset.VMSetSvc/CreateVMSet" + VMSetSvc_GetVMSet_FullMethodName = "/vmset.VMSetSvc/GetVMSet" + VMSetSvc_UpdateVMSet_FullMethodName = "/vmset.VMSetSvc/UpdateVMSet" + VMSetSvc_UpdateVMSetStatus_FullMethodName = "/vmset.VMSetSvc/UpdateVMSetStatus" + VMSetSvc_DeleteVMSet_FullMethodName = "/vmset.VMSetSvc/DeleteVMSet" + VMSetSvc_DeleteCollectionVMSet_FullMethodName = "/vmset.VMSetSvc/DeleteCollectionVMSet" + VMSetSvc_ListVMSet_FullMethodName = "/vmset.VMSetSvc/ListVMSet" + VMSetSvc_AddToWorkqueue_FullMethodName = "/vmset.VMSetSvc/AddToWorkqueue" +) + +// VMSetSvcClient is the client API for VMSetSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type VMSetSvcClient interface { + CreateVMSet(ctx context.Context, in *CreateVMSetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + GetVMSet(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMSet, error) + UpdateVMSet(ctx context.Context, in *UpdateVMSetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + UpdateVMSetStatus(ctx context.Context, in *UpdateVMSetStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteVMSet(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionVMSet(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListVMSet(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMSetsResponse, error) + AddToWorkqueue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type vMSetSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewVMSetSvcClient(cc grpc.ClientConnInterface) VMSetSvcClient { + return &vMSetSvcClient{cc} +} + +func (c *vMSetSvcClient) CreateVMSet(ctx context.Context, in *CreateVMSetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_CreateVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) GetVMSet(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMSet, error) { + out := new(VMSet) + err := c.cc.Invoke(ctx, VMSetSvc_GetVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) UpdateVMSet(ctx context.Context, in *UpdateVMSetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_UpdateVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) UpdateVMSetStatus(ctx context.Context, in *UpdateVMSetStatusRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_UpdateVMSetStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) DeleteVMSet(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_DeleteVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) DeleteCollectionVMSet(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_DeleteCollectionVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) ListVMSet(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMSetsResponse, error) { + out := new(ListVMSetsResponse) + err := c.cc.Invoke(ctx, VMSetSvc_ListVMSet_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMSetSvcClient) AddToWorkqueue(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMSetSvc_AddToWorkqueue_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VMSetSvcServer is the server API for VMSetSvc service. +// All implementations must embed UnimplementedVMSetSvcServer +// for forward compatibility +type VMSetSvcServer interface { + CreateVMSet(context.Context, *CreateVMSetRequest) (*emptypb.Empty, error) + GetVMSet(context.Context, *general.GetRequest) (*VMSet, error) + UpdateVMSet(context.Context, *UpdateVMSetRequest) (*emptypb.Empty, error) + UpdateVMSetStatus(context.Context, *UpdateVMSetStatusRequest) (*emptypb.Empty, error) + DeleteVMSet(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionVMSet(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListVMSet(context.Context, *general.ListOptions) (*ListVMSetsResponse, error) + AddToWorkqueue(context.Context, *general.ResourceId) (*emptypb.Empty, error) + mustEmbedUnimplementedVMSetSvcServer() +} + +// UnimplementedVMSetSvcServer must be embedded to have forward compatible implementations. +type UnimplementedVMSetSvcServer struct { +} + +func (UnimplementedVMSetSvcServer) CreateVMSet(context.Context, *CreateVMSetRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) GetVMSet(context.Context, *general.GetRequest) (*VMSet, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) UpdateVMSet(context.Context, *UpdateVMSetRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) UpdateVMSetStatus(context.Context, *UpdateVMSetStatusRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMSetStatus not implemented") +} +func (UnimplementedVMSetSvcServer) DeleteVMSet(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) DeleteCollectionVMSet(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) ListVMSet(context.Context, *general.ListOptions) (*ListVMSetsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVMSet not implemented") +} +func (UnimplementedVMSetSvcServer) AddToWorkqueue(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddToWorkqueue not implemented") +} +func (UnimplementedVMSetSvcServer) mustEmbedUnimplementedVMSetSvcServer() {} + +// UnsafeVMSetSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VMSetSvcServer will +// result in compilation errors. +type UnsafeVMSetSvcServer interface { + mustEmbedUnimplementedVMSetSvcServer() +} + +func RegisterVMSetSvcServer(s grpc.ServiceRegistrar, srv VMSetSvcServer) { + s.RegisterService(&VMSetSvc_ServiceDesc, srv) +} + +func _VMSetSvc_CreateVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVMSetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).CreateVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_CreateVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).CreateVMSet(ctx, req.(*CreateVMSetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_GetVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).GetVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_GetVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).GetVMSet(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_UpdateVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMSetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).UpdateVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_UpdateVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).UpdateVMSet(ctx, req.(*UpdateVMSetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_UpdateVMSetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMSetStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).UpdateVMSetStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_UpdateVMSetStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).UpdateVMSetStatus(ctx, req.(*UpdateVMSetStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_DeleteVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).DeleteVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_DeleteVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).DeleteVMSet(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_DeleteCollectionVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).DeleteCollectionVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_DeleteCollectionVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).DeleteCollectionVMSet(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_ListVMSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).ListVMSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_ListVMSet_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).ListVMSet(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMSetSvc_AddToWorkqueue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMSetSvcServer).AddToWorkqueue(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMSetSvc_AddToWorkqueue_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMSetSvcServer).AddToWorkqueue(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +// VMSetSvc_ServiceDesc is the grpc.ServiceDesc for VMSetSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VMSetSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "vmset.VMSetSvc", + HandlerType: (*VMSetSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateVMSet", + Handler: _VMSetSvc_CreateVMSet_Handler, + }, + { + MethodName: "GetVMSet", + Handler: _VMSetSvc_GetVMSet_Handler, + }, + { + MethodName: "UpdateVMSet", + Handler: _VMSetSvc_UpdateVMSet_Handler, + }, + { + MethodName: "UpdateVMSetStatus", + Handler: _VMSetSvc_UpdateVMSetStatus_Handler, + }, + { + MethodName: "DeleteVMSet", + Handler: _VMSetSvc_DeleteVMSet_Handler, + }, + { + MethodName: "DeleteCollectionVMSet", + Handler: _VMSetSvc_DeleteCollectionVMSet_Handler, + }, + { + MethodName: "ListVMSet", + Handler: _VMSetSvc_ListVMSet_Handler, + }, + { + MethodName: "AddToWorkqueue", + Handler: _VMSetSvc_AddToWorkqueue_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vmset/virtualmachineset.proto", +} diff --git a/v3/protos/vmtemplate/vmtemplate.pb.go b/v3/protos/vmtemplate/vmtemplate.pb.go new file mode 100644 index 00000000..310f134e --- /dev/null +++ b/v3/protos/vmtemplate/vmtemplate.pb.go @@ -0,0 +1,482 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v3.21.12 +// source: vmtemplate/vmtemplate.proto + +package vmtemplatepb + +import ( + general "github.com/hobbyfarm/gargantua/v3/protos/general" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VMTemplate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Image string `protobuf:"bytes,4,opt,name=image,proto3" json:"image,omitempty"` + ConfigMap map[string]string `protobuf:"bytes,5,rep,name=config_map,json=configMap,proto3" json:"config_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *VMTemplate) Reset() { + *x = VMTemplate{} + if protoimpl.UnsafeEnabled { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VMTemplate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VMTemplate) ProtoMessage() {} + +func (x *VMTemplate) ProtoReflect() protoreflect.Message { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VMTemplate.ProtoReflect.Descriptor instead. +func (*VMTemplate) Descriptor() ([]byte, []int) { + return file_vmtemplate_vmtemplate_proto_rawDescGZIP(), []int{0} +} + +func (x *VMTemplate) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *VMTemplate) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *VMTemplate) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *VMTemplate) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *VMTemplate) GetConfigMap() map[string]string { + if x != nil { + return x.ConfigMap + } + return nil +} + +type CreateVMTemplateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Image string `protobuf:"bytes,2,opt,name=image,proto3" json:"image,omitempty"` + ConfigMapRaw string `protobuf:"bytes,3,opt,name=config_map_raw,json=configMapRaw,proto3" json:"config_map_raw,omitempty"` +} + +func (x *CreateVMTemplateRequest) Reset() { + *x = CreateVMTemplateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateVMTemplateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateVMTemplateRequest) ProtoMessage() {} + +func (x *CreateVMTemplateRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateVMTemplateRequest.ProtoReflect.Descriptor instead. +func (*CreateVMTemplateRequest) Descriptor() ([]byte, []int) { + return file_vmtemplate_vmtemplate_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateVMTemplateRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateVMTemplateRequest) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *CreateVMTemplateRequest) GetConfigMapRaw() string { + if x != nil { + return x.ConfigMapRaw + } + return "" +} + +type UpdateVMTemplateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image,omitempty"` + ConfigMapRaw string `protobuf:"bytes,4,opt,name=config_map_raw,json=configMapRaw,proto3" json:"config_map_raw,omitempty"` +} + +func (x *UpdateVMTemplateRequest) Reset() { + *x = UpdateVMTemplateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateVMTemplateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateVMTemplateRequest) ProtoMessage() {} + +func (x *UpdateVMTemplateRequest) ProtoReflect() protoreflect.Message { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateVMTemplateRequest.ProtoReflect.Descriptor instead. +func (*UpdateVMTemplateRequest) Descriptor() ([]byte, []int) { + return file_vmtemplate_vmtemplate_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateVMTemplateRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateVMTemplateRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateVMTemplateRequest) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +func (x *UpdateVMTemplateRequest) GetConfigMapRaw() string { + if x != nil { + return x.ConfigMapRaw + } + return "" +} + +type ListVMTemplatesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vmtemplates []*VMTemplate `protobuf:"bytes,1,rep,name=vmtemplates,proto3" json:"vmtemplates,omitempty"` +} + +func (x *ListVMTemplatesResponse) Reset() { + *x = ListVMTemplatesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListVMTemplatesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListVMTemplatesResponse) ProtoMessage() {} + +func (x *ListVMTemplatesResponse) ProtoReflect() protoreflect.Message { + mi := &file_vmtemplate_vmtemplate_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListVMTemplatesResponse.ProtoReflect.Descriptor instead. +func (*ListVMTemplatesResponse) Descriptor() ([]byte, []int) { + return file_vmtemplate_vmtemplate_proto_rawDescGZIP(), []int{3} +} + +func (x *ListVMTemplatesResponse) GetVmtemplates() []*VMTemplate { + if x != nil { + return x.Vmtemplates + } + return nil +} + +var File_vmtemplate_vmtemplate_proto protoreflect.FileDescriptor + +var file_vmtemplate_vmtemplate_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x6d, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x76, + 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x15, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, 0x01, + 0x0a, 0x0a, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, + 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x1a, 0x3c, + 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x69, 0x0a, 0x17, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x5f, + 0x72, 0x61, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x4d, 0x61, 0x70, 0x52, 0x61, 0x77, 0x22, 0x79, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x52, + 0x61, 0x77, 0x22, 0x53, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, + 0x0b, 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, + 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x76, 0x6d, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x32, 0xc6, 0x03, 0x0a, 0x0d, 0x56, 0x4d, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x76, 0x63, 0x12, 0x4c, 0x0a, 0x10, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, + 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x56, 0x4d, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x56, 0x4d, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x76, 0x6d, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x4d, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x56, 0x4d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x4d, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x4b, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x23, 0x2e, 0x76, 0x6d, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x4d, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, + 0x6f, 0x62, 0x62, 0x79, 0x66, 0x61, 0x72, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x67, 0x61, 0x6e, 0x74, + 0x75, 0x61, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x6d, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3b, 0x76, 0x6d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_vmtemplate_vmtemplate_proto_rawDescOnce sync.Once + file_vmtemplate_vmtemplate_proto_rawDescData = file_vmtemplate_vmtemplate_proto_rawDesc +) + +func file_vmtemplate_vmtemplate_proto_rawDescGZIP() []byte { + file_vmtemplate_vmtemplate_proto_rawDescOnce.Do(func() { + file_vmtemplate_vmtemplate_proto_rawDescData = protoimpl.X.CompressGZIP(file_vmtemplate_vmtemplate_proto_rawDescData) + }) + return file_vmtemplate_vmtemplate_proto_rawDescData +} + +var file_vmtemplate_vmtemplate_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_vmtemplate_vmtemplate_proto_goTypes = []interface{}{ + (*VMTemplate)(nil), // 0: vmtemplate.VMTemplate + (*CreateVMTemplateRequest)(nil), // 1: vmtemplate.CreateVMTemplateRequest + (*UpdateVMTemplateRequest)(nil), // 2: vmtemplate.UpdateVMTemplateRequest + (*ListVMTemplatesResponse)(nil), // 3: vmtemplate.ListVMTemplatesResponse + nil, // 4: vmtemplate.VMTemplate.ConfigMapEntry + (*general.GetRequest)(nil), // 5: general.GetRequest + (*general.ResourceId)(nil), // 6: general.ResourceId + (*general.ListOptions)(nil), // 7: general.ListOptions + (*emptypb.Empty)(nil), // 8: google.protobuf.Empty +} +var file_vmtemplate_vmtemplate_proto_depIdxs = []int32{ + 4, // 0: vmtemplate.VMTemplate.config_map:type_name -> vmtemplate.VMTemplate.ConfigMapEntry + 0, // 1: vmtemplate.ListVMTemplatesResponse.vmtemplates:type_name -> vmtemplate.VMTemplate + 1, // 2: vmtemplate.VMTemplateSvc.CreateVMTemplate:input_type -> vmtemplate.CreateVMTemplateRequest + 5, // 3: vmtemplate.VMTemplateSvc.GetVMTemplate:input_type -> general.GetRequest + 2, // 4: vmtemplate.VMTemplateSvc.UpdateVMTemplate:input_type -> vmtemplate.UpdateVMTemplateRequest + 6, // 5: vmtemplate.VMTemplateSvc.DeleteVMTemplate:input_type -> general.ResourceId + 7, // 6: vmtemplate.VMTemplateSvc.DeleteCollectionVMTemplate:input_type -> general.ListOptions + 7, // 7: vmtemplate.VMTemplateSvc.ListVMTemplate:input_type -> general.ListOptions + 6, // 8: vmtemplate.VMTemplateSvc.CreateVMTemplate:output_type -> general.ResourceId + 0, // 9: vmtemplate.VMTemplateSvc.GetVMTemplate:output_type -> vmtemplate.VMTemplate + 8, // 10: vmtemplate.VMTemplateSvc.UpdateVMTemplate:output_type -> google.protobuf.Empty + 8, // 11: vmtemplate.VMTemplateSvc.DeleteVMTemplate:output_type -> google.protobuf.Empty + 8, // 12: vmtemplate.VMTemplateSvc.DeleteCollectionVMTemplate:output_type -> google.protobuf.Empty + 3, // 13: vmtemplate.VMTemplateSvc.ListVMTemplate:output_type -> vmtemplate.ListVMTemplatesResponse + 8, // [8:14] is the sub-list for method output_type + 2, // [2:8] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_vmtemplate_vmtemplate_proto_init() } +func file_vmtemplate_vmtemplate_proto_init() { + if File_vmtemplate_vmtemplate_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_vmtemplate_vmtemplate_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VMTemplate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmtemplate_vmtemplate_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateVMTemplateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmtemplate_vmtemplate_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateVMTemplateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vmtemplate_vmtemplate_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListVMTemplatesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_vmtemplate_vmtemplate_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_vmtemplate_vmtemplate_proto_goTypes, + DependencyIndexes: file_vmtemplate_vmtemplate_proto_depIdxs, + MessageInfos: file_vmtemplate_vmtemplate_proto_msgTypes, + }.Build() + File_vmtemplate_vmtemplate_proto = out.File + file_vmtemplate_vmtemplate_proto_rawDesc = nil + file_vmtemplate_vmtemplate_proto_goTypes = nil + file_vmtemplate_vmtemplate_proto_depIdxs = nil +} diff --git a/v3/protos/vmtemplate/vmtemplate.proto b/v3/protos/vmtemplate/vmtemplate.proto new file mode 100644 index 00000000..e0c5f3f5 --- /dev/null +++ b/v3/protos/vmtemplate/vmtemplate.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package vmtemplate; + +option go_package = "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate;vmtemplatepb"; + +import "general/general.proto"; +import "google/protobuf/empty.proto"; + +service VMTemplateSvc { + rpc CreateVMTemplate (CreateVMTemplateRequest) returns (general.ResourceId); + rpc GetVMTemplate (general.GetRequest) returns (VMTemplate); + rpc UpdateVMTemplate (UpdateVMTemplateRequest) returns (google.protobuf.Empty); + rpc DeleteVMTemplate (general.ResourceId) returns (google.protobuf.Empty); + rpc DeleteCollectionVMTemplate (general.ListOptions) returns (google.protobuf.Empty); + rpc ListVMTemplate (general.ListOptions) returns (ListVMTemplatesResponse); +} + +message VMTemplate { + string id = 1; + string uid = 2; + string name = 3; + string image = 4; + map config_map = 5; +} + +message CreateVMTemplateRequest { + string name = 1; + string image = 2; + string config_map_raw = 3; +} + +message UpdateVMTemplateRequest { + string id = 1; + string name = 2; + string image = 3; + string config_map_raw = 4; +} + +message ListVMTemplatesResponse { + repeated VMTemplate vmtemplates = 1; +} diff --git a/v3/protos/vmtemplate/vmtemplate_grpc.pb.go b/v3/protos/vmtemplate/vmtemplate_grpc.pb.go new file mode 100644 index 00000000..63c98660 --- /dev/null +++ b/v3/protos/vmtemplate/vmtemplate_grpc.pb.go @@ -0,0 +1,296 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.21.12 +// source: vmtemplate/vmtemplate.proto + +package vmtemplatepb + +import ( + context "context" + general "github.com/hobbyfarm/gargantua/v3/protos/general" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + VMTemplateSvc_CreateVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/CreateVMTemplate" + VMTemplateSvc_GetVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/GetVMTemplate" + VMTemplateSvc_UpdateVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/UpdateVMTemplate" + VMTemplateSvc_DeleteVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/DeleteVMTemplate" + VMTemplateSvc_DeleteCollectionVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/DeleteCollectionVMTemplate" + VMTemplateSvc_ListVMTemplate_FullMethodName = "/vmtemplate.VMTemplateSvc/ListVMTemplate" +) + +// VMTemplateSvcClient is the client API for VMTemplateSvc service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type VMTemplateSvcClient interface { + CreateVMTemplate(ctx context.Context, in *CreateVMTemplateRequest, opts ...grpc.CallOption) (*general.ResourceId, error) + GetVMTemplate(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMTemplate, error) + UpdateVMTemplate(ctx context.Context, in *UpdateVMTemplateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteVMTemplate(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteCollectionVMTemplate(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) + ListVMTemplate(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMTemplatesResponse, error) +} + +type vMTemplateSvcClient struct { + cc grpc.ClientConnInterface +} + +func NewVMTemplateSvcClient(cc grpc.ClientConnInterface) VMTemplateSvcClient { + return &vMTemplateSvcClient{cc} +} + +func (c *vMTemplateSvcClient) CreateVMTemplate(ctx context.Context, in *CreateVMTemplateRequest, opts ...grpc.CallOption) (*general.ResourceId, error) { + out := new(general.ResourceId) + err := c.cc.Invoke(ctx, VMTemplateSvc_CreateVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMTemplateSvcClient) GetVMTemplate(ctx context.Context, in *general.GetRequest, opts ...grpc.CallOption) (*VMTemplate, error) { + out := new(VMTemplate) + err := c.cc.Invoke(ctx, VMTemplateSvc_GetVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMTemplateSvcClient) UpdateVMTemplate(ctx context.Context, in *UpdateVMTemplateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMTemplateSvc_UpdateVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMTemplateSvcClient) DeleteVMTemplate(ctx context.Context, in *general.ResourceId, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMTemplateSvc_DeleteVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMTemplateSvcClient) DeleteCollectionVMTemplate(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, VMTemplateSvc_DeleteCollectionVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMTemplateSvcClient) ListVMTemplate(ctx context.Context, in *general.ListOptions, opts ...grpc.CallOption) (*ListVMTemplatesResponse, error) { + out := new(ListVMTemplatesResponse) + err := c.cc.Invoke(ctx, VMTemplateSvc_ListVMTemplate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VMTemplateSvcServer is the server API for VMTemplateSvc service. +// All implementations must embed UnimplementedVMTemplateSvcServer +// for forward compatibility +type VMTemplateSvcServer interface { + CreateVMTemplate(context.Context, *CreateVMTemplateRequest) (*general.ResourceId, error) + GetVMTemplate(context.Context, *general.GetRequest) (*VMTemplate, error) + UpdateVMTemplate(context.Context, *UpdateVMTemplateRequest) (*emptypb.Empty, error) + DeleteVMTemplate(context.Context, *general.ResourceId) (*emptypb.Empty, error) + DeleteCollectionVMTemplate(context.Context, *general.ListOptions) (*emptypb.Empty, error) + ListVMTemplate(context.Context, *general.ListOptions) (*ListVMTemplatesResponse, error) + mustEmbedUnimplementedVMTemplateSvcServer() +} + +// UnimplementedVMTemplateSvcServer must be embedded to have forward compatible implementations. +type UnimplementedVMTemplateSvcServer struct { +} + +func (UnimplementedVMTemplateSvcServer) CreateVMTemplate(context.Context, *CreateVMTemplateRequest) (*general.ResourceId, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) GetVMTemplate(context.Context, *general.GetRequest) (*VMTemplate, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) UpdateVMTemplate(context.Context, *UpdateVMTemplateRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) DeleteVMTemplate(context.Context, *general.ResourceId) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) DeleteCollectionVMTemplate(context.Context, *general.ListOptions) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteCollectionVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) ListVMTemplate(context.Context, *general.ListOptions) (*ListVMTemplatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListVMTemplate not implemented") +} +func (UnimplementedVMTemplateSvcServer) mustEmbedUnimplementedVMTemplateSvcServer() {} + +// UnsafeVMTemplateSvcServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VMTemplateSvcServer will +// result in compilation errors. +type UnsafeVMTemplateSvcServer interface { + mustEmbedUnimplementedVMTemplateSvcServer() +} + +func RegisterVMTemplateSvcServer(s grpc.ServiceRegistrar, srv VMTemplateSvcServer) { + s.RegisterService(&VMTemplateSvc_ServiceDesc, srv) +} + +func _VMTemplateSvc_CreateVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVMTemplateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).CreateVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_CreateVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).CreateVMTemplate(ctx, req.(*CreateVMTemplateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMTemplateSvc_GetVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).GetVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_GetVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).GetVMTemplate(ctx, req.(*general.GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMTemplateSvc_UpdateVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateVMTemplateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).UpdateVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_UpdateVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).UpdateVMTemplate(ctx, req.(*UpdateVMTemplateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMTemplateSvc_DeleteVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ResourceId) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).DeleteVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_DeleteVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).DeleteVMTemplate(ctx, req.(*general.ResourceId)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMTemplateSvc_DeleteCollectionVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).DeleteCollectionVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_DeleteCollectionVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).DeleteCollectionVMTemplate(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +func _VMTemplateSvc_ListVMTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(general.ListOptions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMTemplateSvcServer).ListVMTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VMTemplateSvc_ListVMTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMTemplateSvcServer).ListVMTemplate(ctx, req.(*general.ListOptions)) + } + return interceptor(ctx, in, info, handler) +} + +// VMTemplateSvc_ServiceDesc is the grpc.ServiceDesc for VMTemplateSvc service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VMTemplateSvc_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "vmtemplate.VMTemplateSvc", + HandlerType: (*VMTemplateSvcServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateVMTemplate", + Handler: _VMTemplateSvc_CreateVMTemplate_Handler, + }, + { + MethodName: "GetVMTemplate", + Handler: _VMTemplateSvc_GetVMTemplate_Handler, + }, + { + MethodName: "UpdateVMTemplate", + Handler: _VMTemplateSvc_UpdateVMTemplate_Handler, + }, + { + MethodName: "DeleteVMTemplate", + Handler: _VMTemplateSvc_DeleteVMTemplate_Handler, + }, + { + MethodName: "DeleteCollectionVMTemplate", + Handler: _VMTemplateSvc_DeleteCollectionVMTemplate_Handler, + }, + { + MethodName: "ListVMTemplate", + Handler: _VMTemplateSvc_ListVMTemplate_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vmtemplate/vmtemplate.proto", +} diff --git a/v3/services/accesscodesvc/internal/crd.go b/v3/services/accesscodesvc/internal/crd.go index 3b1d2d89..d08c938e 100644 --- a/v3/services/accesscodesvc/internal/crd.go +++ b/v3/services/accesscodesvc/internal/crd.go @@ -3,11 +3,16 @@ package accesscodeservice import ( "github.com/ebauman/crder" v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" ) -func GenerateAccessCodeCRD() []crder.CRD { +// AccessCodeCRDInstaller is a struct that can generate CRDs for access codes. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type AccessCodeCRDInstaller struct{} + +func (aci AccessCodeCRDInstaller) GenerateCRDs() []crder.CRD { return []crder.CRD{ - hobbyfarmCRD(&v1.AccessCode{}, func(c *crder.CRD) { + crd.HobbyfarmCRD(&v1.AccessCode{}, func(c *crder.CRD) { c. IsNamespaced(true). AddVersion("v1", &v1.AccessCode{}, func(cv *crder.Version) { @@ -16,7 +21,7 @@ func GenerateAccessCodeCRD() []crder.CRD { WithColumn("Expiration", ".spec.expiration") }) }), - hobbyfarmCRD(&v1.OneTimeAccessCode{}, func(c *crder.CRD) { + crd.HobbyfarmCRD(&v1.OneTimeAccessCode{}, func(c *crder.CRD) { c. IsNamespaced(true). AddVersion("v1", &v1.OneTimeAccessCode{}, func(cv *crder.Version) { @@ -28,7 +33,3 @@ func GenerateAccessCodeCRD() []crder.CRD { }), } } - -func hobbyfarmCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { - return *crder.NewCRD(obj, "hobbyfarm.io", customize) -} diff --git a/v3/services/accesscodesvc/internal/grpc.go b/v3/services/accesscodesvc/internal/grpc.go index d97dc8ae..697ea1d3 100644 --- a/v3/services/accesscodesvc/internal/grpc.go +++ b/v3/services/accesscodesvc/internal/grpc.go @@ -2,156 +2,582 @@ package accesscodeservice import ( "context" - "fmt" + "time" "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/util" - accessCodeProto "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - empty "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/emptypb" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/retry" ) type GrpcAccessCodeServer struct { - accessCodeProto.UnimplementedAccessCodeSvcServer - hfClientSet hfClientset.Interface - ctx context.Context + accesscodepb.UnimplementedAccessCodeSvcServer + acClient hfClientsetv1.AccessCodeInterface + acLister listersv1.AccessCodeLister + acSynced cache.InformerSynced + otacClient hfClientsetv1.OneTimeAccessCodeInterface + otacLister listersv1.OneTimeAccessCodeLister + otacSynced cache.InformerSynced + eventClient scheduledeventpb.ScheduledEventSvcClient } -func NewGrpcAccessCodeServer(hfClientSet hfClientset.Interface, ctx context.Context) *GrpcAccessCodeServer { +func NewGrpcAccessCodeServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, eventClient scheduledeventpb.ScheduledEventSvcClient) *GrpcAccessCodeServer { return &GrpcAccessCodeServer{ - hfClientSet: hfClientSet, - ctx: ctx, + acClient: hfClientSet.HobbyfarmV1().AccessCodes(util.GetReleaseNamespace()), + acLister: hfInformerFactory.Hobbyfarm().V1().AccessCodes().Lister(), + acSynced: hfInformerFactory.Hobbyfarm().V1().AccessCodes().Informer().HasSynced, + otacClient: hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util.GetReleaseNamespace()), + otacLister: hfInformerFactory.Hobbyfarm().V1().OneTimeAccessCodes().Lister(), + otacSynced: hfInformerFactory.Hobbyfarm().V1().OneTimeAccessCodes().Informer().HasSynced, + eventClient: eventClient, } } -func (a *GrpcAccessCodeServer) getOtac(id string) (*accessCodeProto.OneTimeAccessCode, error) { - if len(id) == 0 { - return &accessCodeProto.OneTimeAccessCode{}, fmt.Errorf("OTAC id passed in was empty") +/************************************************************************************************************** + * Resource oriented RPCs for AccessCodes + * + * The following functions implement the resource oriented RPCs for AccessCodes + **************************************************************************************************************/ + +func (a *GrpcAccessCodeServer) CreateAc(ctx context.Context, cr *accesscodepb.CreateAcRequest) (*emptypb.Empty, error) { + + if err := a.checkInputParamsForCreateAc(cr); err != nil { + return &emptypb.Empty{}, err + } + acName := cr.GetAcName() + seName := cr.GetSeName() + seUid := types.UID(cr.GetSeUid()) + description := cr.GetDescription() + scenarios := cr.GetScenarios() + courses := cr.GetCourses() + expiration := cr.GetExpiration() + restrictedBind := cr.GetRestrictedBind() + restrictedBindValue := cr.GetRestrictedBindValue() + printable := cr.GetPrintable() + + ac := &hfv1.AccessCode{ + ObjectMeta: metav1.ObjectMeta{ + Name: acName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: "ScheduledEvent", + Name: seName, + UID: seUid, + }, + }, + Labels: map[string]string{ + hflabels.ScheduledEventLabel: seName, + hflabels.AccessCodeLabel: acName, + }, + }, + Spec: hfv1.AccessCodeSpec{ + Code: acName, + Description: description, + Scenarios: scenarios, + Courses: courses, + Expiration: expiration, + RestrictedBind: restrictedBind, + Printable: printable, + }, + } + + if restrictedBind { + ac.Spec.RestrictedBindValue = restrictedBindValue } - obj, err := a.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util.GetReleaseNamespace()).Get(a.ctx, id, metav1.GetOptions{}) + + _, err := a.acClient.Create(ctx, ac, metav1.CreateOptions{}) if err != nil { - return &accessCodeProto.OneTimeAccessCode{}, fmt.Errorf("error while retrieving OTAC by id: %s with error: %v", id, err) + return &emptypb.Empty{}, err } - return &accessCodeProto.OneTimeAccessCode{ - Id: obj.Name, - User: obj.Spec.User, - RedeemedTimestamp: obj.Spec.RedeemedTimestamp, - MaxDuration: obj.Spec.MaxDuration, + return &emptypb.Empty{}, nil +} + +func (a *GrpcAccessCodeServer) GetAc(ctx context.Context, req *generalpb.GetRequest) (*accesscodepb.AccessCode, error) { + ac, err := util.GenericHfGetter(ctx, req, a.acClient, a.acLister.AccessCodes(util.GetReleaseNamespace()), "access code", a.acSynced()) + if err != nil { + return &accesscodepb.AccessCode{}, err + } + + return &accesscodepb.AccessCode{ + Id: ac.Name, + Uid: string(ac.UID), + Description: ac.Spec.Description, + Scenarios: ac.Spec.Scenarios, + Courses: ac.Spec.Courses, + Expiration: ac.Spec.Expiration, + RestrictedBind: ac.Spec.RestrictedBind, + RestrictedBindValue: ac.Spec.RestrictedBindValue, + Printable: ac.Spec.Printable, + Labels: ac.Labels, }, nil } -func (a *GrpcAccessCodeServer) GetOtac(ctx context.Context, gor *accessCodeProto.ResourceId) (*accessCodeProto.OneTimeAccessCode, error) { - if len(gor.GetId()) == 0 { - newErr := status.Newf( +func (a *GrpcAccessCodeServer) UpdateAc(ctx context.Context, acRequest *accesscodepb.UpdateAccessCodeRequest) (*emptypb.Empty, error) { + id := acRequest.GetId() + if id == "" { + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, - "no id passed in", + "no ID passed in", + acRequest, ) - newErr, wde := newErr.WithDetails(gor) - if wde != nil { - return &accessCodeProto.OneTimeAccessCode{}, wde + } + + description := acRequest.GetDescription() + scenarios := acRequest.GetScenarios() + courses := acRequest.GetCourses() + expiration := acRequest.GetExpiration() + restrictedBind := acRequest.GetRestrictedBind() + printable := acRequest.GetPrintable() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + ac, err := a.acClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving access code %s", + acRequest, + acRequest.GetId(), + ) + } + + // In the current implementation the code from the access code spec equals the object's kubernetes name/id. + // This ensures that access codes are unique. + // Hence the .Spec.Code is immutable and should not be updated. + // To update an access codes code name it has to be deleted and then recreated. + // ac.Spec.Code = acRequest.GetId() + + // Only update values if they're input value is not empty/blank + if description != "" { + ac.Spec.Description = description + } + // To update scenarios and/or courses, at least one of these arrays needs to contain values + if len(scenarios) > 0 || len(courses) > 0 { + ac.Spec.Scenarios = scenarios + ac.Spec.Courses = courses + } + if expiration != "" { + ac.Spec.Expiration = expiration + } + if restrictedBind != nil { + ac.Spec.RestrictedBind = restrictedBind.Value } - return &accessCodeProto.OneTimeAccessCode{}, newErr.Err() + // if restricted bind is disabled, make sure that restricted bind value is also empty... + // else update restricted bind value if specified + if !ac.Spec.RestrictedBind { + ac.Spec.RestrictedBindValue = "" + } else if ac.Spec.RestrictedBindValue == "" { + ac.Spec.RestrictedBindValue = ac.ObjectMeta.Labels[hflabels.ScheduledEventLabel] + } + if printable != nil { + ac.Spec.Printable = printable.Value + } + + _, updateErr := a.acClient.Update(ctx, ac, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + acRequest, + ) } - otac, err := a.getOtac(gor.GetId()) + return &emptypb.Empty{}, nil +} + +func (a *GrpcAccessCodeServer) DeleteAc(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, a.acClient, "access code") +} + +func (a *GrpcAccessCodeServer) DeleteCollectionAc(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, a.acClient, "access codes") +} +func (a *GrpcAccessCodeServer) ListAc(ctx context.Context, listOptions *generalpb.ListOptions) (*accesscodepb.ListAcsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var accessCodes []hfv1.AccessCode + var err error + if !doLoadFromCache { + var acList *hfv1.AccessCodeList + acList, err = util.ListByHfClient(ctx, listOptions, a.acClient, "access codes") + if err == nil { + accessCodes = acList.Items + } + } else { + accessCodes, err = util.ListByCache(listOptions, a.acLister, "access codes", a.acSynced()) + } if err != nil { - glog.V(2).Infof("%v is not an OTAC, returning status NotFound", err) - newErr := status.Newf( - codes.NotFound, - "no OTAC %s found", - gor.GetId(), - ) - newErr, wde := newErr.WithDetails(gor) - if wde != nil { - return &accessCodeProto.OneTimeAccessCode{}, wde + glog.Error(err) + return &accesscodepb.ListAcsResponse{}, err + } + + preparedAcs := []*accesscodepb.AccessCode{} + + for _, accessCode := range accessCodes { + + if accessCode.Spec.Expiration != "" { + expiration, err := time.Parse(time.UnixDate, accessCode.Spec.Expiration) + + if err != nil { + return &accesscodepb.ListAcsResponse{}, hferrors.GrpcError( + codes.Internal, + "error while parsing expiration time for access code %s %v", + listOptions, + accessCode.Name, + err, + ) + } + + if time.Now().After(expiration) { // if the access code is expired don't return any scenarios + glog.V(4).Infof("access code %s was expired at %s", accessCode.Name, accessCode.Spec.Expiration) + continue + } } - return &accessCodeProto.OneTimeAccessCode{}, newErr.Err() + + preparedAcs = append(preparedAcs, &accesscodepb.AccessCode{ + Id: accessCode.Name, + Uid: string(accessCode.UID), + Description: accessCode.Spec.Description, + Scenarios: accessCode.Spec.Scenarios, + Courses: accessCode.Spec.Courses, + Expiration: accessCode.Spec.Expiration, + RestrictedBind: accessCode.Spec.RestrictedBind, + RestrictedBindValue: accessCode.Spec.RestrictedBindValue, + Printable: accessCode.Spec.Printable, + Labels: accessCode.Labels, + }) } - glog.V(2).Infof("retrieved OTAC %s", gor.GetId()) - return otac, nil + + glog.V(2).Infof("listed access codes") + + return &accesscodepb.ListAcsResponse{AccessCodes: preparedAcs}, nil +} + +/************************************************************************************************************** + * Resource oriented RPCs for OneTimeAccessCodes + * + * The following functions implement the resource oriented RPCs for OneTimeAccessCodes + **************************************************************************************************************/ + +func (a *GrpcAccessCodeServer) CreateOtac(ctx context.Context, cr *accesscodepb.CreateOtacRequest) (*accesscodepb.OneTimeAccessCode, error) { + // Generate an access code that can not be guessed + genName := "" + for genParts := 0; genParts < 3; genParts++ { + genName += util.GenerateResourceName("", util.RandStringRunes(16), 4) + } + genName = genName[1:] + + scheduledEventName := cr.GetSeName() + if scheduledEventName == "" { + return &accesscodepb.OneTimeAccessCode{}, hferrors.GrpcError( + codes.InvalidArgument, + "error creating otac, se_name field blank", + cr, + ) + } + + scheduledUid := cr.GetSeUid() + if scheduledUid == "" { + return &accesscodepb.OneTimeAccessCode{}, hferrors.GrpcError( + codes.InvalidArgument, + "error creating otac, se_uid field blank", + cr, + ) + } + maxDuration := cr.GetMaxDuration() + + otac := &hfv1.OneTimeAccessCode{ + ObjectMeta: metav1.ObjectMeta{ + Name: genName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: "ScheduledEvent", + Name: scheduledEventName, + UID: types.UID(scheduledUid), + }, + }, + Labels: map[string]string{ + hflabels.UserLabel: "", + hflabels.ScheduledEventLabel: scheduledEventName, + hflabels.OneTimeAccessCodeLabel: genName, + }, + }, + Spec: hfv1.OneTimeAccessCodeSpec{ + User: "", + RedeemedTimestamp: "", + MaxDuration: maxDuration, + }, + } + otac, err := a.otacClient.Create(ctx, otac, metav1.CreateOptions{}) + if err != nil { + glog.Errorf("error creating one time access code %v", err) + // error handling + } + return &accesscodepb.OneTimeAccessCode{ + Id: otac.Name, + User: otac.Spec.User, + RedeemedTimestamp: otac.Spec.RedeemedTimestamp, + MaxDuration: otac.Spec.MaxDuration, + Labels: otac.Labels, + }, nil } -func (a *GrpcAccessCodeServer) UpdateOtac(ctx context.Context, otacRequest *accessCodeProto.OneTimeAccessCode) (*empty.Empty, error) { +func (a *GrpcAccessCodeServer) GetOtac(ctx context.Context, req *generalpb.GetRequest) (*accesscodepb.OneTimeAccessCode, error) { + otac, err := util.GenericHfGetter(ctx, req, a.otacClient, a.otacLister.OneTimeAccessCodes(util.GetReleaseNamespace()), "OTAC", a.otacSynced()) + if err != nil { + return &accesscodepb.OneTimeAccessCode{}, err + } + + glog.V(2).Infof("retrieved OTAC %s", otac.Name) + + return &accesscodepb.OneTimeAccessCode{ + Id: otac.Name, + Uid: string(otac.UID), + User: otac.Spec.User, + RedeemedTimestamp: otac.Spec.RedeemedTimestamp, + MaxDuration: otac.Spec.MaxDuration, + Labels: otac.Labels, + }, nil +} + +func (a *GrpcAccessCodeServer) UpdateOtac(ctx context.Context, otacRequest *accesscodepb.OneTimeAccessCode) (*emptypb.Empty, error) { id := otacRequest.GetId() if id == "" { - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "no ID passed in", + otacRequest, ) - newErr, wde := newErr.WithDetails(otacRequest) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - otac, err := a.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util.GetReleaseNamespace()).Get(a.ctx, id, metav1.GetOptions{}) + otac, err := a.otacClient.Get(ctx, id, metav1.GetOptions{}) if err != nil { - newErr := status.Newf( + glog.Error(err) + return hferrors.GrpcError( codes.Internal, "error while retrieving OTAC %s", + otacRequest, otacRequest.GetId(), ) - newErr, wde := newErr.WithDetails(otacRequest) - if wde != nil { - return wde - } - glog.Error(err) - return newErr.Err() } otac.Spec.User = otacRequest.GetUser() otac.Spec.RedeemedTimestamp = otacRequest.GetRedeemedTimestamp() otac.Spec.MaxDuration = otacRequest.GetMaxDuration() - otac.Labels[util.UserLabel] = otacRequest.GetUser() + otac.Labels[hflabels.UserLabel] = otacRequest.GetUser() - _, updateErr := a.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util.GetReleaseNamespace()).Update(a.ctx, otac, metav1.UpdateOptions{}) + _, updateErr := a.otacClient.Update(ctx, otac, metav1.UpdateOptions{}) return updateErr }) if retryErr != nil { - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "error attempting to update", + otacRequest, ) - newErr, wde := newErr.WithDetails(otacRequest) - if wde != nil { - return &empty.Empty{}, wde + } + + return &emptypb.Empty{}, nil +} + +func (a *GrpcAccessCodeServer) DeleteOtac(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, a.otacClient, "OTAC") +} + +func (a *GrpcAccessCodeServer) DeleteCollectionOtac(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, a.otacClient, "OTACs") +} + +func (a *GrpcAccessCodeServer) ListOtac(ctx context.Context, listOptions *generalpb.ListOptions) (*accesscodepb.ListOtacsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var otacs []hfv1.OneTimeAccessCode + var err error + if !doLoadFromCache { + var otacList *hfv1.OneTimeAccessCodeList + otacList, err = util.ListByHfClient(ctx, listOptions, a.otacClient, "OTACs") + if err == nil { + otacs = otacList.Items } - return &empty.Empty{}, newErr.Err() + } else { + otacs, err = util.ListByCache(listOptions, a.otacLister, "OTACs", a.otacSynced()) } + if err != nil { + glog.Error(err) + return &accesscodepb.ListOtacsResponse{}, err + } + + preparedOtacs := []*accesscodepb.OneTimeAccessCode{} // must be declared this way so as to JSON marshal into [] instead of null + for _, otac := range otacs { + preparedOtacs = append(preparedOtacs, &accesscodepb.OneTimeAccessCode{ + Id: otac.Name, + Uid: string(otac.UID), + User: otac.Spec.User, + RedeemedTimestamp: otac.Spec.RedeemedTimestamp, + MaxDuration: otac.Spec.MaxDuration, + Labels: otac.Labels, + }) + } + + glog.V(2).Infof("listed otacs") - return &empty.Empty{}, nil + return &accesscodepb.ListOtacsResponse{Otacs: preparedOtacs}, nil } -func (a *GrpcAccessCodeServer) ValidateExistence(ctx context.Context, gor *accessCodeProto.ResourceId) (*accessCodeProto.ResourceValidation, error) { +/************************************************************************************************************** + * Helper RPCs + * + * This section includes Helper RPCs exposed by the internal gRPC server. + * These RPCs provide advanced functionalities beyond basic resource-related operations. + **************************************************************************************************************/ + +func (a *GrpcAccessCodeServer) ValidateExistence(ctx context.Context, gor *generalpb.ResourceId) (*accesscodepb.ResourceValidation, error) { if len(gor.GetId()) == 0 { - newErr := status.Newf( - codes.InvalidArgument, - "no id passed in", - ) - newErr, wde := newErr.WithDetails(gor) - if wde != nil { - return &accessCodeProto.ResourceValidation{Valid: false}, wde - } - return &accessCodeProto.ResourceValidation{Valid: false}, newErr.Err() + return &accesscodepb.ResourceValidation{Valid: false}, hferrors.GrpcIdNotSpecifiedError(gor) } - _, err := a.hfClientSet.HobbyfarmV1().AccessCodes(util.GetReleaseNamespace()).Get(a.ctx, gor.GetId(), metav1.GetOptions{}) + _, err := a.acClient.Get(ctx, gor.GetId(), metav1.GetOptions{}) if err != nil { // If AccessCode does not exist check if this might be an OTAC - _, err := a.hfClientSet.HobbyfarmV1().OneTimeAccessCodes(util.GetReleaseNamespace()).Get(a.ctx, gor.GetId(), metav1.GetOptions{}) + _, err := a.otacClient.Get(ctx, gor.GetId(), metav1.GetOptions{}) if err != nil { - return &accessCodeProto.ResourceValidation{Valid: false}, nil + return &accesscodepb.ResourceValidation{Valid: false}, nil } } - return &accessCodeProto.ResourceValidation{Valid: true}, nil + return &accesscodepb.ResourceValidation{Valid: true}, nil +} + +func (a *GrpcAccessCodeServer) GetAccessCodesWithOTACs(ctx context.Context, codeIds *accesscodepb.ResourceIds) (*accesscodepb.ListAcsResponse, error) { + ids := codeIds.GetIds() + otacReq, err := labels.NewRequirement(hflabels.OneTimeAccessCodeLabel, selection.In, ids) + if err != nil { + return &accesscodepb.ListAcsResponse{}, hferrors.GrpcError( + codes.Internal, + "Unable to create label selector from access code ids", + codeIds, + ) + } + selector := labels.NewSelector() + selector = selector.Add(*otacReq) + selectorString := selector.String() + + // First get the oneTimeAccessCodes + otacList, err := a.ListOtac(ctx, &generalpb.ListOptions{LabelSelector: selectorString}) + + if err != nil { + return nil, err + } + + //Append the value of onetime access codes to the list + for _, otac := range otacList.Otacs { + se, err := a.eventClient.GetScheduledEvent(ctx, &generalpb.GetRequest{Id: otac.Labels[hflabels.ScheduledEventLabel]}) + if err != nil { + glog.Error(err) + return &accesscodepb.ListAcsResponse{}, hferrors.GrpcError( + codes.Internal, + "error retreiving scheduled event from OTAC: %v", + codeIds, + err, + ) + } + ids = append(ids, se.AccessCode) + } + + // Update the label selector + acReq, err := labels.NewRequirement(hflabels.AccessCodeLabel, selection.In, ids) + if err != nil { + return &accesscodepb.ListAcsResponse{}, hferrors.GrpcError( + codes.Internal, + "Unable to create label selector from access code ids", + codeIds, + ) + } + selector = labels.NewSelector() + selector = selector.Add(*acReq) + selectorString = selector.String() + + accessCodes, err := a.ListAc(ctx, &generalpb.ListOptions{LabelSelector: selectorString}) + return accessCodes, err +} + +func (a *GrpcAccessCodeServer) GetAccessCodeWithOTACs(ctx context.Context, codeId *generalpb.ResourceId) (*accesscodepb.AccessCode, error) { + accessCodeId := codeId.GetId() + if len(accessCodeId) == 0 { + return &accesscodepb.AccessCode{}, hferrors.GrpcIdNotSpecifiedError(codeId) + } + + accessCodeList, err := a.GetAccessCodesWithOTACs(ctx, &accesscodepb.ResourceIds{Ids: []string{accessCodeId}}) + + if err != nil { + return &accesscodepb.AccessCode{}, hferrors.GrpcError( + codes.NotFound, + "access code (%s) not found: %v", + codeId, + accessCodeId, + err, + ) + } + + accessCodes := accessCodeList.GetAccessCodes() + + if len(accessCodes) != 1 { + return &accesscodepb.AccessCode{}, hferrors.GrpcError( + codes.Internal, + "insane result found", + codeId, + ) + } + + return accessCodes[0], nil +} + +func (a *GrpcAccessCodeServer) GetAcOwnerReferences(ctx context.Context, req *generalpb.GetRequest) (*generalpb.OwnerReferences, error) { + return util.GetOwnerReferences(ctx, req, a.acClient, a.acLister.AccessCodes(util.GetReleaseNamespace()), "access code", a.acSynced()) +} + +/************************************************************************************************************** + * Internal helper functions + * + * Internal helper functions which are only used within this file + **************************************************************************************************************/ + +func (a *GrpcAccessCodeServer) checkInputParamsForCreateAc(cr *accesscodepb.CreateAcRequest) error { + if cr.GetAcName() == "" || + cr.GetDescription() == "" || + cr.GetExpiration() == "" || + cr.GetSeName() == "" || + cr.GetSeUid() == "" || + (cr.GetRestrictedBind() && cr.GetRestrictedBindValue() == "") { + + return hferrors.GrpcError( + codes.InvalidArgument, + "error creating access code, required input field is blank", + cr, + ) + } + return nil } diff --git a/v3/services/accesscodesvc/main.go b/v3/services/accesscodesvc/main.go index 6f8db66e..f2575b84 100644 --- a/v3/services/accesscodesvc/main.go +++ b/v3/services/accesscodesvc/main.go @@ -1,15 +1,18 @@ package main import ( - "context" "sync" + "time" - "github.com/ebauman/crder" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" - "github.com/golang/glog" accesscodeservice "github.com/hobbyfarm/gargantua/services/accesscodesvc/v3/internal" - accessCodeProto "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" ) var ( @@ -21,20 +24,27 @@ func init() { } func main() { + stopCh := signals.SetupSignalHandler() cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) - crds := accesscodeservice.GenerateAccessCodeCRD() - glog.Info("installing/updating access code CRDs") - err := crder.InstallUpdateCRDs(cfg, crds...) - if err != nil { - glog.Fatalf("failed installing/updating access code CRDs: %s", err.Error()) + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(accesscodeservice.AccessCodeCRDInstaller{}, cfg, "access code") + + services := []microservices.MicroService{ + microservices.ScheduledEvent, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() } - glog.Info("finished installing/updating access code CRDs") + + eventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) - ctx := context.Background() - as := accesscodeservice.NewGrpcAccessCodeServer(hfClient, ctx) - accessCodeProto.RegisterAccessCodeSvcServer(gs, as) + as := accesscodeservice.NewGrpcAccessCodeServer(hfClient, hfInformerFactory, eventClient) + accesscodepb.RegisterAccessCodeSvcServer(gs, as) var wg sync.WaitGroup wg.Add(1) @@ -44,5 +54,7 @@ func main() { microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) }() + hfInformerFactory.Start(stopCh) + wg.Wait() } diff --git a/v3/services/authnsvc/go.mod b/v3/services/authnsvc/go.mod index ad626175..b7e9e379 100644 --- a/v3/services/authnsvc/go.mod +++ b/v3/services/authnsvc/go.mod @@ -13,13 +13,14 @@ require ( github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 golang.org/x/crypto v0.14.0 google.golang.org/grpc v1.58.3 + k8s.io/apimachinery v0.28.2 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -62,7 +63,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.28.2 // indirect - k8s.io/apimachinery v0.28.2 // indirect k8s.io/client-go v12.0.0+incompatible // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect diff --git a/v3/services/authnsvc/go.sum b/v3/services/authnsvc/go.sum index 92add83c..5668ca42 100644 --- a/v3/services/authnsvc/go.sum +++ b/v3/services/authnsvc/go.sum @@ -25,8 +25,9 @@ github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +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/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/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= diff --git a/v3/services/authnsvc/internal/authnservice.go b/v3/services/authnsvc/internal/authnservice.go index 69179a2f..6825d668 100644 --- a/v3/services/authnsvc/internal/authnservice.go +++ b/v3/services/authnsvc/internal/authnservice.go @@ -12,20 +12,31 @@ import ( "github.com/dgrijalva/jwt-go" "github.com/golang/glog" "github.com/gorilla/mux" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" "github.com/hobbyfarm/gargantua/v3/pkg/util" - accessCodeProto "github.com/hobbyfarm/gargantua/v3/protos/accesscode" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" "golang.org/x/crypto/bcrypt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" ) +type PreparedScheduledEvent struct { + Id string `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + EndDate string `json:"end_timestamp"` +} + func (a AuthServer) ChangePasswordFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -52,7 +63,7 @@ func (a AuthServer) ChangePasswordFunc(w http.ResponseWriter, r *http.Request) { func (a AuthServer) UpdateSettingsFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -81,7 +92,7 @@ func (a AuthServer) UpdateSettingsFunc(w http.ResponseWriter, r *http.Request) { func (a AuthServer) ListAccessCodeFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -106,7 +117,7 @@ func (a AuthServer) ListAccessCodeFunc(w http.ResponseWriter, r *http.Request) { func (a AuthServer) RetreiveSettingsFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -132,7 +143,7 @@ func (a AuthServer) RetreiveSettingsFunc(w http.ResponseWriter, r *http.Request) func (a AuthServer) AddAccessCodeFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -155,17 +166,17 @@ func (a AuthServer) AddAccessCodeFunc(w http.ResponseWriter, r *http.Request) { return } - set, err := a.settingClient.GetSettingValue(r.Context(), &settingProto.Id{Name: string(settingUtil.StrictAccessCodeValidation)}) + set, err := a.settingClient.GetSettingValue(r.Context(), &generalpb.ResourceId{Id: string(settingUtil.StrictAccessCodeValidation)}) if err != nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error adding accesscode") return } - if s, ok := set.GetValue().(*settingProto.SettingValue_BoolValue); err != nil || !ok || set == nil { + if s, ok := set.GetValue().(*settingpb.SettingValue_BoolValue); err != nil || !ok || set == nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error adding accesscode") return } else if s.BoolValue { - validation, err := a.acClient.ValidateExistence(r.Context(), &accessCodeProto.ResourceId{Id: accessCode}) + validation, err := a.acClient.ValidateExistence(r.Context(), &generalpb.ResourceId{Id: accessCode}) if err != nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error adding accesscode") return @@ -191,7 +202,7 @@ func (a AuthServer) AddAccessCodeFunc(w http.ResponseWriter, r *http.Request) { func (a AuthServer) RemoveAccessCodeFunc(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -216,7 +227,7 @@ func (a AuthServer) RemoveAccessCodeFunc(w http.ResponseWriter, r *http.Request) glog.V(2).Infof("removed accesscode %s to user %s", accessCode, user.Email) } -func (a AuthServer) AddAccessCode(user *userProto.User, accessCode string, ctx context.Context) error { +func (a AuthServer) AddAccessCode(user *userpb.User, accessCode string, ctx context.Context) error { if len(user.GetId()) == 0 || len(accessCode) == 0 { return fmt.Errorf("bad parameters passed, %s:%s", user.GetId(), accessCode) } @@ -224,7 +235,7 @@ func (a AuthServer) AddAccessCode(user *userProto.User, accessCode string, ctx c accessCode = strings.ToLower(accessCode) // check if this is an otac - otac, err := a.acClient.GetOtac(ctx, &accessCodeProto.ResourceId{Id: accessCode}) + otac, err := a.acClient.GetOtac(ctx, &generalpb.GetRequest{Id: accessCode}) if err != nil { //otac does not exist. normal access code } else { @@ -257,7 +268,7 @@ func (a AuthServer) AddAccessCode(user *userProto.User, accessCode string, ctx c // Important: user.GetPassword() contains the hashed password. Hence, it can and should not be updated! // Otherwise the password would be updated to the current password hash value. // To not update the password, we therefore need to provide an empty string or a user object without password. - user = &userProto.User{ + user = &userpb.User{ Id: user.Id, AccessCodes: append(user.AccessCodes, accessCode), } @@ -271,7 +282,7 @@ func (a AuthServer) AddAccessCode(user *userProto.User, accessCode string, ctx c return nil } -func (a AuthServer) RemoveAccessCode(user *userProto.User, accessCode string, ctx context.Context) error { +func (a AuthServer) RemoveAccessCode(user *userpb.User, accessCode string, ctx context.Context) error { if len(user.GetId()) == 0 || len(accessCode) == 0 { return fmt.Errorf("bad parameters passed, %s:%s", user.GetId(), accessCode) } @@ -303,7 +314,7 @@ func (a AuthServer) RemoveAccessCode(user *userProto.User, accessCode string, ct // Important: user.GetPassword() contains the hashed password. Hence, it can and should not be updated! // Otherwise the password would be updated to the current password hash value. // To not update the password, we therefore need to provide an empty string or a user object without password. - updateAccessCode := &userProto.UpdateAccessCodesRequest{ + updateAccessCode := &userpb.UpdateAccessCodesRequest{ Id: user.Id, AccessCodes: newAccessCodes, } @@ -317,7 +328,7 @@ func (a AuthServer) RemoveAccessCode(user *userProto.User, accessCode string, ct return nil } -func (a AuthServer) ChangePassword(user *userProto.User, oldPassword string, newPassword string, ctx context.Context) error { +func (a AuthServer) ChangePassword(user *userpb.User, oldPassword string, newPassword string, ctx context.Context) error { if len(user.GetId()) == 0 || len(oldPassword) == 0 || len(newPassword) == 0 { return fmt.Errorf("bad parameters passed, %s", user.GetId()) } @@ -340,12 +351,12 @@ func (a AuthServer) ChangePassword(user *userProto.User, oldPassword string, new return nil } -func (a AuthServer) UpdateSettings(user *userProto.User, newSettings map[string]string, ctx context.Context) error { +func (a AuthServer) UpdateSettings(user *userpb.User, newSettings map[string]string, ctx context.Context) error { if len(user.GetId()) == 0 { return fmt.Errorf("bad parameters passed, %s", user.GetId()) } - user = &userProto.User{ + user = &userpb.User{ Id: user.GetId(), Settings: newSettings, } @@ -360,13 +371,13 @@ func (a AuthServer) UpdateSettings(user *userProto.User, newSettings map[string] } func (a AuthServer) RegisterWithAccessCodeFunc(w http.ResponseWriter, r *http.Request) { - set, err := a.settingClient.GetSettingValue(r.Context(), &settingProto.Id{Name: string(settingUtil.SettingRegistrationDisabled)}) + set, err := a.settingClient.GetSettingValue(r.Context(), &generalpb.ResourceId{Id: string(settingUtil.SettingRegistrationDisabled)}) if err != nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error performing registration") return } - if s, ok := set.GetValue().(*settingProto.SettingValue_BoolValue); err != nil || !ok || set == nil { + if s, ok := set.GetValue().(*settingpb.SettingValue_BoolValue); err != nil || !ok || set == nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error performing registration") return } else if s.BoolValue { @@ -396,17 +407,17 @@ func (a AuthServer) RegisterWithAccessCodeFunc(w http.ResponseWriter, r *http.Re return } - set, err = a.settingClient.GetSettingValue(r.Context(), &settingProto.Id{Name: string(settingUtil.StrictAccessCodeValidation)}) + set, err = a.settingClient.GetSettingValue(r.Context(), &generalpb.ResourceId{Id: string(settingUtil.StrictAccessCodeValidation)}) if err != nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error performing registration") return } - if s, ok := set.GetValue().(*settingProto.SettingValue_BoolValue); err != nil || !ok || set == nil { + if s, ok := set.GetValue().(*settingpb.SettingValue_BoolValue); err != nil || !ok || set == nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error performing registration") return } else if s.BoolValue { - validation, err := a.acClient.ValidateExistence(r.Context(), &accessCodeProto.ResourceId{Id: accessCode}) + validation, err := a.acClient.ValidateExistence(r.Context(), &generalpb.ResourceId{Id: accessCode}) if err != nil { util.ReturnHTTPMessage(w, r, 500, "internalerror", "error performing registration") return @@ -417,28 +428,24 @@ func (a AuthServer) RegisterWithAccessCodeFunc(w http.ResponseWriter, r *http.Re } } - userId, err := a.userClient.CreateUser(r.Context(), &userProto.CreateUserRequest{ + userId, err := a.userClient.CreateUser(r.Context(), &userpb.CreateUserRequest{ Email: email, Password: password, }) if err != nil { - if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*userProto.CreateUserRequest) - if s.Code() == codes.InvalidArgument { - glog.Errorf("error creating user, invalid argument for user with email: %s", details.Email) - util.ReturnHTTPMessage(w, r, 400, "error", s.Message()) - return - } else if s.Code() == codes.AlreadyExists { - glog.Errorf("user with email %s already exists", details.Email) - util.ReturnHTTPMessage(w, r, 409, "error", s.Message()) - return - } - glog.Errorf("error creating user: %s", s.Message()) - util.ReturnHTTPMessage(w, r, 500, "error", "error creating user") + s := status.Convert(err) + details, _ := hferrors.ExtractDetail[*userpb.CreateUserRequest](s) + if s.Code() == codes.InvalidArgument { + glog.Errorf("error creating user, invalid argument for user with email: %s", details.GetEmail()) + util.ReturnHTTPMessage(w, r, 400, "error", s.Message()) + return + } else if s.Code() == codes.AlreadyExists { + glog.Errorf("user with email %s already exists", details.GetEmail()) + util.ReturnHTTPMessage(w, r, 409, "error", s.Message()) return } - glog.Errorf("error creating user: %s", err.Error()) + glog.Errorf("error creating user: %s", hferrors.GetErrorMessage(err)) util.ReturnHTTPMessage(w, r, 500, "error", "error creating user") return } @@ -446,20 +453,18 @@ func (a AuthServer) RegisterWithAccessCodeFunc(w http.ResponseWriter, r *http.Re // from this point, the user is created // we are now trying to add the access code he provided - user, err := a.userClient.GetUserById(r.Context(), &userProto.UserId{ + user, err := a.userClient.GetUserById(r.Context(), &generalpb.GetRequest{ Id: userId.GetId(), }) if err != nil { - if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*userProto.UserId) - if s.Code() == codes.InvalidArgument { - glog.Error("error retrieving created user, no id passed in") - } else { - glog.Errorf("error while retrieving created user %s: %s", details.Id, s.Message()) - } + s := status.Convert(err) + details, _ := hferrors.ExtractDetail[*generalpb.GetRequest](s) + if s.Code() == codes.InvalidArgument { + glog.Error("error retrieving created user, no id passed in") + } else { + glog.Errorf("error while retrieving created user %s: %s", details.GetId(), hferrors.GetErrorMessage(err)) } - glog.Errorf("error while retrieving created user: %s", err.Error()) util.ReturnHTTPMessage(w, r, 500, "error", "error creating user with accesscode") } @@ -479,7 +484,7 @@ func (a AuthServer) LoginFunc(w http.ResponseWriter, r *http.Request) { email := r.PostFormValue("email") password := r.PostFormValue("password") - user, err := a.userClient.GetUserByEmail(r.Context(), &userProto.GetUserByEmailRequest{Email: email}) + user, err := a.userClient.GetUserByEmail(r.Context(), &userpb.GetUserByEmailRequest{Email: email}) if err != nil { glog.Errorf("there was an error retrieving the user %s: %v", email, err) @@ -501,20 +506,20 @@ func (a AuthServer) LoginFunc(w http.ResponseWriter, r *http.Request) { glog.Error(err) } - a.userClient.SetLastLoginTimestamp(r.Context(), &userProto.UserId{Id: user.GetId()}) + a.userClient.SetLastLoginTimestamp(r.Context(), &generalpb.ResourceId{Id: user.GetId()}) util.ReturnHTTPMessage(w, r, 200, "authorized", token) } -func (a AuthServer) GenerateJWT(user *userProto.User) (string, error) { +func (a AuthServer) GenerateJWT(user *userpb.User) (string, error) { // Get Expiration Date Setting - setting, err := a.settingClient.GetSettingValue(context.Background(), &settingProto.Id{Name: string(settingUtil.UserTokenExpiration)}) + setting, err := a.settingClient.GetSettingValue(context.Background(), &generalpb.ResourceId{Id: string(settingUtil.UserTokenExpiration)}) if err != nil { return "", err } tokenExpiration := time.Duration(24) - if s, ok := setting.GetValue().(*settingProto.SettingValue_Int64Value); err != nil || !ok || setting == nil { + if s, ok := setting.GetValue().(*settingpb.SettingValue_Int64Value); err != nil || !ok || setting == nil { return "", fmt.Errorf("error retreiving retention Time setting") } else { tokenExpiration = time.Duration(s.Int64Value) @@ -537,7 +542,7 @@ func (a AuthServer) GenerateJWT(user *userProto.User) (string, error) { func (a *AuthServer) GetAccessSet(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") - user, err := a.internalAuthnServer.AuthN(r.Context(), &authn.AuthNRequest{ + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ Token: token, }) if err != nil { @@ -546,7 +551,7 @@ func (a *AuthServer) GetAccessSet(w http.ResponseWriter, r *http.Request) { } // need to get the user's access set and publish to front end - as, err := a.rbacClient.GetAccessSet(r.Context(), &userProto.UserId{Id: user.GetId()}) + as, err := a.rbacClient.GetAccessSet(r.Context(), &generalpb.ResourceId{Id: user.GetId()}) if err != nil { util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error fetching access set") glog.Error(err) @@ -562,3 +567,82 @@ func (a *AuthServer) GetAccessSet(w http.ResponseWriter, r *http.Request) { util.ReturnHTTPContent(w, r, http.StatusOK, "access_set", encodedAS) } + +func (a AuthServer) ListScheduledEventsFunc(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("Authorization") + user, err := a.internalAuthnServer.AuthN(r.Context(), &authnpb.AuthNRequest{ + Token: token, + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list suitable scheduledevents") + return + } + + // This holds a map of AC -> SE + accessCodeScheduledEvent := make(map[string]PreparedScheduledEvent) + + // First we add ScheduledEvents based on OneTimeAccessCodes + otacReq, _ := labels.NewRequirement(hflabels.OneTimeAccessCodeLabel, selection.In, user.GetAccessCodes()) + selector := labels.NewSelector() + selector = selector.Add(*otacReq) + + otacList, err := a.acClient.ListOtac(r.Context(), &generalpb.ListOptions{LabelSelector: selector.String()}) + + if err == nil { + for _, otac := range otacList.GetOtacs() { + se, err := a.scheduledEventClient.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: otac.Labels[hflabels.ScheduledEventLabel]}) + if err != nil { + continue + } + endTime := se.GetEndTime() + + // If OTAC specifies a max Duration we need to calculate the EndTime correctly + if otac.GetMaxDuration() != "" { + otacEndTime, err := time.Parse(time.UnixDate, otac.GetRedeemedTimestamp()) + if err != nil { + continue + } + otacDurationWithDays, _ := util.GetDurationWithDays(otac.GetMaxDuration()) + otacDuration, err := time.ParseDuration(otacDurationWithDays) + if err != nil { + continue + } + otacEndTime = otacEndTime.Add(otacDuration) + endTime = otacEndTime.Format(time.UnixDate) + } + + accessCodeScheduledEvent[otac.GetId()] = PreparedScheduledEvent{se.GetId(), se.GetDescription(), se.GetName(), endTime} + } + } + + acReq, err := labels.NewRequirement(hflabels.AccessCodeLabel, selection.In, user.GetAccessCodes()) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "internal error while retrieving scheduled events") + return + } + selector = labels.NewSelector() + selector = selector.Add(*acReq) + + // Afterwards we retreive the normal AccessCodes + acList, err := a.acClient.ListAc(r.Context(), &generalpb.ListOptions{LabelSelector: selector.String()}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "internal error while retrieving scheduled events") + return + } + accessCodes := acList.GetAccessCodes() + //Getting single SEs should be faster than listing all of them and iterating them in O(n^2), in most cases users only have a hand full of accessCodes. + for _, ac := range accessCodes { + se, err := a.scheduledEventClient.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: ac.GetLabels()[hflabels.ScheduledEventLabel]}) + if err != nil { + glog.Error(err) + continue + } + accessCodeScheduledEvent[ac.GetId()] = PreparedScheduledEvent{se.GetId(), se.GetDescription(), se.GetName(), se.GetEndTime()} + } + + encodedMap, err := json.Marshal(accessCodeScheduledEvent) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedMap) +} diff --git a/v3/services/authnsvc/internal/grpc.go b/v3/services/authnsvc/internal/grpc.go index 9be51061..ed91c9ce 100644 --- a/v3/services/authnsvc/internal/grpc.go +++ b/v3/services/authnsvc/internal/grpc.go @@ -7,36 +7,30 @@ import ( "github.com/dgrijalva/jwt-go" "github.com/golang/glog" - authnProto "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/user" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + "github.com/hobbyfarm/gargantua/v3/pkg/errors" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) type GrpcAuthnServer struct { - authnProto.UnimplementedAuthNServer - userClient user.UserSvcClient + authnpb.UnimplementedAuthNServer + userClient userpb.UserSvcClient } -func NewGrpcAuthNServer(userClient user.UserSvcClient) *GrpcAuthnServer { +func NewGrpcAuthNServer(userClient userpb.UserSvcClient) *GrpcAuthnServer { return &GrpcAuthnServer{userClient: userClient} } -func (a *GrpcAuthnServer) AuthN(c context.Context, ar *authnProto.AuthNRequest) (*userProto.User, error) { +func (a *GrpcAuthnServer) AuthN(c context.Context, ar *authnpb.AuthNRequest) (*userpb.User, error) { token := ar.GetToken() if len(token) == 0 { - err := status.Newf( + glog.Errorf("no bearer token passed, authentication failed") + return &userpb.User{}, errors.GrpcError( codes.InvalidArgument, "missing the following properties from type 'AuthNRequest': token", + ar, ) - - err, wde := err.WithDetails(ar) - if wde != nil { - return &userProto.User{}, wde - } - glog.Errorf("no bearer token passed, authentication failed") - return &userProto.User{}, err.Err() } var finalToken string @@ -50,45 +44,41 @@ func (a *GrpcAuthnServer) AuthN(c context.Context, ar *authnProto.AuthNRequest) user, err := a.validateToken(c, finalToken) if err != nil { - newErr := status.Newf( + glog.Infof("could not validate token: %s", err) + return &userpb.User{}, errors.GrpcError( codes.Unauthenticated, "could not validate token: %s", + ar, err, ) - newErr, wde := newErr.WithDetails(ar) - if wde != nil { - return &userProto.User{}, wde - } - glog.Infof("could not validate token: %s", err) - return &userProto.User{}, newErr.Err() } return user, nil } -func (a *GrpcAuthnServer) validateToken(ctx context.Context, token string) (*userProto.User, error) { +func (a *GrpcAuthnServer) validateToken(ctx context.Context, token string) (*userpb.User, error) { user, err := a.validate(ctx, token) if err != nil { glog.Errorf("error validating user %v", err) - return &userProto.User{}, fmt.Errorf("authentication failed") + return &userpb.User{}, fmt.Errorf("authentication failed") } return user, nil } -func (a *GrpcAuthnServer) validate(ctx context.Context, tokenString string) (*userProto.User, error) { +func (a *GrpcAuthnServer) validate(ctx context.Context, tokenString string) (*userpb.User, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // Don't forget to validate the alg is what you expect: if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } - var user *userProto.User + var user *userpb.User if claims, ok := token.Claims.(jwt.MapClaims); ok { var err error - user, err = a.userClient.GetUserByEmail(ctx, &userProto.GetUserByEmailRequest{Email: fmt.Sprint(claims["email"])}) + user, err = a.userClient.GetUserByEmail(ctx, &userpb.GetUserByEmailRequest{Email: fmt.Sprint(claims["email"])}) if err != nil { glog.Errorf("could not find user that matched token %s", fmt.Sprint(claims["email"])) - return &userProto.User{}, fmt.Errorf("could not find user that matched token %s", fmt.Sprint(claims["email"])) + return &userpb.User{}, fmt.Errorf("could not find user that matched token %s", fmt.Sprint(claims["email"])) } } // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") @@ -97,17 +87,17 @@ func (a *GrpcAuthnServer) validate(ctx context.Context, tokenString string) (*us if err != nil { glog.Errorf("error while validating user: %v", err) - return &userProto.User{}, err + return &userpb.User{}, err } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { - user, err := a.userClient.GetUserByEmail(ctx, &userProto.GetUserByEmailRequest{Email: fmt.Sprint(claims["email"])}) + user, err := a.userClient.GetUserByEmail(ctx, &userpb.GetUserByEmailRequest{Email: fmt.Sprint(claims["email"])}) if err != nil { - return &userProto.User{}, err + return &userpb.User{}, err } else { return user, nil } } glog.Errorf("error while validating user") - return &userProto.User{}, fmt.Errorf("error while validating user") + return &userpb.User{}, fmt.Errorf("error while validating user") } diff --git a/v3/services/authnsvc/internal/server.go b/v3/services/authnsvc/internal/server.go index 06aef8fc..df10c6f3 100644 --- a/v3/services/authnsvc/internal/server.go +++ b/v3/services/authnsvc/internal/server.go @@ -3,26 +3,36 @@ package authnservice import ( "github.com/golang/glog" "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/accesscode" - "github.com/hobbyfarm/gargantua/v3/protos/rbac" - "github.com/hobbyfarm/gargantua/v3/protos/setting" - "github.com/hobbyfarm/gargantua/v3/protos/user" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" ) type AuthServer struct { - acClient accesscode.AccessCodeSvcClient - userClient user.UserSvcClient - settingClient setting.SettingSvcClient - rbacClient rbac.RbacSvcClient - internalAuthnServer *GrpcAuthnServer + acClient accesscodepb.AccessCodeSvcClient + rbacClient rbacpb.RbacSvcClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + settingClient settingpb.SettingSvcClient + userClient userpb.UserSvcClient + internalAuthnServer *GrpcAuthnServer } -func NewAuthServer(accesscodeClient accesscode.AccessCodeSvcClient, userClient user.UserSvcClient, settingCLient setting.SettingSvcClient, rbacClient rbac.RbacSvcClient, internalAuthnServer *GrpcAuthnServer) (AuthServer, error) { +func NewAuthServer( + accesscodeClient accesscodepb.AccessCodeSvcClient, + rbacClient rbacpb.RbacSvcClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + settingClient settingpb.SettingSvcClient, + userClient userpb.UserSvcClient, + internalAuthnServer *GrpcAuthnServer, +) (AuthServer, error) { a := AuthServer{} a.acClient = accesscodeClient - a.userClient = userClient - a.settingClient = settingCLient a.rbacClient = rbacClient + a.scheduledEventClient = scheduledEventClient + a.settingClient = settingClient + a.userClient = userClient a.internalAuthnServer = internalAuthnServer return a, nil } @@ -37,5 +47,6 @@ func (a AuthServer) SetupRoutes(r *mux.Router) { r.HandleFunc("/auth/settings", a.UpdateSettingsFunc).Methods("POST") r.HandleFunc("/auth/authenticate", a.LoginFunc).Methods("POST") r.HandleFunc("/auth/access", a.GetAccessSet).Methods("GET") + r.HandleFunc("/auth/scheduledevents", a.ListScheduledEventsFunc).Methods("GET") glog.V(2).Infof("set up route") } diff --git a/v3/services/authnsvc/main.go b/v3/services/authnsvc/main.go index bee4a7df..421fa126 100644 --- a/v3/services/authnsvc/main.go +++ b/v3/services/authnsvc/main.go @@ -8,11 +8,12 @@ import ( "github.com/golang/glog" authnservice "github.com/hobbyfarm/gargantua/services/authnsvc/v3/internal" - "github.com/hobbyfarm/gargantua/v3/protos/accesscode" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/rbac" - "github.com/hobbyfarm/gargantua/v3/protos/setting" - "github.com/hobbyfarm/gargantua/v3/protos/user" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" ) var ( @@ -23,40 +24,41 @@ func init() { serviceConfig = microservices.BuildServiceConfig() } -// TODO: Remove rbacClient, hfClientSet etc. func main() { services := []microservices.MicroService{ microservices.AccessCode, - microservices.User, - microservices.Setting, microservices.Rbac, + microservices.ScheduledEvent, + microservices.Setting, + microservices.User, } connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) for _, conn := range connections { defer conn.Close() } - rbacClient := rbac.NewRbacSvcClient(connections[microservices.Rbac]) - accesscodeClient := accesscode.NewAccessCodeSvcClient(connections[microservices.AccessCode]) - userClient := user.NewUserSvcClient(connections[microservices.User]) - settingClient := setting.NewSettingSvcClient(connections[microservices.Setting]) + accesscodeClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + rbacClient := rbacpb.NewRbacSvcClient(connections[microservices.Rbac]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + settingClient := settingpb.NewSettingSvcClient(connections[microservices.Setting]) + userClient := userpb.NewUserSvcClient(connections[microservices.User]) gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) as := authnservice.NewGrpcAuthNServer(userClient) - authn.RegisterAuthNServer(gs, as) + authnpb.RegisterAuthNServer(gs, as) var wg sync.WaitGroup - + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates wg.Add(1) + go func() { defer wg.Done() microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) }() - wg.Add(1) go func() { defer wg.Done() - authServer, err := authnservice.NewAuthServer(accesscodeClient, userClient, settingClient, rbacClient, as) + authServer, err := authnservice.NewAuthServer(accesscodeClient, rbacClient, scheduledEventClient, settingClient, userClient, as) if err != nil { glog.Fatal(err) } diff --git a/v3/services/authrsvc/internal/grpc.go b/v3/services/authrsvc/internal/grpc.go index 5e3c2a17..36220d08 100644 --- a/v3/services/authrsvc/internal/grpc.go +++ b/v3/services/authrsvc/internal/grpc.go @@ -5,10 +5,12 @@ import ( "fmt" "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - authrProto "github.com/hobbyfarm/gargantua/v3/protos/authr" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" v1 "k8s.io/api/authorization/v1" @@ -23,18 +25,18 @@ const ( ) type GrpcAuthRServer struct { - authrProto.UnimplementedAuthRServer - rbacClient rbacProto.RbacSvcClient + authrpb.UnimplementedAuthRServer + rbacClient rbacpb.RbacSvcClient } -func NewGrpcAuthRServer(rbacClient rbacProto.RbacSvcClient) *GrpcAuthRServer { +func NewGrpcAuthRServer(rbacClient rbacpb.RbacSvcClient) *GrpcAuthRServer { return &GrpcAuthRServer{rbacClient: rbacClient} } // This function authorizes the user by using impersonation as an additional security layer. // After impersonation, the user must also authorize himself against the rbac-service. // If the authorization fails, this method should always return an AuthRResponse with Success = false AND an error -func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrProto.AuthRRequest) (*authrProto.AuthRResponse, error) { +func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrpb.AuthRRequest) (*authrpb.AuthRResponse, error) { glog.Info("Authorizing (gRPC)...") config, err := rest.InClusterConfig() if err != nil { @@ -62,11 +64,11 @@ func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrProto.AuthRRequest) return a.returnResponseFailedAuthrWithError(ar, msg, err) } - rbacAuthGrant, err := a.rbacClient.Grants(c, &rbacProto.GrantRequest{UserName: iu, Permission: p}) + rbacAuthGrant, err := a.rbacClient.Grants(c, &rbacpb.GrantRequest{UserName: iu, Permission: p}) if err != nil { if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*rbacProto.GrantRequest) - glog.Errorf("could not perform auth grant for user %s: %s", details.UserName, s.Message()) + details, _ := hferrors.ExtractDetail[*rbacpb.GrantRequest](s) + glog.Errorf("could not perform auth grant for user %s: %s", details.GetUserName(), s.Message()) glog.Infof("auth grant failed for permission with apiGroup=%s, resource=%s and verb=%s", details.GetPermission().GetApiGroup(), details.GetPermission().GetResource(), details.GetPermission().GetVerb()) msg := "could not perform auth grant: " @@ -79,14 +81,14 @@ func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrProto.AuthRRequest) if !result.Status.Allowed || !rbacAuthGrant.Success { // Return the authorization decision. glog.Infof("User %s is not authorized to perform this request", iu) - return &authrProto.AuthRResponse{ + return &authrpb.AuthRResponse{ Success: false, }, fmt.Errorf("permission denied") } } // if we get here, AND has succeeded - return &authrProto.AuthRResponse{ + return &authrpb.AuthRResponse{ Success: true, }, nil } else { @@ -103,11 +105,11 @@ func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrProto.AuthRRequest) return a.returnResponseFailedAuthrWithError(ar, msg, err) } - rbacAuthGrant, err := a.rbacClient.Grants(c, &rbacProto.GrantRequest{UserName: iu, Permission: p}) + rbacAuthGrant, err := a.rbacClient.Grants(c, &rbacpb.GrantRequest{UserName: iu, Permission: p}) if err != nil { if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*rbacProto.GrantRequest) - glog.Errorf("could not perform auth grant for user %s: %s", details.UserName, s.Message()) + details, _ := hferrors.ExtractDetail[*rbacpb.GrantRequest](s) + glog.Errorf("could not perform auth grant for user %s: %s", details.GetUserName(), s.Message()) glog.Infof("auth grant failed for permission with apiGroup=%s, resource=%s and verb=%s", details.GetPermission().GetApiGroup(), details.GetPermission().GetResource(), details.GetPermission().GetVerb()) msg := "could not perform auth grant: " @@ -119,14 +121,14 @@ func (a *GrpcAuthRServer) AuthR(c context.Context, ar *authrProto.AuthRRequest) if result.Status.Allowed && rbacAuthGrant.Success { // Return the authorization decision. - return &authrProto.AuthRResponse{ + return &authrpb.AuthRResponse{ Success: true, }, nil } } } - return &authrProto.AuthRResponse{ + return &authrpb.AuthRResponse{ Success: false, }, fmt.Errorf("permission denied") } @@ -150,20 +152,12 @@ func (a *GrpcAuthRServer) createSubjectAccessReview(userName string, releaseName return sar } -func (a *GrpcAuthRServer) returnResponseFailedAuthrWithError(ar *authrProto.AuthRRequest, msg string, err error) (*authrProto.AuthRResponse, error) { - newErr := status.Newf( +func (a *GrpcAuthRServer) returnResponseFailedAuthrWithError(ar *authrpb.AuthRRequest, msg string, err error) (*authrpb.AuthRResponse, error) { + return &authrpb.AuthRResponse{}, errors.GrpcError( codes.Internal, "%s %s", + ar, msg, err, ) - newErr, wde := newErr.WithDetails(ar) - if wde != nil { - return &authrProto.AuthRResponse{ - Success: false, - }, wde - } - return &authrProto.AuthRResponse{ - Success: false, - }, newErr.Err() } diff --git a/v3/services/authrsvc/main.go b/v3/services/authrsvc/main.go index c9d79dcd..5934c70d 100644 --- a/v3/services/authrsvc/main.go +++ b/v3/services/authrsvc/main.go @@ -7,8 +7,8 @@ import ( authrservice "github.com/hobbyfarm/gargantua/services/authrsvc/v3/internal" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - "github.com/hobbyfarm/gargantua/v3/protos/rbac" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" ) var ( @@ -28,10 +28,10 @@ func main() { defer conn.Close() } - rbacClient := rbac.NewRbacSvcClient(connections[microservices.Rbac]) + rbacClient := rbacpb.NewRbacSvcClient(connections[microservices.Rbac]) gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) as := authrservice.NewGrpcAuthRServer(rbacClient) - authr.RegisterAuthRServer(gs, as) + authrpb.RegisterAuthRServer(gs, as) var wg sync.WaitGroup wg.Add(1) diff --git a/v3/services/coursesvc/Dockerfile b/v3/services/coursesvc/Dockerfile new file mode 100644 index 00000000..14bd2cfa --- /dev/null +++ b/v3/services/coursesvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/coursesvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/coursesvc/go.mod b/v3/services/coursesvc/go.mod new file mode 100644 index 00000000..a39f64a5 --- /dev/null +++ b/v3/services/coursesvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/coursesvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/coursesvc/go.sum b/v3/services/coursesvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/coursesvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/coursesvc/internal/courseservice.go b/v3/services/coursesvc/internal/courseservice.go new file mode 100644 index 00000000..24c42053 --- /dev/null +++ b/v3/services/coursesvc/internal/courseservice.go @@ -0,0 +1,486 @@ +package courseservice + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + "github.com/gorilla/mux" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" +) + +const ( + idIndex = "courseserver.hobbyfarm.io/id-index" + resourcePlural = rbac.ResourcePluralCourse +) + +type PreparedCourse struct { + Id string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Scenarios []string `json:"scenarios"` + Categories []string `json:"categories"` + VirtualMachines []map[string]string `json:"virtualmachines"` + KeepAliveDuration string `json:"keepalive_duration"` + PauseDuration string `json:"pause_duration"` + Pauseable bool `json:"pauseable"` + KeepVM bool `json:"keep_vm"` +} + +func convertToPreparedCourse(course *coursepb.Course) PreparedCourse { + return PreparedCourse{ + Id: course.GetId(), + Name: course.GetName(), + Description: course.GetDescription(), + Scenarios: course.GetScenarios(), + Categories: course.GetCategories(), + VirtualMachines: util.ConvertToStringMapSlice(course.GetVms()), + KeepAliveDuration: course.GetKeepaliveDuration(), + PauseDuration: course.GetPauseDuration(), + Pauseable: course.GetPausable(), + KeepVM: course.GetKeepVm(), + } +} + +func (c CourseServer) getPreparedCourseById(ctx context.Context, id string) (PreparedCourse, error) { + // load course from cache + course, err := c.internalCourseServer.GetCourse(ctx, &generalpb.GetRequest{Id: id, LoadFromCache: true}) + if err != nil { + return PreparedCourse{}, fmt.Errorf("error while retrieving course %s", hferrors.GetErrorMessage(err)) + } + + return convertToPreparedCourse(course), nil +} + +func (c CourseServer) ListFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + glog.Infof("Authr error: %s", err.Error()) + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list courses") + return + } + + tempCoursList, err := c.internalCourseServer.ListCourse(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error listing courses: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing courses") + return + } + tempCourses := tempCoursList.GetCourses() + + courses := make([]PreparedCourse, 0, len(tempCourses)) + for _, c := range tempCourses { + courses = append(courses, convertToPreparedCourse(c)) + } + + encodedCourses, err := json.Marshal(courses) + if err != nil { + glog.Errorf("error marshalling prepared courses: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing courses") + return + } + + util.ReturnHTTPContent(w, r, 200, "success", encodedCourses) + + glog.V(4).Infof("listed courses") +} + +func (c CourseServer) GetCourse(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to courses") + return + } + + vars := mux.Vars(r) + + courseId := vars["course_id"] + if len(courseId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no course id passed in") + return + } + + course, err := c.getPreparedCourseById(r.Context(), courseId) + if err != nil { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("error retrieving course: %v", err)) + return + } + + encodedCourse, err := json.Marshal(course) + if err != nil { + glog.Error(err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error preparing course") + return + } + + util.ReturnHTTPContent(w, r, 200, "success", encodedCourse) +} + +func (c CourseServer) CreateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create courses") + return + } + + name := r.PostFormValue("name") + if name == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") + return + } + + description := r.PostFormValue("description") + if description == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") + return + } + + keepaliveDuration := r.PostFormValue("keepalive_duration") + // keepaliveDuration is optional + + scenarios := r.PostFormValue("scenarios") + // scenarios are optional + + categories := r.PostFormValue("categories") + // categories are optional + + rawVirtualMachines := r.PostFormValue("virtualmachines") + // virtualmachines are optional + + pauseableRaw := r.PostFormValue("pauseable") + pauseable, err := strconv.ParseBool(pauseableRaw) + if err != nil { + glog.Errorf("error while parsing bool %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + pauseDuration := r.PostFormValue("pause_duration") + + keepVMRaw := r.PostFormValue("keep_vm") + keepVM, err := strconv.ParseBool(keepVMRaw) + if err != nil { + glog.Errorf("error while parsing bool: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + + courseId, err := c.internalCourseServer.CreateCourse(r.Context(), &coursepb.CreateCourseRequest{ + Name: name, + Description: description, + RawScenarios: scenarios, + RawCategories: categories, + RawVms: rawVirtualMachines, + KeepaliveDuration: keepaliveDuration, + PauseDuration: pauseDuration, + Pausable: pauseable, + KeepVm: keepVM, + }) + if err != nil { + statusErr := status.Convert(err) + if hferrors.IsGrpcParsingError(err) { + glog.Errorf("error while parsing: %s", statusErr.Message()) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + glog.Errorf("error creating course %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating course") + return + } + + util.ReturnHTTPMessage(w, r, 201, "created", courseId.GetId()) + glog.V(4).Infof("Created course %s", courseId.GetId()) +} + +func (c CourseServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update courses") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") + return + } + + name := r.PostFormValue("name") + description := r.PostFormValue("description") + scenarios := r.PostFormValue("scenarios") + categories := r.PostFormValue("categories") + virtualMachinesRaw := r.PostFormValue("virtualmachines") + keepaliveDuration := r.PostFormValue("keepalive_duration") + pauseDuration := r.PostFormValue("pause_duration") + pauseableRaw := r.PostFormValue("pauseable") + keepVMRaw := r.PostFormValue("keep_vm") + + var keepaliveWrapper *wrapperspb.StringValue + if keepaliveDuration != "" { + keepaliveWrapper = wrapperspb.String(keepaliveDuration) + } + + var pauseDurationWrapper *wrapperspb.StringValue + if pauseDuration != "" { + pauseDurationWrapper = wrapperspb.String(pauseDuration) + } + + var pauseable bool + if pauseableRaw != "" { + pauseable, err = strconv.ParseBool(pauseableRaw) + if err != nil { + glog.Errorf("error while parsing bool: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + } + + var keepVM bool + if keepVMRaw != "" { + keepVM, err = strconv.ParseBool(keepVMRaw) + if err != nil { + glog.Errorf("error while parsing bool: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + } + + _, err = c.internalCourseServer.UpdateCourse(r.Context(), &coursepb.UpdateCourseRequest{ + Id: id, + Name: name, + Description: description, + RawScenarios: scenarios, + RawCategories: categories, + RawVms: virtualMachinesRaw, + KeepaliveDuration: keepaliveWrapper, + PauseDuration: pauseDurationWrapper, + Pausable: wrapperspb.Bool(pauseable), + KeepVm: wrapperspb.Bool(keepVM), + }) + + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error attempting to update") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "") + glog.V(4).Infof("Updated course %s", id) +} + +func (c CourseServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbDelete)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to to delete courses") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") + return + } + + // when can we safely toDelete c course? + // 1. when there are no active scheduled events using the course + // 2. when there are no sessions using the course + + seList, err := c.scheduledEventClient.ListScheduledEvent(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error retrieving scheduledevent list: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") + return + } + + seInUse := util.FilterScheduledEvents(id, seList, util.FilterByCourse) + + sessList, err := c.sessionClient.ListSession(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error retrieving session list: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") + return + } + + sessInUse := util.FilterSessions(id, sessList, util.IsSessionOfCourse) + + var msg = "" + toDelete := true + + if len(seInUse) > 0 { + // cannot toDelete, in use. alert the user + msg += "In use by scheduled events:" + for _, se := range seInUse { + msg += " " + se.GetId() + } + toDelete = false + } + + if len(sessInUse) > 0 { + msg += "In use by sessions:" + for _, sess := range sessInUse { + msg += " " + sess.GetId() + } + toDelete = false + } + + if !toDelete { + util.ReturnHTTPMessage(w, r, 403, "badrequest", msg) + return + } + + _, err = c.internalCourseServer.DeleteCourse(r.Context(), &generalpb.ResourceId{Id: id}) + if err != nil { + glog.Errorf("error deleting course: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting course") + return + } + + util.ReturnHTTPMessage(w, r, 204, "deleted", "deleted successfully") + glog.V(4).Infof("deleted course: %s", id) +} + +func (c CourseServer) ListCoursesForAccesscode(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + vars := mux.Vars(r) + accessCode := vars["access_code"] + + if accessCode == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "access_code is missing") + return + } + + contains := false + for _, acc := range user.GetAccessCodes() { + if acc == accessCode { + contains = true + break + } + } + + if !contains { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios for this AccessCode") + return + } + + tmpAccesscode, err := c.acClient.GetAccessCodeWithOTACs(r.Context(), &generalpb.ResourceId{Id: accessCode}) + if err != nil { + glog.Errorf("error retrieving course ids for access code: %s %v", accessCode, err) + } + courseIds := util.UniqueStringSlice(tmpAccesscode.GetCourses()) + + var courses []PreparedCourse + for _, courseId := range courseIds { + course, err := c.getPreparedCourseById(r.Context(), courseId) + if err != nil { + glog.Errorf("error retrieving course %s", hferrors.GetErrorMessage(err)) + } else { + course.Scenarios = util.AppendDynamicScenariosByCategories( + r.Context(), + course.Scenarios, + course.Categories, + c.listScenarios, + ) + courses = append(courses, course) + } + } + + encodedCourses, err := json.Marshal(courses) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedCourses) +} + +func (c CourseServer) previewDynamicScenarios(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, c.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, c.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(rbac.ResourcePluralScenario, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to preview dynamic scenarios") + return + } + + categories := r.PostFormValue("categories") + categoriesSlice := make([]string, 0) + if categories != "" { + err = json.Unmarshal([]byte(categories), &categoriesSlice) + if err != nil { + glog.Errorf("error while unmarshalling categories %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + } + + scenarios := []string{} + + scenarios = util.AppendDynamicScenariosByCategories(r.Context(), scenarios, categoriesSlice, c.listScenarios) + + encodedScenarios, err := json.Marshal(scenarios) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) +} + +// We need this helper function because util.AppendDynamicScenariosByCategories expects a list function without grpc call options +func (c CourseServer) listScenarios(ctx context.Context, listOptions *generalpb.ListOptions) (*scenariopb.ListScenariosResponse, error) { + return c.scenarioClient.ListScenario(ctx, listOptions) +} diff --git a/v3/services/coursesvc/internal/crd.go b/v3/services/coursesvc/internal/crd.go new file mode 100644 index 00000000..e0291b48 --- /dev/null +++ b/v3/services/coursesvc/internal/crd.go @@ -0,0 +1,21 @@ +package courseservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// CourseCRDInstaller is a struct that can generate CRDs for scenarios. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type CourseCRDInstaller struct{} + +func (si CourseCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.Course{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.Course{}, nil) + }), + } +} diff --git a/v3/services/coursesvc/internal/grpc.go b/v3/services/coursesvc/internal/grpc.go new file mode 100644 index 00000000..b05e01ce --- /dev/null +++ b/v3/services/coursesvc/internal/grpc.go @@ -0,0 +1,267 @@ +package courseservice + +import ( + "context" + + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcCourseServer struct { + coursepb.UnimplementedCourseSvcServer + courseClient hfClientsetv1.CourseInterface + courseLister listersv1.CourseLister + courseSynced cache.InformerSynced +} + +func NewGrpcCourseServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcCourseServer { + return &GrpcCourseServer{ + courseClient: hfClientSet.HobbyfarmV1().Courses(util.GetReleaseNamespace()), + courseLister: hfInformerFactory.Hobbyfarm().V1().Courses().Lister(), + courseSynced: hfInformerFactory.Hobbyfarm().V1().Courses().Informer().HasSynced, + } +} + +func (c *GrpcCourseServer) CreateCourse(ctx context.Context, req *coursepb.CreateCourseRequest) (*generalpb.ResourceId, error) { + name := req.GetName() + description := req.GetDescription() + rawScenarios := req.GetRawScenarios() + rawCategories := req.GetRawCategories() + rawVirtualMachines := req.GetRawVms() + keepaliveDuration := req.GetKeepaliveDuration() + pauseDuration := req.GetPauseDuration() + pausable := req.GetPausable() + keepVm := req.GetKeepVm() + + requiredStringParams := map[string]string{ + "name": name, + "description": description, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + id := util.GenerateResourceName("c", name, 10) + + course := &hfv1.Course{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + }, + Spec: hfv1.CourseSpec{ + Name: name, + Description: description, + KeepAliveDuration: keepaliveDuration, + PauseDuration: pauseDuration, + Pauseable: pausable, + KeepVM: keepVm, + }, + } + + if rawScenarios != "" { + scenarios, err := util.GenericUnmarshal[[]string](rawScenarios, "rawScenarios") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "rawScenarios") + } + course.Spec.Scenarios = scenarios + } + if rawCategories != "" { + categories, err := util.GenericUnmarshal[[]string](rawCategories, "rawCategories") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "rawCategories") + } + course.Spec.Categories = categories + } + if rawVirtualMachines != "" { + vms, err := util.GenericUnmarshal[[]map[string]string](rawVirtualMachines, "rawVirtualMachines") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "rawVirtualMachines") + } + course.Spec.VirtualMachines = vms + } + + _, err := c.courseClient.Create(ctx, course, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: course.Name}, nil +} + +func (c *GrpcCourseServer) GetCourse(ctx context.Context, req *generalpb.GetRequest) (*coursepb.Course, error) { + course, err := util.GenericHfGetter(ctx, req, c.courseClient, c.courseLister.Courses(util.GetReleaseNamespace()), "course", c.courseSynced()) + if err != nil { + return &coursepb.Course{}, err + } + + vms := []*generalpb.StringMap{} + for _, vm := range course.Spec.VirtualMachines { + vms = append(vms, &generalpb.StringMap{Value: vm}) + } + + return &coursepb.Course{ + Id: course.Name, + Uid: string(course.UID), + Name: course.Spec.Name, + Description: course.Spec.Description, + Scenarios: course.Spec.Scenarios, + Categories: course.Spec.Categories, + Vms: vms, + KeepaliveDuration: course.Spec.KeepAliveDuration, + PauseDuration: course.Spec.PauseDuration, + Pausable: course.Spec.Pauseable, + KeepVm: course.Spec.KeepVM, + }, nil +} + +func (s *GrpcCourseServer) UpdateCourse(ctx context.Context, req *coursepb.UpdateCourseRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + name := req.GetName() + description := req.GetDescription() + rawScenarios := req.GetRawScenarios() + rawCategories := req.GetRawCategories() + rawVirtualMachines := req.GetRawVms() + keepaliveDuration := req.GetKeepaliveDuration() + pauseDuration := req.GetPauseDuration() + pausable := req.GetPausable() + keepVm := req.GetKeepVm() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + course, err := s.courseClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving course %s", + req, + req.GetId(), + ) + } + if name != "" { + course.Spec.Name = name + } + if description != "" { + course.Spec.Description = description + } + if keepaliveDuration != nil { + course.Spec.KeepAliveDuration = keepaliveDuration.GetValue() + } + if pauseDuration != nil { + course.Spec.PauseDuration = pauseDuration.GetValue() + } + if pausable != nil { + course.Spec.Pauseable = pausable.GetValue() + } + if keepVm != nil { + course.Spec.KeepVM = keepVm.GetValue() + } + if rawScenarios != "" { + scenarios, err := util.GenericUnmarshal[[]string](rawScenarios, "rawScenarios") + if err != nil { + return hferrors.GrpcParsingError(req, "rawScenarios") + } + course.Spec.Scenarios = scenarios + } + if rawCategories != "" { + categories, err := util.GenericUnmarshal[[]string](rawCategories, "rawCategories") + if err != nil { + return hferrors.GrpcParsingError(req, "rawCategories") + } + course.Spec.Categories = categories + } + if rawVirtualMachines != "" { + vms, err := util.GenericUnmarshal[[]map[string]string](rawVirtualMachines, "rawVirtualMachines") + if err != nil { + return hferrors.GrpcParsingError(req, "rawVirtualMachines") + } + course.Spec.VirtualMachines = vms + } + + _, updateErr := s.courseClient.Update(ctx, course, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcCourseServer) DeleteCourse(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.courseClient, "course") +} + +func (s *GrpcCourseServer) DeleteCollectionCourse(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.courseClient, "courses") +} + +func (s *GrpcCourseServer) ListCourse(ctx context.Context, listOptions *generalpb.ListOptions) (*coursepb.ListCoursesResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var courses []hfv1.Course + var err error + if !doLoadFromCache { + var courseList *hfv1.CourseList + courseList, err = util.ListByHfClient(ctx, listOptions, s.courseClient, "courses") + if err == nil { + courses = courseList.Items + } + } else { + courses, err = util.ListByCache(listOptions, s.courseLister, "courses", s.courseSynced()) + } + if err != nil { + glog.Error(err) + return &coursepb.ListCoursesResponse{}, err + } + + preparedCourses := []*coursepb.Course{} + + for _, course := range courses { + + vms := []*generalpb.StringMap{} + for _, vm := range course.Spec.VirtualMachines { + vms = append(vms, &generalpb.StringMap{Value: vm}) + } + + preparedCourses = append(preparedCourses, &coursepb.Course{ + Id: course.Name, + Uid: string(course.UID), + Name: course.Spec.Name, + Description: course.Spec.Description, + Scenarios: course.Spec.Scenarios, + Categories: course.Spec.Categories, + Vms: vms, + KeepaliveDuration: course.Spec.KeepAliveDuration, + PauseDuration: course.Spec.PauseDuration, + Pausable: course.Spec.Pauseable, + KeepVm: course.Spec.KeepVM, + }) + } + + return &coursepb.ListCoursesResponse{Courses: preparedCourses}, nil +} diff --git a/v3/services/coursesvc/internal/server.go b/v3/services/coursesvc/internal/server.go new file mode 100644 index 00000000..7518de65 --- /dev/null +++ b/v3/services/coursesvc/internal/server.go @@ -0,0 +1,52 @@ +package courseservice + +import ( + "github.com/gorilla/mux" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" +) + +type CourseServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + acClient accesscodepb.AccessCodeSvcClient + scenarioClient scenariopb.ScenarioSvcClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + sessionClient sessionpb.SessionSvcClient + internalCourseServer *GrpcCourseServer +} + +func NewCourseServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + acClient accesscodepb.AccessCodeSvcClient, + scenarioClient scenariopb.ScenarioSvcClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + sessionClient sessionpb.SessionSvcClient, + internalCourseServer *GrpcCourseServer, +) CourseServer { + return CourseServer{ + authnClient: authnClient, + authrClient: authrClient, + acClient: acClient, + scenarioClient: scenarioClient, + scheduledEventClient: scheduledEventClient, + sessionClient: sessionClient, + internalCourseServer: internalCourseServer, + } +} + +func (c CourseServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/course/list/{access_code}", c.ListCoursesForAccesscode).Methods("GET") + r.HandleFunc("/course/{course_id}", c.GetCourse).Methods("GET") + r.HandleFunc("/a/course/list", c.ListFunc).Methods("GET") + r.HandleFunc("/a/course/new", c.CreateFunc).Methods("POST") + r.HandleFunc("/a/course/{course_id}", c.GetCourse).Methods("GET") + r.HandleFunc("/a/course/{id}", c.UpdateFunc).Methods("PUT") + r.HandleFunc("/a/course/{id}", c.DeleteFunc).Methods("DELETE") + r.HandleFunc("/a/course/previewDynamicScenarios", c.previewDynamicScenarios).Methods("POST") +} diff --git a/v3/services/coursesvc/main.go b/v3/services/coursesvc/main.go new file mode 100644 index 00000000..c53a6c60 --- /dev/null +++ b/v3/services/coursesvc/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + courseservice "github.com/hobbyfarm/gargantua/services/coursesvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(courseservice.CourseCRDInstaller{}, cfg, "course") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.AccessCode, + microservices.Scenario, + microservices.ScheduledEvent, + microservices.Session, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + acClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + scenarioClient := scenariopb.NewScenarioSvcClient(connections[microservices.Scenario]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + cs := courseservice.NewGrpcCourseServer(hfClient, hfInformerFactory) + coursepb.RegisterCourseSvcServer(gs, cs) + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + courseServer := courseservice.NewCourseServer( + authnClient, + authrClient, + acClient, + scenarioClient, + scheduledEventClient, + sessionClient, + cs, + ) + microservices.StartAPIServer(courseServer) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/dbconfigsvc/Dockerfile b/v3/services/dbconfigsvc/Dockerfile new file mode 100644 index 00000000..e3e9fe7b --- /dev/null +++ b/v3/services/dbconfigsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/dbconfigsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/dbconfigsvc/go.mod b/v3/services/dbconfigsvc/go.mod new file mode 100644 index 00000000..a38bff37 --- /dev/null +++ b/v3/services/dbconfigsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/dbconfigsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/dbconfigsvc/go.sum b/v3/services/dbconfigsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/dbconfigsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/dbconfigsvc/internal/crd.go b/v3/services/dbconfigsvc/internal/crd.go new file mode 100644 index 00000000..5818a0d7 --- /dev/null +++ b/v3/services/dbconfigsvc/internal/crd.go @@ -0,0 +1,21 @@ +package dbconfigservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// DBConfigCRDInstaller is a struct that can generate CRDs for dynamic bind configurations. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type DBConfigCRDInstaller struct{} + +func (dbci DBConfigCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.DynamicBindConfiguration{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.DynamicBindConfiguration{}, nil) + }), + } +} diff --git a/v3/services/dbconfigsvc/internal/grpc.go b/v3/services/dbconfigsvc/internal/grpc.go new file mode 100644 index 00000000..ccb78b46 --- /dev/null +++ b/v3/services/dbconfigsvc/internal/grpc.go @@ -0,0 +1,220 @@ +package dbconfigservice + +import ( + "context" + "fmt" + "math/rand" + "os" + "strings" + + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcDynamicBindConfigurationServer struct { + dbconfigpb.UnimplementedDynamicBindConfigSvcServer + dbConfigClient hfClientsetv1.DynamicBindConfigurationInterface + dbConfigLister listersv1.DynamicBindConfigurationLister + dbConfigSynced cache.InformerSynced +} + +var baseNameDynamicPrefix string + +func init() { + bndp := os.Getenv("HF_BASENAME_DYNAMIC_PREFIX") + if bndp == "" { + baseNameDynamicPrefix = "dynamic" + } else { + baseNameDynamicPrefix = bndp + } +} + +func NewGrpcDynamicBindConfigurationServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcDynamicBindConfigurationServer { + return &GrpcDynamicBindConfigurationServer{ + dbConfigClient: hfClientSet.HobbyfarmV1().DynamicBindConfigurations(util.GetReleaseNamespace()), + dbConfigLister: hfInformerFactory.Hobbyfarm().V1().DynamicBindConfigurations().Lister(), + dbConfigSynced: hfInformerFactory.Hobbyfarm().V1().DynamicBindConfigurations().Informer().HasSynced, + } +} + +func (s *GrpcDynamicBindConfigurationServer) CreateDynamicBindConfig(ctx context.Context, req *dbconfigpb.CreateDynamicBindConfigRequest) (*emptypb.Empty, error) { + // create the dynamic bind configurations + dbcRand := fmt.Sprintf("%s-%08x", baseNameDynamicPrefix, rand.Uint32()) + dbcName := strings.Join([]string{"se", req.GetSeName(), "dbc", dbcRand}, "-") + seName := req.GetSeName() + envName := req.GetEnvName() + restrictedBind := req.GetRestrictedBind() + restrictedBindValue := req.GetRestrictedBindValue() + seUid := types.UID(req.GetSeUid()) + burstCapacity := req.GetBurstCountCapacity() + dbc := &hfv1.DynamicBindConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: dbcName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: "ScheduledEvent", + Name: seName, + UID: seUid, + }, + }, + Labels: map[string]string{ + hflabels.EnvironmentLabel: envName, + hflabels.ScheduledEventLabel: seName, + "restrictedbind": fmt.Sprintf("%t", restrictedBind), + }, + }, + Spec: hfv1.DynamicBindConfigurationSpec{ + Environment: envName, + BaseName: dbcRand, + BurstCountCapacity: util.ConvertIntMap[uint32, int](burstCapacity), + }, + } + + if restrictedBind { + dbc.Spec.RestrictedBind = restrictedBind + dbc.Spec.RestrictedBindValue = restrictedBindValue + dbc.ObjectMeta.Labels["restrictedbindvalue"] = restrictedBindValue + } + + _, err := s.dbConfigClient.Create(ctx, dbc, metav1.CreateOptions{}) + if err != nil { + return &emptypb.Empty{}, err + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcDynamicBindConfigurationServer) GetDynamicBindConfig(ctx context.Context, req *generalpb.GetRequest) (*dbconfigpb.DynamicBindConfig, error) { + dbc, err := util.GenericHfGetter(ctx, req, s.dbConfigClient, s.dbConfigLister.DynamicBindConfigurations(util.GetReleaseNamespace()), "dynamic bind configuation", s.dbConfigSynced()) + if err != nil { + return &dbconfigpb.DynamicBindConfig{}, err + } + + return &dbconfigpb.DynamicBindConfig{ + Id: dbc.Name, + Uid: string(dbc.UID), + Environment: dbc.Spec.Environment, + RestrictedBind: dbc.Spec.RestrictedBind, + RestrictedBindValue: dbc.Spec.RestrictedBindValue, + BurstCountCapacity: util.ConvertIntMap[int, uint32](dbc.Spec.BurstCountCapacity), + Labels: dbc.Labels, + }, nil +} + +func (s *GrpcDynamicBindConfigurationServer) UpdateDynamicBindConfig(ctx context.Context, req *dbconfigpb.UpdateDynamicBindConfigRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + environment := req.GetEnvironment() + restrictedBind := req.GetRestrictedBind() + burstCountCapacity := req.GetBurstCountCapacity() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + dbc, err := s.dbConfigClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving dynamic bind configuration %s", + req, + req.GetId(), + ) + } + + if environment != "" { + dbc.Spec.Environment = environment + dbc.ObjectMeta.Labels[hflabels.EnvironmentLabel] = environment + } + if restrictedBind != nil { + dbc.Spec.RestrictedBind = restrictedBind.Value + dbc.ObjectMeta.Labels["restrictedbind"] = fmt.Sprintf("%t", restrictedBind.Value) + } + // if restricted bind is disabled, make sure that restricted bind value is also empty... + // else update restricted bind value to the id of scheduled event (if it is not already set) + if !dbc.Spec.RestrictedBind { + dbc.Spec.RestrictedBindValue = "" + dbc.ObjectMeta.Labels["restrictedbindvalue"] = "" + } else if dbc.Spec.RestrictedBindValue == "" { + dbc.Spec.RestrictedBindValue = dbc.ObjectMeta.Labels[hflabels.ScheduledEventLabel] + dbc.ObjectMeta.Labels["restrictedbindvalue"] = dbc.ObjectMeta.Labels[hflabels.ScheduledEventLabel] + } + + if len(burstCountCapacity) > 0 { + dbc.Spec.BurstCountCapacity = util.ConvertIntMap[uint32, int](burstCountCapacity) + } + + _, updateErr := s.dbConfigClient.Update(ctx, dbc, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcDynamicBindConfigurationServer) DeleteDynamicBindConfig(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.dbConfigClient, "dynamic bind configuration") +} + +func (s *GrpcDynamicBindConfigurationServer) DeleteCollectionDynamicBindConfig(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.dbConfigClient, "dynamic bind configurations") +} + +func (s *GrpcDynamicBindConfigurationServer) ListDynamicBindConfig(ctx context.Context, listOptions *generalpb.ListOptions) (*dbconfigpb.ListDynamicBindConfigsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var dbConfigs []hfv1.DynamicBindConfiguration + var err error + if !doLoadFromCache { + var dbConfigList *hfv1.DynamicBindConfigurationList + dbConfigList, err = util.ListByHfClient(ctx, listOptions, s.dbConfigClient, "dynamic bind configurations") + if err == nil { + dbConfigs = dbConfigList.Items + } + } else { + dbConfigs, err = util.ListByCache(listOptions, s.dbConfigLister, "dynamic bind configurations", s.dbConfigSynced()) + } + if err != nil { + glog.Error(err) + return &dbconfigpb.ListDynamicBindConfigsResponse{}, err + } + + preparedDbcs := []*dbconfigpb.DynamicBindConfig{} + + for _, dbc := range dbConfigs { + preparedDbcs = append(preparedDbcs, &dbconfigpb.DynamicBindConfig{ + Id: dbc.Name, + Uid: string(dbc.UID), + Environment: dbc.Spec.Environment, + BurstCountCapacity: util.ConvertIntMap[int, uint32](dbc.Spec.BurstCountCapacity), + RestrictedBind: dbc.Spec.RestrictedBind, + RestrictedBindValue: dbc.Spec.RestrictedBindValue, + Labels: dbc.Labels, + }) + } + + return &dbconfigpb.ListDynamicBindConfigsResponse{DbConfig: preparedDbcs}, nil +} diff --git a/v3/services/dbconfigsvc/main.go b/v3/services/dbconfigsvc/main.go new file mode 100644 index 00000000..4e0bacac --- /dev/null +++ b/v3/services/dbconfigsvc/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + dbconfigservice "github.com/hobbyfarm/gargantua/services/dbconfigsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(dbconfigservice.DBConfigCRDInstaller{}, cfg, "dynamic bind configuration") + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ds := dbconfigservice.NewGrpcDynamicBindConfigurationServer(hfClient, hfInformerFactory) + dbconfigpb.RegisterDynamicBindConfigSvcServer(gs, ds) + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/environmentsvc/Dockerfile b/v3/services/environmentsvc/Dockerfile new file mode 100644 index 00000000..9312e66f --- /dev/null +++ b/v3/services/environmentsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/environmentsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/environmentsvc/go.mod b/v3/services/environmentsvc/go.mod new file mode 100644 index 00000000..9bad525c --- /dev/null +++ b/v3/services/environmentsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/environmentsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/environmentsvc/go.sum b/v3/services/environmentsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/environmentsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/environmentsvc/internal/crd.go b/v3/services/environmentsvc/internal/crd.go new file mode 100644 index 00000000..5173b05e --- /dev/null +++ b/v3/services/environmentsvc/internal/crd.go @@ -0,0 +1,21 @@ +package environmentservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// EnvironmentCRDInstaller is a struct that can generate CRDs for environments. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type EnvironmentCRDInstaller struct{} + +func (ei EnvironmentCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.Environment{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.Environment{}, nil) + }), + } +} diff --git a/v3/services/environmentsvc/internal/environmentservice.go b/v3/services/environmentsvc/internal/environmentservice.go new file mode 100644 index 00000000..c9746b7d --- /dev/null +++ b/v3/services/environmentsvc/internal/environmentservice.go @@ -0,0 +1,372 @@ +package environmentservice + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + "github.com/gorilla/mux" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" +) + +const ( + resourcePlural = rbac.ResourcePluralEnvironment +) + +type PreparedAvailableCount struct { + AvailableCount map[string]uint32 `json:"available_count"` +} + +type PreparedEnvironment struct { + Name string `json:"name"` + DisplayName string `json:"display_name"` + DNSSuffix string `json:"dnssuffix"` + Provider string `json:"provider"` // aws,vsphere,azure,custom ;) + TemplateMapping map[string]map[string]string `json:"template_mapping"` // lol + EnvironmentSpecifics map[string]string `json:"environment_specifics"` + IPTranslationMap map[string]string `json:"ip_translation_map"` + WsEndpoint string `json:"ws_endpoint"` + CountCapacity map[string]uint32 `json:"count_capacity"` +} + +type PreparedListEnvironment struct { + Name string `json:"name"` + DisplayName string `json:"display_name"` + Provider string `json:"provider"` + TemplateMapping map[string]map[string]string `json:"template_mapping"` +} + +func (e EnvironmentServer) GetFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, e.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get environment") + return + } + + vars := mux.Vars(r) + + environmentId := vars["id"] + + if len(environmentId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no environment id passed in") + return + } + + environment, err := e.internalEnvironmentServer.GetEnvironment(r.Context(), &generalpb.GetRequest{Id: environmentId}) + if err != nil { + glog.Errorf("error while retrieving environment: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + returnMsg := fmt.Sprintf("environment with id %s not found", environmentId) + util.ReturnHTTPMessage(w, r, 404, "error", returnMsg) + return + } + util.ReturnHTTPMessage(w, r, 500, "error", "internal error while retrieving environment") + return + } + + preparedEnvironment := PreparedEnvironment{ + Name: environment.GetId(), + DisplayName: environment.GetDisplayName(), + DNSSuffix: environment.GetDnssuffix(), + Provider: environment.GetProvider(), + TemplateMapping: util.ConvertMapStruct(environment.GetTemplateMapping(), util.GetRawStringMap), + EnvironmentSpecifics: environment.GetEnvironmentSpecifics(), + IPTranslationMap: environment.GetIpTranslationMap(), + WsEndpoint: environment.GetWsEndpoint(), + CountCapacity: environment.GetCountCapacity(), + } + + encodedEnvironment, err := json.Marshal(preparedEnvironment) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironment) + + glog.V(2).Infof("retrieved environment %s", environment.GetId()) +} + +func (e EnvironmentServer) ListFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, e.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list environments") + return + } + + environmentList, err := e.internalEnvironmentServer.ListEnvironment(r.Context(), &generalpb.ListOptions{}) + + if err != nil { + glog.Errorf("error while listing all environments: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error listing all environments") + return + } + + preparedEnvironments := []PreparedListEnvironment{} // must be declared this way so as to JSON marshal into [] instead of null + + for _, e := range environmentList.GetEnvironments() { + keys := make(map[string]map[string]string) + for k := range util.ConvertMapStruct(e.GetTemplateMapping(), util.GetRawStringMap) { + keys[k] = map[string]string{} // reset template mapping entries -> @TODO: Figure out why? + } + preparedEnvironments = append(preparedEnvironments, PreparedListEnvironment{e.GetId(), e.GetDisplayName(), e.GetProvider(), keys}) + } + + encodedEnvironments, err := json.Marshal(preparedEnvironments) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironments) + + glog.V(2).Infof("retrieved list of all environments") +} + +func (e EnvironmentServer) CreateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, e.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create environments") + return + } + + displayName := r.PostFormValue("display_name") + if displayName == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no display_name passed in") + return + } + + dnssuffix := r.PostFormValue("dnssuffix") + // dnssuffix optional so no validation performed + + provider := r.PostFormValue("provider") + if provider == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no provider passed in") + return + } + + templateMapping := r.PostFormValue("template_mapping") + if templateMapping == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no template_mapping passed in") + return + } + + environmentSpecifics := r.PostFormValue("environment_specifics") + if environmentSpecifics == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no environment_specifics passed in") + return + } + + countCapacity := r.PostFormValue("count_capacity") + if environmentSpecifics == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no count_capacity passed in") + return + } + + ipTranslationMap := r.PostFormValue("ip_translation_map") + if ipTranslationMap == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ip_translation_map passed in") + return + } + + wsEndpoint := r.PostFormValue("ws_endpoint") + if wsEndpoint == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ws_endpoint passed in") + return + } + + environmentId, err := e.internalEnvironmentServer.CreateEnvironment(r.Context(), &environmentpb.CreateEnvironmentRequest{ + DisplayName: displayName, + Dnssuffix: dnssuffix, + Provider: provider, + TemplateMapping: templateMapping, + EnvironmentSpecifics: environmentSpecifics, + IpTranslationMap: ipTranslationMap, + WsEndpoint: wsEndpoint, + CountCapacity: countCapacity, + }) + + if err != nil { + glog.Errorf("error creating environment: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating environment") + return + } + + util.ReturnHTTPMessage(w, r, 201, "created", environmentId.GetId()) +} + +func (e EnvironmentServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, e.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, e.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update environment") + return + } + + vars := mux.Vars(r) + + environmentId := vars["id"] + if len(environmentId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no environment id passed in") + return + } + + displayName := r.PostFormValue("display_name") + dnssuffix := r.PostFormValue("dnssuffix") + provider := r.PostFormValue("provider") + templateMapping := r.PostFormValue("template_mapping") + environmentSpecifics := r.PostFormValue("environment_specifics") + ipTranslationMap := r.PostFormValue("ip_translation_map") + wsEndpoint := r.PostFormValue("ws_endpoint") + countCapacity := r.PostFormValue("count_capacity") + + _, err = e.internalEnvironmentServer.UpdateEnvironment(r.Context(), &environmentpb.UpdateEnvironmentRequest{ + Id: environmentId, + DisplayName: displayName, + Dnssuffix: wrapperspb.String(dnssuffix), + Provider: provider, + TemplateMapping: templateMapping, + EnvironmentSpecifics: environmentSpecifics, + IpTranslationMap: ipTranslationMap, + WsEndpoint: wsEndpoint, + CountCapacity: countCapacity, + }) + + if err != nil { + glog.Errorf("error while updating environment: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcParsingError(err) { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error parsing") + return + } + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error attempting to update") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "") +} + +func (e EnvironmentServer) PostEnvironmentAvailableFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, e.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.Authorize(r, e.authrClient, impersonatedUserId, []*authrpb.Permission{ + rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList), + rbac.HobbyfarmPermission(rbac.ResourcePluralVMTemplate, rbac.VerbList), + }, rbac.OperatorAND) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list environments") + return + } + + vars := mux.Vars(r) + + start := r.PostFormValue("start") + end := r.PostFormValue("end") + if start == "" || end == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "start or end time not provided") + return + } + + environmentId := vars["environment_id"] + + if len(environmentId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no environment id passed in") + return + } + + environment, err := e.internalEnvironmentServer.GetEnvironment(r.Context(), &generalpb.GetRequest{Id: environmentId}) + if err != nil { + glog.Errorf("error while retrieving environment: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + returnMsg := fmt.Sprintf("environment with id %s not found", environmentId) + util.ReturnHTTPMessage(w, r, 404, "error", returnMsg) + return + } + util.ReturnHTTPMessage(w, r, 500, "error", "internal error while retrieving environment") + return + } + + if err != nil { + glog.Errorf("error while retrieving environment %v", err) + util.ReturnHTTPMessage(w, r, 500, "error", "no environment found") + return + } + max, err := e.maxAvailableDuringPeriod(environmentId, start, end, r.Context()) + if err != nil { + glog.Errorf("error while getting max available count: %v", err) + util.ReturnHTTPMessage(w, r, 500, "error", "error getting max available vms for environment") + return + } + + encodedEnvironment, err := json.Marshal(max) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedEnvironment) + + glog.V(2).Infof("retrieved max available count in environment %s", environment.GetId()) +} + +func (e EnvironmentServer) maxAvailableDuringPeriod(environment string, startString string, endString string, ctx context.Context) (PreparedAvailableCount, error) { + _, maximumVirtualMachineCount, err := util.VirtualMachinesUsedDuringPeriod(e.scheduledEventClient, environment, startString, endString, ctx) + + if err != nil { + return PreparedAvailableCount{}, err + } + + envObj, err := e.internalEnvironmentServer.GetEnvironment(ctx, &generalpb.GetRequest{Id: environment}) + if err != nil { + return PreparedAvailableCount{}, fmt.Errorf("error retrieving environment %v", err) + } + + max := PreparedAvailableCount{} + max.AvailableCount = make(map[string]uint32) + for k, v := range envObj.GetCountCapacity() { + max.AvailableCount[k] = v + } + for vmt, count := range maximumVirtualMachineCount { + if vmtCap, ok := envObj.GetCountCapacity()[vmt]; ok { + max.AvailableCount[vmt] = vmtCap - count + } else { + glog.Errorf("Error looking for maximum count capacity of virtual machine template %s", vmt) + max.AvailableCount[vmt] = 0 + } + } + return max, nil +} diff --git a/v3/services/environmentsvc/internal/grpc.go b/v3/services/environmentsvc/internal/grpc.go new file mode 100644 index 00000000..9d3fcd4e --- /dev/null +++ b/v3/services/environmentsvc/internal/grpc.go @@ -0,0 +1,275 @@ +package environmentservice + +import ( + "context" + "crypto/sha256" + "encoding/base32" + "strings" + "time" + + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcEnvironmentServer struct { + environmentpb.UnimplementedEnvironmentSvcServer + environmentClient hfClientsetv1.EnvironmentInterface + environmentLister listersv1.EnvironmentLister + environmentSynced cache.InformerSynced +} + +func NewGrpcEnvironmentServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcEnvironmentServer { + return &GrpcEnvironmentServer{ + environmentClient: hfClientSet.HobbyfarmV1().Environments(util.GetReleaseNamespace()), + environmentLister: hfInformerFactory.Hobbyfarm().V1().Environments().Lister(), + environmentSynced: hfInformerFactory.Hobbyfarm().V1().Environments().Informer().HasSynced, + } +} + +func (s *GrpcEnvironmentServer) CreateEnvironment(ctx context.Context, req *environmentpb.CreateEnvironmentRequest) (*generalpb.ResourceId, error) { + displayName := req.GetDisplayName() + dnsSuffix := req.GetDnssuffix() // optional + provider := req.GetProvider() + templateMappingRaw := req.GetTemplateMapping() + environmentSpecificsRaw := req.GetEnvironmentSpecifics() + ipTranslationMapRaw := req.GetIpTranslationMap() + wsEndpoint := req.GetWsEndpoint() + countCapacityRaw := req.GetCountCapacity() + + requiredStringParams := map[string]string{ + "displayName": displayName, + "provider": provider, + "templateMapping": templateMappingRaw, + "environmentSpecifics": environmentSpecificsRaw, + "ipTranslationMap": ipTranslationMapRaw, + "wsEndpoint": wsEndpoint, + "countCapacity": countCapacityRaw, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + templateMapping, err := util.GenericUnmarshal[map[string]map[string]string](templateMappingRaw, "templateMapping") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "templateMapping") + } + countCapacity, err := util.GenericUnmarshal[map[string]int](countCapacityRaw, "countCapacity") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "countCapacity") + } + environmentSpecifics, err := util.GenericUnmarshal[map[string]string](environmentSpecificsRaw, "environmentSpecifics") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "environmentSpecifics") + } + ipTranslationMap, err := util.GenericUnmarshal[map[string]string](ipTranslationMapRaw, "ipTranslationMap") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "ipTranslationMap") + } + + hasher := sha256.New() + hasher.Write([]byte(time.Now().String())) // generate random name + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + id := "env-" + strings.ToLower(sha) + + environment := &hfv1.Environment{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + }, + Spec: hfv1.EnvironmentSpec{ + DisplayName: displayName, + DNSSuffix: dnsSuffix, + Provider: provider, + TemplateMapping: templateMapping, + EnvironmentSpecifics: environmentSpecifics, + IPTranslationMap: ipTranslationMap, + WsEndpoint: wsEndpoint, + CountCapacity: countCapacity, + }, + } + + _, err = s.environmentClient.Create(ctx, environment, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: id}, nil +} + +func (s *GrpcEnvironmentServer) GetEnvironment(ctx context.Context, req *generalpb.GetRequest) (*environmentpb.Environment, error) { + environment, err := util.GenericHfGetter(ctx, req, s.environmentClient, s.environmentLister.Environments(util.GetReleaseNamespace()), "environment", s.environmentSynced()) + if err != nil { + return &environmentpb.Environment{}, err + } + + templateMapping := make(map[string]*generalpb.StringMap) + for templateName, keyValueMap := range environment.Spec.TemplateMapping { + templateMapping[templateName] = &generalpb.StringMap{Value: keyValueMap} + } + + return &environmentpb.Environment{ + Id: environment.Name, + Uid: string(environment.UID), + DisplayName: environment.Spec.DisplayName, + Dnssuffix: environment.Spec.DNSSuffix, + Provider: environment.Spec.Provider, + TemplateMapping: templateMapping, + EnvironmentSpecifics: environment.Spec.EnvironmentSpecifics, + IpTranslationMap: environment.Spec.IPTranslationMap, + WsEndpoint: environment.Spec.WsEndpoint, + CountCapacity: util.ConvertIntMap[int, uint32](environment.Spec.CountCapacity), + Annotations: environment.Annotations, + }, nil +} + +func (s *GrpcEnvironmentServer) UpdateEnvironment(ctx context.Context, req *environmentpb.UpdateEnvironmentRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + displayName := req.GetDisplayName() + dnsSuffix := req.GetDnssuffix() // optional + provider := req.GetProvider() + templateMappingRaw := req.GetTemplateMapping() + environmentSpecificsRaw := req.GetEnvironmentSpecifics() + ipTranslationMapRaw := req.GetIpTranslationMap() + wsEndpoint := req.GetWsEndpoint() + countCapacityRaw := req.GetCountCapacity() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + environment, err := s.environmentClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving environment %s", + req, + req.GetId(), + ) + } + if displayName != "" { + environment.Spec.DisplayName = displayName + } + if dnsSuffix != nil { + environment.Spec.DNSSuffix = dnsSuffix.Value + } + if provider != "" { + environment.Spec.Provider = provider + } + if wsEndpoint != "" { + environment.Spec.WsEndpoint = wsEndpoint + } + if templateMappingRaw != "" { + templateMapping, err := util.GenericUnmarshal[map[string]map[string]string](templateMappingRaw, "templateMapping") + if err != nil { + return hferrors.GrpcParsingError(req, "templateMapping") + } + environment.Spec.TemplateMapping = templateMapping + } + if environmentSpecificsRaw != "" { + environmentSpecifics, err := util.GenericUnmarshal[map[string]string](environmentSpecificsRaw, "environmentSpecifics") + if err != nil { + return hferrors.GrpcParsingError(req, "environmentSpecifics") + } + environment.Spec.EnvironmentSpecifics = environmentSpecifics + } + if ipTranslationMapRaw != "" { + ipTranslationMap, err := util.GenericUnmarshal[map[string]string](ipTranslationMapRaw, "ipTranslationMap") + if err != nil { + return hferrors.GrpcParsingError(req, "ipTranslationMap") + } + environment.Spec.IPTranslationMap = ipTranslationMap + } + if countCapacityRaw != "" { + countCapacity, err := util.GenericUnmarshal[map[string]int](countCapacityRaw, "countCapacity") + if err != nil { + return hferrors.GrpcParsingError(req, "countCapacity") + } + environment.Spec.CountCapacity = countCapacity + } + + _, updateErr := s.environmentClient.Update(ctx, environment, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcEnvironmentServer) DeleteEnvironment(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.environmentClient, "environment") +} + +func (s *GrpcEnvironmentServer) DeleteCollectionEnvironment(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.environmentClient, "environments") +} + +func (s *GrpcEnvironmentServer) ListEnvironment(ctx context.Context, listOptions *generalpb.ListOptions) (*environmentpb.ListEnvironmentsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var enviroments []hfv1.Environment + var err error + if !doLoadFromCache { + var enviromentList *hfv1.EnvironmentList + enviromentList, err = util.ListByHfClient(ctx, listOptions, s.environmentClient, "environments") + if err == nil { + enviroments = enviromentList.Items + } + } else { + enviroments, err = util.ListByCache(listOptions, s.environmentLister, "environments", s.environmentSynced()) + } + if err != nil { + glog.Error(err) + return &environmentpb.ListEnvironmentsResponse{}, err + } + + preparedEnvironments := []*environmentpb.Environment{} + + for _, environment := range enviroments { + + templateMapping := make(map[string]*generalpb.StringMap) + for templateName, keyValueMap := range environment.Spec.TemplateMapping { + templateMapping[templateName] = &generalpb.StringMap{Value: keyValueMap} + } + + preparedEnvironments = append(preparedEnvironments, &environmentpb.Environment{ + Id: environment.Name, + Uid: string(environment.UID), + DisplayName: environment.Spec.DisplayName, + Dnssuffix: environment.Spec.DNSSuffix, + Provider: environment.Spec.Provider, + TemplateMapping: templateMapping, + EnvironmentSpecifics: environment.Spec.EnvironmentSpecifics, + IpTranslationMap: environment.Spec.IPTranslationMap, + WsEndpoint: environment.Spec.WsEndpoint, + CountCapacity: util.ConvertIntMap[int, uint32](environment.Spec.CountCapacity), + Annotations: environment.Annotations, + }) + } + + return &environmentpb.ListEnvironmentsResponse{Environments: preparedEnvironments}, nil +} diff --git a/v3/services/environmentsvc/internal/server.go b/v3/services/environmentsvc/internal/server.go new file mode 100644 index 00000000..7d57acf0 --- /dev/null +++ b/v3/services/environmentsvc/internal/server.go @@ -0,0 +1,39 @@ +package environmentservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" +) + +type EnvironmentServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + internalEnvironmentServer *GrpcEnvironmentServer +} + +func NewEnvironmentServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + internalEnvironmentServer *GrpcEnvironmentServer, +) EnvironmentServer { + return EnvironmentServer{ + authnClient: authnClient, + authrClient: authrClient, + scheduledEventClient: scheduledEventClient, + internalEnvironmentServer: internalEnvironmentServer, + } +} + +func (e EnvironmentServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/a/environment/list", e.ListFunc).Methods("GET") + r.HandleFunc("/a/environment/{id}", e.GetFunc).Methods("GET") + r.HandleFunc("/a/environment/create", e.CreateFunc).Methods("POST") + r.HandleFunc("/a/environment/{id}/update", e.UpdateFunc).Methods("PUT") + r.HandleFunc("/a/environment/{environment_id}/available", e.PostEnvironmentAvailableFunc).Methods("POST") + glog.V(2).Infof("set up routes for environment server") +} diff --git a/v3/services/environmentsvc/main.go b/v3/services/environmentsvc/main.go new file mode 100644 index 00000000..7506021e --- /dev/null +++ b/v3/services/environmentsvc/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + environmentservice "github.com/hobbyfarm/gargantua/services/environmentsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(environmentservice.EnvironmentCRDInstaller{}, cfg, "environment") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.ScheduledEvent, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + es := environmentservice.NewGrpcEnvironmentServer(hfClient, hfInformerFactory) + environmentpb.RegisterEnvironmentSvcServer(gs, es) + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + environmentServer := environmentservice.NewEnvironmentServer( + authnClient, + authrClient, + scheduledEventClient, + es, + ) + microservices.StartAPIServer(environmentServer) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/progresssvc/Dockerfile b/v3/services/progresssvc/Dockerfile new file mode 100644 index 00000000..7db8edcb --- /dev/null +++ b/v3/services/progresssvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/progresssvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/progresssvc/go.mod b/v3/services/progresssvc/go.mod new file mode 100644 index 00000000..7a2f4ba1 --- /dev/null +++ b/v3/services/progresssvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/progresssvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/progresssvc/go.sum b/v3/services/progresssvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/progresssvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/progresssvc/internal/crd.go b/v3/services/progresssvc/internal/crd.go new file mode 100644 index 00000000..6523e0d8 --- /dev/null +++ b/v3/services/progresssvc/internal/crd.go @@ -0,0 +1,30 @@ +package progressservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// ProgressCRDInstaller is a struct that can generate CRDs for progresses. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type ProgressCRDInstaller struct{} + +func (pi ProgressCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.Progress{}, func(c *crder.CRD) { + c. + WithNames("progress", "progresses"). + IsNamespaced(true). + AddVersion("v1", &v1.Progress{}, func(cv *crder.Version) { + cv. + WithColumn("CurrentStep", ".spec.current_step"). + WithColumn("Course", ".spec.course"). + WithColumn("Scenario", ".spec.scenario"). + WithColumn("User", ".spec.user"). + WithColumn("Started", ".spec.started"). + WithColumn("LastUpdate", ".spec.last_update") + }) + }), + } +} diff --git a/v3/services/progresssvc/internal/grpc.go b/v3/services/progresssvc/internal/grpc.go new file mode 100644 index 00000000..2ebc4a11 --- /dev/null +++ b/v3/services/progresssvc/internal/grpc.go @@ -0,0 +1,324 @@ +package progressservice + +import ( + "context" + "time" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcProgressServer struct { + progresspb.UnimplementedProgressSvcServer + progressClient hfClientsetv1.ProgressInterface + progressLister listersv1.ProgressLister + progressSynced cache.InformerSynced +} + +func NewGrpcProgressServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcProgressServer { + return &GrpcProgressServer{ + progressClient: hfClientSet.HobbyfarmV1().Progresses(util.GetReleaseNamespace()), + progressLister: hfInformerFactory.Hobbyfarm().V1().Progresses().Lister(), + progressSynced: hfInformerFactory.Hobbyfarm().V1().Progresses().Informer().HasSynced, + } +} + +func (s *GrpcProgressServer) CreateProgress(ctx context.Context, req *progresspb.CreateProgressRequest) (*generalpb.ResourceId, error) { + random := util.RandStringRunes(16) + now := time.Now() + progressId := util.GenerateResourceName("progress", random, 16) + + currentStep := req.GetCurrentStep() + maxStep := req.GetMaxStep() + totalStep := req.GetTotalStep() + scenario := req.GetScenario() + course := req.GetCourse() + user := req.GetUser() + labels := req.GetLabels() + + progress := &hfv1.Progress{ + ObjectMeta: metav1.ObjectMeta{ + Name: progressId, + Labels: labels, + }, + Spec: hfv1.ProgressSpec{ + CurrentStep: int(currentStep), + MaxStep: int(maxStep), + TotalStep: int(totalStep), + Course: course, + Scenario: scenario, + UserId: user, + Started: now.Format(time.UnixDate), + LastUpdate: now.Format(time.UnixDate), + Finished: "false", + }, + } + + steps := []hfv1.ProgressStep{} + step := hfv1.ProgressStep{Step: 0, Timestamp: now.Format(time.UnixDate)} + steps = append(steps, step) + progress.Spec.Steps = steps + + _, err := s.progressClient.Create(ctx, progress, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: progressId}, nil +} + +func (s *GrpcProgressServer) GetProgress(ctx context.Context, req *generalpb.GetRequest) (*progresspb.Progress, error) { + progress, err := util.GenericHfGetter(ctx, req, s.progressClient, s.progressLister.Progresses(util.GetReleaseNamespace()), "progress", s.progressSynced()) + if err != nil { + return &progresspb.Progress{}, err + } + + progressSteps := []*progresspb.ProgressStep{} + + for _, step := range progress.Spec.Steps { + progressStep := &progresspb.ProgressStep{ + Step: uint32(step.Step), + Timestamp: step.Timestamp, + } + progressSteps = append(progressSteps, progressStep) + } + + var creationTimeStamp *timestamppb.Timestamp + if !progress.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(progress.CreationTimestamp.Time) + } + + return &progresspb.Progress{ + Id: progress.Name, + Uid: string(progress.UID), + CurrentStep: uint32(progress.Spec.CurrentStep), + MaxStep: uint32(progress.Spec.MaxStep), + TotalStep: uint32(progress.Spec.TotalStep), + Scenario: progress.Spec.Scenario, + Course: progress.Spec.Course, + User: progress.Spec.UserId, + Started: progress.Spec.Started, + LastUpdate: progress.Spec.LastUpdate, + Finished: progress.Spec.Finished, + Steps: progressSteps, + Labels: progress.Labels, + CreationTimestamp: creationTimeStamp, + }, nil +} + +func (s *GrpcProgressServer) UpdateProgress(ctx context.Context, req *progresspb.UpdateProgressRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + currentStep := req.GetCurrentStep() + maxStep := req.GetMaxStep() + totalStep := req.GetTotalStep() + lastUpdate := req.GetLastUpdate() + finished := req.GetFinished() + steps := req.GetSteps() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + progress, err := s.progressClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving progress %s", + req, + req.GetId(), + ) + } + return s.updateProgress(ctx, progress, currentStep, maxStep, totalStep, lastUpdate, finished, steps) + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcProgressServer) UpdateCollectionProgress(ctx context.Context, req *progresspb.UpdateCollectionProgressRequest) (*emptypb.Empty, error) { + progressList, err := util.ListByHfClient(ctx, &generalpb.ListOptions{LabelSelector: req.GetLabelselector()}, s.progressClient, "progresses") + if err != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error while listing progress", + req, + ) + } + progresses := progressList.Items + // If a client tries to update on an empty list, we throw a notFound error... this is an invalid operation. + if len(progresses) == 0 { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.NotFound, + "error no progress found", + req, + ) + } + + currentStep := req.GetCurrentStep() + maxStep := req.GetMaxStep() + totalStep := req.GetTotalStep() + lastUpdate := req.GetLastUpdate() + finished := req.GetFinished() + steps := req.GetSteps() + + var retryErr error + for _, progress := range progresses { + retryErr = retry.RetryOnConflict(retry.DefaultRetry, func() error { + return s.updateProgress(ctx, &progress, currentStep, maxStep, totalStep, lastUpdate, finished, steps) + }) + } + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcProgressServer) DeleteProgress(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.progressClient, "progress") +} + +func (s *GrpcProgressServer) DeleteCollectionProgress(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.progressClient, "progresses") +} + +func (s *GrpcProgressServer) ListProgress(ctx context.Context, listOptions *generalpb.ListOptions) (*progresspb.ListProgressesResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var progresses []hfv1.Progress + var err error + if !doLoadFromCache { + var progressList *hfv1.ProgressList + progressList, err = util.ListByHfClient(ctx, listOptions, s.progressClient, "progresses") + if err == nil { + progresses = progressList.Items + } + } else { + progresses, err = util.ListByCache(listOptions, s.progressLister, "progresses", s.progressSynced()) + } + if err != nil { + glog.Error(err) + return &progresspb.ListProgressesResponse{}, err + } + + preparedProgress := []*progresspb.Progress{} + + for _, progress := range progresses { + progressSteps := []*progresspb.ProgressStep{} + for _, step := range progress.Spec.Steps { + progressStep := &progresspb.ProgressStep{ + Step: uint32(step.Step), + Timestamp: step.Timestamp, + } + progressSteps = append(progressSteps, progressStep) + } + + var creationTimeStamp *timestamppb.Timestamp + if !progress.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(progress.CreationTimestamp.Time) + } + + preparedProgress = append(preparedProgress, &progresspb.Progress{ + Id: progress.Name, + Uid: string(progress.UID), + CurrentStep: uint32(progress.Spec.CurrentStep), + MaxStep: uint32(progress.Spec.MaxStep), + TotalStep: uint32(progress.Spec.TotalStep), + Scenario: progress.Spec.Scenario, + Course: progress.Spec.Course, + User: progress.Spec.UserId, + Started: progress.Spec.Started, + LastUpdate: progress.Spec.LastUpdate, + Finished: progress.Spec.Finished, + Steps: progressSteps, + Labels: progress.Labels, + CreationTimestamp: creationTimeStamp, + }) + } + + return &progresspb.ListProgressesResponse{Progresses: preparedProgress}, nil +} + +func (s *GrpcProgressServer) updateProgress( + ctx context.Context, + progress *hfv1.Progress, + currStep *wrapperspb.UInt32Value, + maxStep *wrapperspb.UInt32Value, + totalStep *wrapperspb.UInt32Value, + lastUpdate string, + finished string, + steps []*progresspb.ProgressStep, +) error { + if currStep != nil { + progress.Spec.CurrentStep = int(currStep.Value) + } + + if maxStep != nil { + progress.Spec.MaxStep = int(maxStep.Value) + } + + // ensure the max visited step is always >= the currently visited step after an update + if progress.Spec.CurrentStep > progress.Spec.MaxStep { + progress.Spec.MaxStep = progress.Spec.CurrentStep + } + + if totalStep != nil { + progress.Spec.TotalStep = int(totalStep.Value) + } + + if lastUpdate != "" { + progress.Spec.LastUpdate = lastUpdate + } + + if finished != "" { + progress.Spec.Finished = finished + progress.Labels["finished"] = finished + } + + if len(steps) > 0 { + progressSteps := []hfv1.ProgressStep{} + for _, step := range steps { + progressStep := hfv1.ProgressStep{ + Step: int(step.GetStep()), + Timestamp: step.GetTimestamp(), + } + progressSteps = append(progressSteps, progressStep) + } + progress.Spec.Steps = progressSteps + } + + _, updateErr := s.progressClient.Update(ctx, progress, metav1.UpdateOptions{}) + return updateErr +} diff --git a/v3/services/progresssvc/internal/progressservice.go b/v3/services/progresssvc/internal/progressservice.go new file mode 100644 index 00000000..756f219a --- /dev/null +++ b/v3/services/progresssvc/internal/progressservice.go @@ -0,0 +1,398 @@ +package progressservice + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "time" + + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + "github.com/golang/glog" + "github.com/gorilla/mux" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +const ( + idIndex = "progressserver.hobbyfarm.io/id-index" + resourcePlural = rbac.ResourcePluralProgress +) + +type AdminPreparedProgress struct { + ID string `json:"id"` + Session string `json:"session"` + CurrentStep uint32 `json:"current_step"` + MaxStep uint32 `json:"max_step"` + TotalStep uint32 `json:"total_step"` + Course string `json:"course"` + Scenario string `json:"scenario"` + UserId string `json:"user"` + Started string `json:"started"` + LastUpdate string `json:"last_update"` + Finished string `json:"finished"` + Steps []*progresspb.ProgressStep `json:"steps"` +} + +type AdminPreparedProgressWithScheduledEvent struct { + AdminPreparedProgress + ScheduledEvent string `json:"scheduled_event"` +} + +type ScheduledEventProgressCount struct { + CountMap map[string]int `json:"count_map"` +} + +/* +List Progress by Scheduled Event + + Vars: + - id : The scheduled event id +*/ +func (s ProgressServer) ListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") + return + } + + includeFinished := false + includeFinishedParam := r.URL.Query().Get("includeFinished") + if includeFinishedParam != "" && includeFinishedParam != "false" { + includeFinished = true + } + + s.ListByLabel(w, r, hflabels.ScheduledEventLabel, id, includeFinished) + + glog.V(2).Infof("listed progress for scheduledevent %s", id) +} + +func (s ProgressServer) ListByRangeFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") + return + } + + fromString := r.URL.Query().Get("from") + if fromString == "" { + util.ReturnHTTPMessage(w, r, 500, "error", "no start of range passed in") + return + } + + start, err := time.Parse(time.UnixDate, fromString) + + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error parsing start time") + return + } + + toString := r.URL.Query().Get("to") + if toString == "" { + util.ReturnHTTPMessage(w, r, 500, "error", "no end of range passed in") + return + } + + end, err := time.Parse(time.UnixDate, toString) + + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error parsing end time") + return + } + + s.ListByRange(w, r, start, end, true) + + glog.V(2).Info("listed progress for time range") +} + +/* +List Progress for the authenticated user +*/ +func (s ProgressServer) ListForUserFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") + return + } + + s.ListByLabel(w, r, hflabels.UserLabel, user.GetId(), true) +} + +/* +List Progress by User + + Vars: + - id : The user id +*/ +func (s ProgressServer) ListByUserFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") + return + } + + s.ListByLabel(w, r, hflabels.UserLabel, id, true) + + glog.V(2).Infof("listed progress for user %s", id) +} + +func (s ProgressServer) CountByScheduledEvent(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list progress") + return + } + + progressList, err := s.internalProgressServer.ListProgress(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", "finished", "false"), + }) + if err != nil { + glog.Errorf("error while retrieving progress: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no progress found") + return + } + countMap := map[string]int{} + for _, p := range progressList.GetProgresses() { + se := p.GetLabels()[hflabels.ScheduledEventLabel] + if _, ok := countMap[se]; ok { + countMap[se] = countMap[se] + 1 + } else { + countMap[se] = 1 + } + } + + encodedMap, err := json.Marshal(countMap) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedMap) +} + +func (s ProgressServer) ListByRange(w http.ResponseWriter, r *http.Request, start time.Time, end time.Time, includeFinished bool) { + includeFinishedFilter := "finished=false" // Default is to only include active (finished=false) progress + if includeFinished { + includeFinishedFilter = "" + } + + progressList, err := s.internalProgressServer.ListProgress(r.Context(), &generalpb.ListOptions{ + LabelSelector: includeFinishedFilter, + }) + + if err != nil { + glog.Errorf("error while retrieving progress: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no progress found") + return + } + + preparedProgress := []AdminPreparedProgressWithScheduledEvent{} + for _, p := range progressList.GetProgresses() { + creationTimeStamp := p.GetCreationTimestamp().AsTime() + //CreationTimestamp of progress is out of range + if creationTimeStamp.Before(start) || end.Before(creationTimeStamp) { + continue + } + pProgressWithEventId := AdminPreparedProgressWithScheduledEvent{ + AdminPreparedProgress: AdminPreparedProgress{ + ID: p.GetId(), + Session: p.GetLabels()[hflabels.SessionLabel], + CurrentStep: p.GetCurrentStep(), + MaxStep: p.GetMaxStep(), + TotalStep: p.GetTotalStep(), + Course: p.GetCourse(), + Scenario: p.GetScenario(), + UserId: p.GetUser(), + Started: p.GetStarted(), + LastUpdate: p.GetLastUpdate(), + Finished: p.GetFinished(), + Steps: p.GetSteps(), + }, + ScheduledEvent: p.GetLabels()[hflabels.ScheduledEventLabel], + } + preparedProgress = append(preparedProgress, pProgressWithEventId) + } + + encodedProgress, err := json.Marshal(preparedProgress) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedProgress) +} + +func (s ProgressServer) ListByLabel(w http.ResponseWriter, r *http.Request, label string, value string, includeFinished bool) { + includeFinishedFilter := ",finished=false" // Default is to only include active (finished=false) progress + if includeFinished { + includeFinishedFilter = "" + } + progressList, err := s.internalProgressServer.ListProgress(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s%s", label, value, includeFinishedFilter), + }) + + if err != nil { + glog.Errorf("error while retrieving progress %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no progress found") + return + } + + preparedProgress := []AdminPreparedProgress{} + for _, p := range progressList.GetProgresses() { + pProgress := AdminPreparedProgress{ + ID: p.GetId(), + Session: p.GetLabels()[hflabels.SessionLabel], + CurrentStep: p.GetCurrentStep(), + MaxStep: p.GetMaxStep(), + TotalStep: p.GetTotalStep(), + Course: p.GetCourse(), + Scenario: p.GetScenario(), + UserId: p.GetUser(), + Started: p.GetStarted(), + LastUpdate: p.GetLastUpdate(), + Finished: p.GetFinished(), + Steps: p.GetSteps(), + } + preparedProgress = append(preparedProgress, pProgress) + } + + encodedProgress, err := json.Marshal(preparedProgress) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedProgress) +} + +/* +Update Progress + + Vars: + - id : Session linked to the progress resource +*/ +func (s ProgressServer) Update(w http.ResponseWriter, r *http.Request) { + now := time.Now() + + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update progress") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") + return + } + + stepRaw := r.PostFormValue("step") + if stepRaw == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no step was passed in") + return + } + + step, err := strconv.Atoi(stepRaw) + if err != nil { + glog.Errorf("error while converting step %v", err) + util.ReturnHTTPMessage(w, r, 500, "error", "provided step was invalid") + return + } + + // @TODO: Currently we're using the progress k8s client directly. + // The grpc service would internally retrieve each progress object again before updating which is less performant. + // In the future, we should use the internal gRPC service to abstract the underlying database operations. + // This approach ensures that database interactions are not exposed directly, allowing easier interchangeability and improved modularity. + // We already implemented an UpdateCollectionProgress function, however, within that function we don't have access to p.Spec.Steps. + progress, err := s.internalProgressServer.progressClient.List(r.Context(), metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s,%s=%s,finished=false", hflabels.SessionLabel, id, hflabels.UserLabel, user.GetId())}) + + if err != nil { + glog.Errorf("error while retrieving progress %v", err) + util.ReturnHTTPMessage(w, r, 500, "error", "no active progress for this session found") + return + } + + if len(progress.Items) < 1 { + util.ReturnHTTPMessage(w, r, 404, "error", "no active progress for this session found") + return + } + + for _, p := range progress.Items { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if step > p.Spec.MaxStep { + p.Spec.MaxStep = step + } + p.Spec.CurrentStep = step + p.Spec.LastUpdate = now.Format(time.UnixDate) + + steps := p.Spec.Steps + newStep := hfv1.ProgressStep{Step: step, Timestamp: now.Format(time.UnixDate)} + steps = append(steps, newStep) + p.Spec.Steps = steps + + _, updateErr := s.internalProgressServer.progressClient.Update(r.Context(), &p, metav1.UpdateOptions{}) + glog.V(4).Infof("updated result for progress") + + return updateErr + }) + + if retryErr != nil { + glog.Errorf("error updating progress %s: %v", p.Name, err) + util.ReturnHTTPMessage(w, r, 500, "error", "progress could not be updated") + return + } + } + + util.ReturnHTTPMessage(w, r, 200, "success", "Progress was updated") +} diff --git a/v3/services/progresssvc/internal/server.go b/v3/services/progresssvc/internal/server.go new file mode 100644 index 00000000..1eb71009 --- /dev/null +++ b/v3/services/progresssvc/internal/server.go @@ -0,0 +1,36 @@ +package progressservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" +) + +type ProgressServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + internalProgressServer *GrpcProgressServer +} + +func NewProgressServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + internalProgressServer *GrpcProgressServer, +) ProgressServer { + return ProgressServer{ + authnClient: authnClient, + authrClient: authrClient, + internalProgressServer: internalProgressServer, + } +} + +func (s ProgressServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/a/progress/scheduledevent/{id}", s.ListByScheduledEventFunc).Methods("GET") + r.HandleFunc("/a/progress/user/{id}", s.ListByUserFunc).Methods("GET") + r.HandleFunc("/a/progress/count", s.CountByScheduledEvent).Methods("GET") + r.HandleFunc("/a/progress/range", s.ListByRangeFunc).Methods("GET") + r.HandleFunc("/progress/update/{id}", s.Update).Methods("POST") + r.HandleFunc("/progress/list", s.ListForUserFunc).Methods("GET") + glog.V(2).Infof("set up routes for ProgressServer") +} diff --git a/v3/services/progresssvc/main.go b/v3/services/progresssvc/main.go new file mode 100644 index 00000000..c059628e --- /dev/null +++ b/v3/services/progresssvc/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + progressService "github.com/hobbyfarm/gargantua/services/progresssvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(progressService.ProgressCRDInstaller{}, cfg, "progress") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ps := progressService.NewGrpcProgressServer(hfClient, hfInformerFactory) + progresspb.RegisterProgressSvcServer(gs, ps) + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + progressServer := progressService.NewProgressServer( + authnClient, + authrClient, + ps, + ) + microservices.StartAPIServer(progressServer) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/rbacsvc/internal/grpc.go b/v3/services/rbacsvc/internal/grpc.go index a2687565..2b66deb0 100644 --- a/v3/services/rbacsvc/internal/grpc.go +++ b/v3/services/rbacsvc/internal/grpc.go @@ -1,23 +1,38 @@ package rbac import ( - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" + rbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" + listersv1 "k8s.io/client-go/listers/rbac/v1" + "k8s.io/client-go/tools/cache" ) type GrpcRbacServer struct { - rbacProto.UnimplementedRbacSvcServer - kubeClientSet *kubernetes.Clientset - userIndex *Index - groupIndex *Index + rbacpb.UnimplementedRbacSvcServer + roleClient rbacv1.RoleInterface + roleBindingClient rbacv1.RoleBindingInterface + userIndex *Index + groupIndex *Index + roleLister listersv1.RoleLister + roleSynced cache.InformerSynced + roleBindingLister listersv1.RoleBindingLister + roleBindingSynced cache.InformerSynced } func NewGrpcRbacServer(kubeClientSet *kubernetes.Clientset, namespace string, kubeInformerFactory informers.SharedInformerFactory) (*GrpcRbacServer, error) { + rClient := kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()) + rbClient := kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()) rbInformer := kubeInformerFactory.Rbac().V1().RoleBindings().Informer() crbInformer := kubeInformerFactory.Rbac().V1().ClusterRoleBindings().Informer() rInformer := kubeInformerFactory.Rbac().V1().Roles().Informer() crInformer := kubeInformerFactory.Rbac().V1().ClusterRoles().Informer() + rLister := kubeInformerFactory.Rbac().V1().Roles().Lister() + rbLister := kubeInformerFactory.Rbac().V1().RoleBindings().Lister() + rSynced := rInformer.HasSynced + rbSynced := rbInformer.HasSynced userIndex, err := NewIndex("User", namespace, rbInformer, crbInformer, rInformer, crInformer) if err != nil { return nil, err @@ -29,8 +44,13 @@ func NewGrpcRbacServer(kubeClientSet *kubernetes.Clientset, namespace string, ku } return &GrpcRbacServer{ - kubeClientSet: kubeClientSet, - userIndex: userIndex, - groupIndex: groupIndex, + roleClient: rClient, + roleBindingClient: rbClient, + userIndex: userIndex, + groupIndex: groupIndex, + roleLister: rLister, + roleSynced: rSynced, + roleBindingLister: rbLister, + roleBindingSynced: rbSynced, }, nil } diff --git a/v3/services/rbacsvc/internal/grpc_access.go b/v3/services/rbacsvc/internal/grpc_access.go index 8f5c4f58..8e8eef24 100644 --- a/v3/services/rbacsvc/internal/grpc_access.go +++ b/v3/services/rbacsvc/internal/grpc_access.go @@ -3,9 +3,9 @@ package rbac import ( "fmt" - "github.com/hobbyfarm/gargantua/v3/pkg/util" - authrProto "github.com/hobbyfarm/gargantua/v3/protos/authr" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" rbacv1 "k8s.io/api/rbac/v1" ) @@ -23,7 +23,7 @@ type AccessSet struct { Access map[string]bool `json:"access"` } -func Grants(perm *authrProto.Permission, as *rbacProto.AccessSet) bool { +func Grants(perm *authrpb.Permission, as *rbacpb.AccessSet) bool { // key is /apigroup/resource/verb for _, a := range []string{perm.GetApiGroup(), All} { for _, r := range []string{perm.GetResource(), All} { @@ -38,8 +38,8 @@ func Grants(perm *authrProto.Permission, as *rbacProto.AccessSet) bool { return false } -func (i *Index) GetAccessSet(subj string) (*rbacProto.AccessSet, error) { - var as = &rbacProto.AccessSet{ +func (i *Index) GetAccessSet(subj string) (*rbacpb.AccessSet, error) { + var as = &rbacpb.AccessSet{ Subject: subj, Access: map[string]bool{}, } @@ -77,7 +77,7 @@ func (i *Index) GetAccessSet(subj string) (*rbacProto.AccessSet, error) { return as, nil } -func (i *Index) addToAccessSet(accessSet *rbacProto.AccessSet, namespace string, rules []rbacv1.PolicyRule) { +func (i *Index) addToAccessSet(accessSet *rbacpb.AccessSet, namespace string, rules []rbacv1.PolicyRule) { // we only care about rules that are global, or apply to our namespace // any others can be discarded // this simplifies the frontend from having to worry about what namespace HF is installed into @@ -151,13 +151,13 @@ func (i *Index) getRoleBindings(subj string) ([]*rbacv1.RoleBinding, error) { return roleBindings, nil } -func (i *Index) getPreparedRoleBindings(subj string) (*rbacProto.RoleBindings, error) { +func (i *Index) getPreparedRoleBindings(subj string) (*rbacpb.RoleBindings, error) { obj, err := i.roleBindingIndexer.ByIndex(rbIndex+"-"+i.kind, subj) if err != nil { return nil, err } - var roleBindings []*rbacProto.RoleBinding + var roleBindings []*rbacpb.RoleBinding for _, v := range obj { rb, ok := v.(*rbacv1.RoleBinding) @@ -165,16 +165,16 @@ func (i *Index) getPreparedRoleBindings(subj string) (*rbacProto.RoleBindings, e continue // rb is not of type *rbacv1.RoleBinding, don't return it } - if _, ok := rb.Labels[util.RBACManagedLabel]; !ok { + if _, ok := rb.Labels[hflabels.RBACManagedLabel]; !ok { continue // we aren't managing this role, don't return it } - tmpRoleBinding := &rbacProto.RoleBinding{ + tmpRoleBinding := &rbacpb.RoleBinding{ Name: rb.Name, Role: rb.RoleRef.Name, - Subjects: []*rbacProto.Subject{}, + Subjects: []*rbacpb.Subject{}, } for _, s := range rb.Subjects { - tmpRoleBinding.Subjects = append(tmpRoleBinding.Subjects, &rbacProto.Subject{ + tmpRoleBinding.Subjects = append(tmpRoleBinding.Subjects, &rbacpb.Subject{ Kind: s.Kind, Name: s.Name, }) @@ -182,7 +182,7 @@ func (i *Index) getPreparedRoleBindings(subj string) (*rbacProto.RoleBindings, e roleBindings = append(roleBindings, tmpRoleBinding) } - return &rbacProto.RoleBindings{Rolebindings: roleBindings}, nil + return &rbacpb.RoleBindings{Rolebindings: roleBindings}, nil } func (i *Index) getClusterRoleBindings(subj string) ([]*rbacv1.ClusterRoleBinding, error) { diff --git a/v3/services/rbacsvc/internal/grpc_rbac.go b/v3/services/rbacsvc/internal/grpc_rbac.go index c4db8f94..344ae525 100644 --- a/v3/services/rbacsvc/internal/grpc_rbac.go +++ b/v3/services/rbacsvc/internal/grpc_rbac.go @@ -4,53 +4,42 @@ import ( "context" "github.com/golang/glog" - authrProto "github.com/hobbyfarm/gargantua/v3/protos/authr" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + "github.com/hobbyfarm/gargantua/v3/pkg/errors" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) -func (rs *GrpcRbacServer) Grants(c context.Context, gr *rbacProto.GrantRequest) (*authrProto.AuthRResponse, error) { +func (rs *GrpcRbacServer) Grants(c context.Context, gr *rbacpb.GrantRequest) (*authrpb.AuthRResponse, error) { as, err := rs.userIndex.GetAccessSet(gr.GetUserName()) if err != nil { - err := status.Newf( + glog.Errorf("failed to retrieve access set for user %s", gr.GetUserName()) + return &authrpb.AuthRResponse{}, errors.GrpcError( codes.Internal, "failed to retrieve access set for user %s", + gr, gr.GetUserName(), ) - - err, wde := err.WithDetails(gr) - if wde != nil { - return &authrProto.AuthRResponse{Success: false}, wde - } - glog.Errorf("failed to retrieve access set for user %s", gr.GetUserName()) - return &authrProto.AuthRResponse{Success: false}, err.Err() } - return &authrProto.AuthRResponse{Success: Grants(gr.GetPermission(), as)}, nil + return &authrpb.AuthRResponse{Success: Grants(gr.GetPermission(), as)}, nil } -func (rs *GrpcRbacServer) GetAccessSet(c context.Context, uid *userProto.UserId) (*rbacProto.AccessSet, error) { +func (rs *GrpcRbacServer) GetAccessSet(c context.Context, uid *generalpb.ResourceId) (*rbacpb.AccessSet, error) { return rs.userIndex.GetAccessSet(uid.GetId()) } -func (rs *GrpcRbacServer) GetHobbyfarmRoleBindings(c context.Context, uid *userProto.UserId) (*rbacProto.RoleBindings, error) { +func (rs *GrpcRbacServer) GetHobbyfarmRoleBindings(c context.Context, uid *generalpb.ResourceId) (*rbacpb.RoleBindings, error) { rbs, err := rs.userIndex.getPreparedRoleBindings(uid.GetId()) if err != nil { glog.Errorf("failed to retrieve rolebindings for user %s with error: %s", uid.GetId(), err.Error()) - err := status.Newf( + return &rbacpb.RoleBindings{}, errors.GrpcError( codes.Internal, "failed to retrieve rolebindings for user %s", + uid, uid.GetId(), ) - - err, wde := err.WithDetails(uid) - if wde != nil { - return nil, wde - } - - return nil, err.Err() } return rbs, nil } diff --git a/v3/services/rbacsvc/internal/grpc_rolebindings.go b/v3/services/rbacsvc/internal/grpc_rolebindings.go index a95503f3..821f5757 100644 --- a/v3/services/rbacsvc/internal/grpc_rolebindings.go +++ b/v3/services/rbacsvc/internal/grpc_rolebindings.go @@ -5,51 +5,44 @@ import ( "fmt" "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - empty "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/emptypb" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/util/retry" ) -func (rs *GrpcRbacServer) CreateRolebinding(c context.Context, cr *rbacProto.RoleBinding) (*empty.Empty, error) { +func (rs *GrpcRbacServer) CreateRolebinding(c context.Context, cr *rbacpb.RoleBinding) (*emptypb.Empty, error) { rolebinding, err := rs.marshalRolebinding(c, cr) if err != nil { glog.Errorf("invalid rolebinding: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "invalid rolebinding", + cr, ) - newErr, wde := newErr.WithDetails(cr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - _, err = rs.kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()).Create(c, rolebinding, metav1.CreateOptions{}) + _, err = rs.roleBindingClient.Create(c, rolebinding, metav1.CreateOptions{}) if err != nil { glog.Errorf("error creating rolebinding in kubernetes: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, - "internal error", + "error creating rolebinding", + cr, ) - newErr, wde := newErr.WithDetails(cr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (rs *GrpcRbacServer) GetRolebinding(c context.Context, gr *rbacProto.ResourceId) (*rbacProto.RoleBinding, error) { +func (rs *GrpcRbacServer) GetRolebinding(c context.Context, gr *generalpb.GetRequest) (*rbacpb.RoleBinding, error) { rolebinding, err := rs.getRolebinding(c, gr) if err != nil { return nil, err @@ -57,113 +50,87 @@ func (rs *GrpcRbacServer) GetRolebinding(c context.Context, gr *rbacProto.Resour return unmarshalRolebinding(rolebinding), nil } -func (rs *GrpcRbacServer) UpdateRolebinding(c context.Context, ur *rbacProto.RoleBinding) (*empty.Empty, error) { +func (rs *GrpcRbacServer) UpdateRolebinding(c context.Context, ur *rbacpb.RoleBinding) (*emptypb.Empty, error) { inputRolebinding, err := rs.marshalRolebinding(c, ur) if err != nil { glog.Errorf("invalid role: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "invalid role", + ur, ) - newErr, wde := newErr.WithDetails(ur) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - k8sRolebinding, err := rs.getRolebinding(c, &rbacProto.ResourceId{Id: ur.GetName()}) + k8sRolebinding, err := rs.getRolebinding(c, &generalpb.GetRequest{Id: ur.GetName()}) if err != nil { - return &empty.Empty{}, err + return &emptypb.Empty{}, err } k8sRolebinding.RoleRef = inputRolebinding.RoleRef k8sRolebinding.Subjects = inputRolebinding.Subjects retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - _, err := rs.kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()).Update(c, k8sRolebinding, metav1.UpdateOptions{}) + _, err := rs.roleBindingClient.Update(c, k8sRolebinding, metav1.UpdateOptions{}) if err != nil { glog.Errorf("error while updating rolebinding in kubernetes: %v", err) - newErr := status.Newf( + return hferrors.GrpcError( codes.Internal, - "internal error", + "error while updating rolebinding", + ur, ) - newErr, wde := newErr.WithDetails(ur) - if wde != nil { - return wde - } - return newErr.Err() } return nil }) if retryErr != nil { - return &empty.Empty{}, retryErr + return &emptypb.Empty{}, retryErr } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (rs *GrpcRbacServer) DeleteRolebinding(c context.Context, dr *rbacProto.ResourceId) (*empty.Empty, error) { +func (rs *GrpcRbacServer) DeleteRolebinding(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { // we want to get the rolebinding first as this allows us to run it through the various checks before we attempt deletion // most important of which is checking that we have labeled it correctly // but it doesn't hurt to check if it exists before - rolebinding, err := rs.getRolebinding(c, dr) + _, err := rs.getRolebinding(ctx, &generalpb.GetRequest{Id: req.GetId()}) if err != nil { - return &empty.Empty{}, err + return &emptypb.Empty{}, err } - err = rs.kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()).Delete(c, rolebinding.Name, metav1.DeleteOptions{}) - if err != nil { - glog.Errorf("error deleting rolebinding in kubernetes: %v", err) - newErr := status.Newf( - codes.Internal, - "internal error", - ) - newErr, wde := newErr.WithDetails(dr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() - } - return &empty.Empty{}, nil + return util.DeleteHfResource(ctx, req, rs.roleBindingClient, "rolebinding") } -func (rs *GrpcRbacServer) ListRolebinding(c context.Context, lr *empty.Empty) (*rbacProto.RoleBindings, error) { - listOptions := metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%t", util.RBACManagedLabel, true), +func (rs *GrpcRbacServer) ListRolebinding(ctx context.Context, listOptions *generalpb.ListOptions) (*rbacpb.RoleBindings, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var rolebindings []rbacv1.RoleBinding + var err error + if !doLoadFromCache { + var rolebindingList *rbacv1.RoleBindingList + rolebindingList, err = util.ListByHfClient(ctx, listOptions, rs.roleBindingClient, "rolebindings") + if err == nil { + rolebindings = rolebindingList.Items + } + } else { + rolebindings, err = util.ListByCache(listOptions, rs.roleBindingLister, "rolebindings", rs.roleBindingSynced()) } - - rolebindings, err := rs.kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()).List(c, listOptions) if err != nil { - if errors.IsNotFound(err) { - glog.Errorf("error: rolebindings not found") - newErr := status.Newf( - codes.NotFound, - "rolebindings not found", - ) - return &rbacProto.RoleBindings{}, newErr.Err() - } - glog.Errorf("error in kubernetes while listing rolebindings %v", err) - newErr := status.Newf( - codes.Internal, - "internal error", - ) - return &rbacProto.RoleBindings{}, newErr.Err() + glog.Error(err) + return &rbacpb.RoleBindings{}, err } - var preparedRolebindings = make([]*rbacProto.RoleBinding, 0) - for _, r := range rolebindings.Items { + var preparedRolebindings = make([]*rbacpb.RoleBinding, 0) + for _, r := range rolebindings { pr := unmarshalRolebinding(&r) preparedRolebindings = append(preparedRolebindings, pr) } - return &rbacProto.RoleBindings{Rolebindings: preparedRolebindings}, nil + return &rbacpb.RoleBindings{Rolebindings: preparedRolebindings}, nil } -func (rs *GrpcRbacServer) marshalRolebinding(ctx context.Context, preparedRoleBinding *rbacProto.RoleBinding) (*rbacv1.RoleBinding, error) { +func (rs *GrpcRbacServer) marshalRolebinding(ctx context.Context, preparedRoleBinding *rbacpb.RoleBinding) (*rbacv1.RoleBinding, error) { // first validation, the role it is referencing has to exist - role, err := rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).Get(ctx, preparedRoleBinding.GetRole(), metav1.GetOptions{}) + role, err := rs.roleClient.Get(ctx, preparedRoleBinding.GetRole(), metav1.GetOptions{}) if err != nil { return nil, fmt.Errorf("invalid role ref") } @@ -173,7 +140,7 @@ func (rs *GrpcRbacServer) marshalRolebinding(ctx context.Context, preparedRoleBi Name: preparedRoleBinding.GetName(), Namespace: util.GetReleaseNamespace(), Labels: map[string]string{ - util.RBACManagedLabel: "true", + hflabels.RBACManagedLabel: "true", }, OwnerReferences: []metav1.OwnerReference{ { @@ -207,15 +174,15 @@ func (rs *GrpcRbacServer) marshalRolebinding(ctx context.Context, preparedRoleBi return &rb, nil } -func unmarshalRolebinding(roleBinding *rbacv1.RoleBinding) *rbacProto.RoleBinding { - prb := &rbacProto.RoleBinding{ +func unmarshalRolebinding(roleBinding *rbacv1.RoleBinding) *rbacpb.RoleBinding { + prb := &rbacpb.RoleBinding{ Name: roleBinding.Name, Role: roleBinding.RoleRef.Name, - Subjects: []*rbacProto.Subject{}, + Subjects: []*rbacpb.Subject{}, } for _, s := range roleBinding.Subjects { - prb.Subjects = append(prb.GetSubjects(), &rbacProto.Subject{ + prb.Subjects = append(prb.GetSubjects(), &rbacpb.Subject{ Kind: s.Kind, Name: s.Name, }) @@ -224,58 +191,20 @@ func unmarshalRolebinding(roleBinding *rbacv1.RoleBinding) *rbacProto.RoleBindin return prb } -func (rs *GrpcRbacServer) getRolebinding(c context.Context, gr *rbacProto.ResourceId) (*rbacv1.RoleBinding, error) { - if gr.GetId() == "" { - glog.Errorf("invalid rolebinding id") - newErr := status.Newf( - codes.InvalidArgument, - "invalid rolebinding id", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() - } - - rolebinding, err := rs.kubeClientSet.RbacV1().RoleBindings(util.GetReleaseNamespace()).Get(c, gr.GetId(), metav1.GetOptions{}) +func (rs *GrpcRbacServer) getRolebinding(ctx context.Context, req *generalpb.GetRequest) (*rbacv1.RoleBinding, error) { + rolebinding, err := util.GenericHfGetter(ctx, req, rs.roleBindingClient, rs.roleBindingLister.RoleBindings(util.GetReleaseNamespace()), "rolebinding", rs.roleBindingSynced()) if err != nil { - if errors.IsNotFound(err) { - glog.Errorf("rolebinding not found") - newErr := status.Newf( - codes.NotFound, - "rolebinding not found", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() - } - glog.Errorf("kubernetes error while getting rolebinding: %v", err) - newErr := status.Newf( - codes.Internal, - "internal server error", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() + return &rbacv1.RoleBinding{}, err } - if _, ok := rolebinding.Labels[util.RBACManagedLabel]; !ok { + if _, ok := rolebinding.Labels[hflabels.RBACManagedLabel]; !ok { // this isn't a hobbyfarm rolebinding. we don't serve your kind here glog.Error("permission denied: rolebinding not managed by hobbyfarm") - newErr := status.Newf( + return &rbacv1.RoleBinding{}, hferrors.GrpcError( codes.PermissionDenied, "rolebinding not managed by hobbyfarm", + req, ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() } return rolebinding, nil diff --git a/v3/services/rbacsvc/internal/grpc_roles.go b/v3/services/rbacsvc/internal/grpc_roles.go index 7e06cee1..440a5a87 100644 --- a/v3/services/rbacsvc/internal/grpc_roles.go +++ b/v3/services/rbacsvc/internal/grpc_roles.go @@ -5,50 +5,43 @@ import ( "fmt" "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/util" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - empty "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/emptypb" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/util/retry" ) -func (rs *GrpcRbacServer) CreateRole(c context.Context, cr *rbacProto.Role) (*empty.Empty, error) { +func (rs *GrpcRbacServer) CreateRole(c context.Context, cr *rbacpb.Role) (*emptypb.Empty, error) { role, err := marshalRole(cr) if err != nil { glog.Errorf("invalid role: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "invalid role", + cr, ) - newErr, wde := newErr.WithDetails(cr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - _, err = rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).Create(c, role, metav1.CreateOptions{}) + _, err = rs.roleClient.Create(c, role, metav1.CreateOptions{}) if err != nil { glog.Errorf("error creating role in kubernetes: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, - "internal error", + "error creating role", + cr, ) - newErr, wde := newErr.WithDetails(cr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (rs *GrpcRbacServer) GetRole(c context.Context, gr *rbacProto.ResourceId) (*rbacProto.Role, error) { +func (rs *GrpcRbacServer) GetRole(c context.Context, gr *generalpb.GetRequest) (*rbacpb.Role, error) { role, err := rs.getRole(c, gr) if err != nil { return nil, err @@ -56,109 +49,83 @@ func (rs *GrpcRbacServer) GetRole(c context.Context, gr *rbacProto.ResourceId) ( return unmarshalRole(role), nil } -func (rs *GrpcRbacServer) UpdateRole(c context.Context, ur *rbacProto.Role) (*empty.Empty, error) { +func (rs *GrpcRbacServer) UpdateRole(c context.Context, ur *rbacpb.Role) (*emptypb.Empty, error) { role, err := marshalRole(ur) if err != nil { glog.Errorf("invalid role: %v", err) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "invalid role", + ur, ) - newErr, wde := newErr.WithDetails(ur) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - _, err := rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).Update(c, role, metav1.UpdateOptions{}) + _, err := rs.roleClient.Update(c, role, metav1.UpdateOptions{}) if err != nil { glog.Errorf("error while updating role in kubernetes: %v", err) - newErr := status.Newf( + return hferrors.GrpcError( codes.Internal, - "internal error", + "error updating role", + ur, ) - newErr, wde := newErr.WithDetails(ur) - if wde != nil { - return wde - } - return newErr.Err() } return nil }) if retryErr != nil { - return &empty.Empty{}, retryErr + return &emptypb.Empty{}, retryErr } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (rs *GrpcRbacServer) DeleteRole(c context.Context, dr *rbacProto.ResourceId) (*empty.Empty, error) { +func (rs *GrpcRbacServer) DeleteRole(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { // we want to get the role first as this allows us to run it through the various checks before we attempt deletion // most important of which is checking that we have labeled it correctly // but it doesn't hurt to check if it exists before - role, err := rs.getRole(c, dr) + _, err := rs.getRole(ctx, &generalpb.GetRequest{Id: req.GetId()}) if err != nil { - return &empty.Empty{}, err + return &emptypb.Empty{}, err } - err = rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).Delete(c, role.Name, metav1.DeleteOptions{}) - if err != nil { - glog.Errorf("error deleting role in kubernetes: %v", err) - newErr := status.Newf( - codes.Internal, - "internal error", - ) - newErr, wde := newErr.WithDetails(dr) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() - } - return &empty.Empty{}, nil + return util.DeleteHfResource(ctx, req, rs.roleClient, "role") } -func (rs *GrpcRbacServer) ListRole(c context.Context, lr *empty.Empty) (*rbacProto.Roles, error) { - listOptions := metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%t", util.RBACManagedLabel, true), +func (rs *GrpcRbacServer) ListRole(ctx context.Context, listOptions *generalpb.ListOptions) (*rbacpb.Roles, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var roles []rbacv1.Role + var err error + if !doLoadFromCache { + var roleList *rbacv1.RoleList + roleList, err = util.ListByHfClient(ctx, listOptions, rs.roleClient, "roles") + if err == nil { + roles = roleList.Items + } + } else { + roles, err = util.ListByCache(listOptions, rs.roleLister, "roles", rs.roleSynced()) } - - roles, err := rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).List(c, listOptions) if err != nil { - if errors.IsNotFound(err) { - glog.Errorf("error: roles not found") - newErr := status.Newf( - codes.NotFound, - "roles not found", - ) - return &rbacProto.Roles{}, newErr.Err() - } - glog.Errorf("error in kubernetes while listing roles %v", err) - newErr := status.Newf( - codes.Internal, - "internal error", - ) - return &rbacProto.Roles{}, newErr.Err() + glog.Error(err) + return &rbacpb.Roles{}, err } - var preparedRoles = make([]*rbacProto.Role, 0) - for _, r := range roles.Items { + var preparedRoles = make([]*rbacpb.Role, 0) + for _, r := range roles { pr := unmarshalRole(&r) preparedRoles = append(preparedRoles, pr) } - return &rbacProto.Roles{Roles: preparedRoles}, nil + return &rbacpb.Roles{Roles: preparedRoles}, nil } -func marshalRole(preparedRole *rbacProto.Role) (*rbacv1.Role, error) { +func marshalRole(preparedRole *rbacpb.Role) (*rbacv1.Role, error) { role := rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: preparedRole.GetName(), Namespace: util.GetReleaseNamespace(), Labels: map[string]string{ - util.RBACManagedLabel: "true", + hflabels.RBACManagedLabel: "true", }, }, Rules: []rbacv1.PolicyRule{}, @@ -181,12 +148,12 @@ func marshalRole(preparedRole *rbacProto.Role) (*rbacv1.Role, error) { return &role, nil } -func unmarshalRole(role *rbacv1.Role) (preparedRole *rbacProto.Role) { - preparedRole = &rbacProto.Role{} +func unmarshalRole(role *rbacv1.Role) (preparedRole *rbacpb.Role) { + preparedRole = &rbacpb.Role{} preparedRole.Name = role.Name for _, r := range role.Rules { - preparedRole.Rules = append(preparedRole.Rules, &rbacProto.Rule{ + preparedRole.Rules = append(preparedRole.Rules, &rbacpb.Rule{ Resources: r.Resources, Verbs: r.Verbs, ApiGroups: r.APIGroups, @@ -196,58 +163,20 @@ func unmarshalRole(role *rbacv1.Role) (preparedRole *rbacProto.Role) { return preparedRole } -func (rs *GrpcRbacServer) getRole(c context.Context, gr *rbacProto.ResourceId) (*rbacv1.Role, error) { - if gr.GetId() == "" { - glog.Errorf("invalid role id") - newErr := status.Newf( - codes.InvalidArgument, - "invalid role id", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() - } - - role, err := rs.kubeClientSet.RbacV1().Roles(util.GetReleaseNamespace()).Get(c, gr.GetId(), metav1.GetOptions{}) +func (rs *GrpcRbacServer) getRole(ctx context.Context, req *generalpb.GetRequest) (*rbacv1.Role, error) { + role, err := util.GenericHfGetter(ctx, req, rs.roleClient, rs.roleLister.Roles(util.GetReleaseNamespace()), "role", rs.roleSynced()) if err != nil { - if errors.IsNotFound(err) { - glog.Errorf("role not found") - newErr := status.Newf( - codes.NotFound, - "role not found", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() - } - glog.Errorf("kubernetes error while getting role: %v", err) - newErr := status.Newf( - codes.Internal, - "internal server error", - ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() + return &rbacv1.Role{}, err } - if _, ok := role.Labels[util.RBACManagedLabel]; !ok { + if _, ok := role.Labels[hflabels.RBACManagedLabel]; !ok { // this isn't a hobbyfarm role. we don't serve your kind here glog.Error("permission denied: role not managed by hobbyfarm") - newErr := status.Newf( + return &rbacv1.Role{}, hferrors.GrpcError( codes.PermissionDenied, "role not managed by hobbyfarm", + req, ) - newErr, wde := newErr.WithDetails(gr) - if wde != nil { - return nil, wde - } - return nil, newErr.Err() } return role, nil diff --git a/v3/services/rbacsvc/internal/rbac/rbac_roles.go b/v3/services/rbacsvc/internal/rbac/rbac_roles.go index aedfd63a..c494c46b 100644 --- a/v3/services/rbacsvc/internal/rbac/rbac_roles.go +++ b/v3/services/rbacsvc/internal/rbac/rbac_roles.go @@ -3,6 +3,7 @@ package rbacinstaller import ( "context" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/util" wranglerRbac "github.com/rancher/wrangler/pkg/generated/controllers/rbac" rbacv1 "k8s.io/api/rbac/v1" @@ -98,7 +99,7 @@ func newRole(name string, customize func(Role) Role) Role { Name: name, Namespace: util.GetReleaseNamespace(), Labels: map[string]string{ - util.RBACManagedLabel: "true", + hflabels.RBACManagedLabel: "true", }, }, Rules: []rbacv1.PolicyRule{}, diff --git a/v3/services/rbacsvc/internal/rolebindings.go b/v3/services/rbacsvc/internal/rolebindings.go index cdac2867..b07e4284 100644 --- a/v3/services/rbacsvc/internal/rolebindings.go +++ b/v3/services/rbacsvc/internal/rolebindings.go @@ -2,16 +2,19 @@ package rbac import ( "encoding/json" + "fmt" "net/http" "github.com/golang/glog" "github.com/gorilla/mux" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" ) type PreparedRoleBinding struct { @@ -39,14 +42,12 @@ func (s Server) ListRoleBindings(w http.ResponseWriter, r *http.Request) { return } - bindings, err := s.internalRbacServer.ListRolebinding(r.Context(), &emptypb.Empty{}) + labelSelector := fmt.Sprintf("%s=%t", hflabels.RBACManagedLabel, true) + bindings, err := s.internalRbacServer.ListRolebinding(r.Context(), &generalpb.ListOptions{LabelSelector: labelSelector}) if err != nil { - if s, ok := status.FromError(err); ok { - switch s.Code() { - case codes.NotFound: - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", s.Message()) - return - } + if hferrors.IsGrpcNotFound(err) { + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", status.Convert(err).Message()) + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -84,20 +85,19 @@ func (s Server) GetRoleBinding(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) rolebindingId := vars["id"] - preparedRoleBinding, err := s.internalRbacServer.GetRolebinding(r.Context(), &rbacProto.ResourceId{Id: rolebindingId}) + preparedRoleBinding, err := s.internalRbacServer.GetRolebinding(r.Context(), &generalpb.GetRequest{Id: rolebindingId}) if err != nil { - if s, ok := status.FromError(err); ok { - switch s.Code() { - case codes.InvalidArgument: - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", s.Message()) - return - case codes.NotFound: - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", s.Message()) - return - case codes.PermissionDenied: - util.ReturnHTTPMessage(w, r, http.StatusForbidden, "forbidden", s.Message()) - return - } + statusErr := status.Convert(err) + switch statusErr.Code() { + case codes.InvalidArgument: + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", statusErr.Message()) + return + case codes.NotFound: + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", statusErr.Message()) + return + case codes.PermissionDenied: + util.ReturnHTTPMessage(w, r, http.StatusForbidden, "forbidden", statusErr.Message()) + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -127,7 +127,7 @@ func (s Server) CreateRoleBinding(w http.ResponseWriter, r *http.Request) { return } - var preparedRoleBinding *rbacProto.RoleBinding + var preparedRoleBinding *rbacpb.RoleBinding err = json.NewDecoder(r.Body).Decode(&preparedRoleBinding) if err != nil { glog.Errorf("error decoding json from create rolebinding request: %v", err) @@ -137,11 +137,9 @@ func (s Server) CreateRoleBinding(w http.ResponseWriter, r *http.Request) { _, err = s.internalRbacServer.CreateRolebinding(r.Context(), preparedRoleBinding) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -164,7 +162,7 @@ func (s Server) UpdateRoleBinding(w http.ResponseWriter, r *http.Request) { return } - var preparedRoleBinding *rbacProto.RoleBinding + var preparedRoleBinding *rbacpb.RoleBinding err = json.NewDecoder(r.Body).Decode(&preparedRoleBinding) if err != nil { glog.Errorf("error decoding json from update rolebinding request: %v", err) @@ -174,11 +172,9 @@ func (s Server) UpdateRoleBinding(w http.ResponseWriter, r *http.Request) { _, err = s.internalRbacServer.UpdateRolebinding(r.Context(), preparedRoleBinding) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -204,13 +200,11 @@ func (s Server) DeleteRoleBinding(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) rolebindingId := vars["id"] - _, err = s.internalRbacServer.DeleteRolebinding(r.Context(), &rbacProto.ResourceId{Id: rolebindingId}) + _, err = s.internalRbacServer.DeleteRolebinding(r.Context(), &generalpb.ResourceId{Id: rolebindingId}) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid rolebinding") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -219,7 +213,7 @@ func (s Server) DeleteRoleBinding(w http.ResponseWriter, r *http.Request) { util.ReturnHTTPMessage(w, r, http.StatusOK, "deleted", "deleted") } -func (s Server) prepareRoleBinding(roleBinding *rbacProto.RoleBinding) PreparedRoleBinding { +func (s Server) prepareRoleBinding(roleBinding *rbacpb.RoleBinding) PreparedRoleBinding { prb := PreparedRoleBinding{ Name: roleBinding.GetName(), Role: roleBinding.GetRole(), diff --git a/v3/services/rbacsvc/internal/roles.go b/v3/services/rbacsvc/internal/roles.go index ae1a54e8..6d94116c 100644 --- a/v3/services/rbacsvc/internal/roles.go +++ b/v3/services/rbacsvc/internal/roles.go @@ -2,16 +2,19 @@ package rbac import ( "encoding/json" + "fmt" "net/http" "github.com/golang/glog" "github.com/gorilla/mux" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" ) type PreparedRole struct { @@ -39,14 +42,12 @@ func (s Server) ListRoles(w http.ResponseWriter, r *http.Request) { return } - roles, err := s.internalRbacServer.ListRole(r.Context(), &emptypb.Empty{}) + labelSelector := fmt.Sprintf("%s=%t", hflabels.RBACManagedLabel, true) + roles, err := s.internalRbacServer.ListRole(r.Context(), &generalpb.ListOptions{LabelSelector: labelSelector}) if err != nil { - if s, ok := status.FromError(err); ok { - switch s.Code() { - case codes.NotFound: - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", s.Message()) - return - } + if hferrors.IsGrpcNotFound(err) { + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", status.Convert(err).Message()) + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -84,20 +85,19 @@ func (s Server) GetRole(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) roleId := vars["id"] - preparedRole, err := s.internalRbacServer.GetRole(r.Context(), &rbacProto.ResourceId{Id: roleId}) + preparedRole, err := s.internalRbacServer.GetRole(r.Context(), &generalpb.GetRequest{Id: roleId}) if err != nil { - if s, ok := status.FromError(err); ok { - switch s.Code() { - case codes.InvalidArgument: - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", s.Message()) - return - case codes.NotFound: - util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", s.Message()) - return - case codes.PermissionDenied: - util.ReturnHTTPMessage(w, r, http.StatusForbidden, "forbidden", s.Message()) - return - } + statusErr := status.Convert(err) + switch statusErr.Code() { + case codes.InvalidArgument: + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", statusErr.Message()) + return + case codes.NotFound: + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "notfound", statusErr.Message()) + return + case codes.PermissionDenied: + util.ReturnHTTPMessage(w, r, http.StatusForbidden, "forbidden", statusErr.Message()) + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -127,7 +127,7 @@ func (s Server) CreateRole(w http.ResponseWriter, r *http.Request) { return } - var preparedRole *rbacProto.Role + var preparedRole *rbacpb.Role err = json.NewDecoder(r.Body).Decode(&preparedRole) if err != nil { glog.Errorf("error decoding json from create role request: %v", err) @@ -137,11 +137,9 @@ func (s Server) CreateRole(w http.ResponseWriter, r *http.Request) { _, err = s.internalRbacServer.CreateRole(r.Context(), preparedRole) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -164,7 +162,7 @@ func (s Server) UpdateRole(w http.ResponseWriter, r *http.Request) { return } - var preparedRole *rbacProto.Role + var preparedRole *rbacpb.Role err = json.NewDecoder(r.Body).Decode(&preparedRole) if err != nil { glog.Errorf("error decoding json from update role request: %v", err) @@ -174,11 +172,9 @@ func (s Server) UpdateRole(w http.ResponseWriter, r *http.Request) { _, err = s.internalRbacServer.UpdateRole(r.Context(), preparedRole) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -204,13 +200,11 @@ func (s Server) DeleteRole(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) roleId := vars["id"] - _, err = s.internalRbacServer.DeleteRole(r.Context(), &rbacProto.ResourceId{Id: roleId}) + _, err = s.internalRbacServer.DeleteRole(r.Context(), &generalpb.ResourceId{Id: roleId}) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") - return - } + if status.Convert(err).Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, http.StatusBadRequest, "badrequest", "invalid role") + return } util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error") return @@ -219,7 +213,7 @@ func (s Server) DeleteRole(w http.ResponseWriter, r *http.Request) { util.ReturnHTTPMessage(w, r, http.StatusOK, "deleted", "deleted") } -func (s Server) prepareRole(role *rbacProto.Role) (preparedRole PreparedRole) { +func (s Server) prepareRole(role *rbacpb.Role) (preparedRole PreparedRole) { pr := PreparedRole{ Name: role.GetName(), Rules: []PreparedRule{}, diff --git a/v3/services/rbacsvc/internal/server.go b/v3/services/rbacsvc/internal/server.go index 611804a9..a24078f7 100644 --- a/v3/services/rbacsvc/internal/server.go +++ b/v3/services/rbacsvc/internal/server.go @@ -2,17 +2,17 @@ package rbac import ( "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" ) type Server struct { internalRbacServer *GrpcRbacServer - authnClient authn.AuthNClient - authrClient authr.AuthRClient + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient } -func NewRbacServer(internalRbacServer *GrpcRbacServer, authnClient authn.AuthNClient, authrClient authr.AuthRClient) *Server { +func NewRbacServer(internalRbacServer *GrpcRbacServer, authnClient authnpb.AuthNClient, authrClient authrpb.AuthRClient) *Server { return &Server{ internalRbacServer: internalRbacServer, authnClient: authnClient, diff --git a/v3/services/rbacsvc/main.go b/v3/services/rbacsvc/main.go index c12f25e5..1657c860 100644 --- a/v3/services/rbacsvc/main.go +++ b/v3/services/rbacsvc/main.go @@ -12,9 +12,9 @@ import ( "github.com/hobbyfarm/gargantua/v3/pkg/microservices" "github.com/hobbyfarm/gargantua/v3/pkg/signals" "github.com/hobbyfarm/gargantua/v3/pkg/util" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" ) @@ -54,7 +54,7 @@ func main() { if err != nil { glog.Fatalf("Failed to start rbac grpc server: %s", err) } - rbacProto.RegisterRbacSvcServer(gs, rs) + rbacpb.RegisterRbacSvcServer(gs, rs) services := []microservices.MicroService{ microservices.AuthN, @@ -65,18 +65,18 @@ func main() { defer conn.Close() } - authnClient := authn.NewAuthNClient(connections[microservices.AuthN]) - authrClient := authr.NewAuthRClient(connections[microservices.AuthR]) + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) var wg sync.WaitGroup - + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates wg.Add(1) + go func() { defer wg.Done() microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) }() - wg.Add(1) go func() { defer wg.Done() rbacServer := rbacservice.NewRbacServer(rs, authnClient, authrClient) diff --git a/v3/services/scenariosvc/Dockerfile b/v3/services/scenariosvc/Dockerfile new file mode 100644 index 00000000..4850468b --- /dev/null +++ b/v3/services/scenariosvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/scenariosvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/scenariosvc/go.mod b/v3/services/scenariosvc/go.mod new file mode 100644 index 00000000..1cd8eb40 --- /dev/null +++ b/v3/services/scenariosvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/scenariosvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/scenariosvc/go.sum b/v3/services/scenariosvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/scenariosvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/scenariosvc/internal/crd.go b/v3/services/scenariosvc/internal/crd.go new file mode 100644 index 00000000..03f20960 --- /dev/null +++ b/v3/services/scenariosvc/internal/crd.go @@ -0,0 +1,21 @@ +package scenarioservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// ScenarioCRDInstaller is a struct that can generate CRDs for scenarios. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type ScenarioCRDInstaller struct{} + +func (si ScenarioCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.Scenario{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.Scenario{}, nil) + }), + } +} diff --git a/v3/services/scenariosvc/internal/grpc.go b/v3/services/scenariosvc/internal/grpc.go new file mode 100644 index 00000000..d3444899 --- /dev/null +++ b/v3/services/scenariosvc/internal/grpc.go @@ -0,0 +1,410 @@ +package scenarioservice + +import ( + "context" + "encoding/base64" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcScenarioServer struct { + scenariopb.UnimplementedScenarioSvcServer + scenarioClient hfClientsetv1.ScenarioInterface + scenarioLister listersv1.ScenarioLister + scenarioSynced cache.InformerSynced +} + +func NewGrpcScenarioServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcScenarioServer { + return &GrpcScenarioServer{ + scenarioClient: hfClientSet.HobbyfarmV1().Scenarios(util.GetReleaseNamespace()), + scenarioLister: hfInformerFactory.Hobbyfarm().V1().Scenarios().Lister(), + scenarioSynced: hfInformerFactory.Hobbyfarm().V1().Scenarios().Informer().HasSynced, + } +} + +func (s *GrpcScenarioServer) CreateScenario(ctx context.Context, req *scenariopb.CreateScenarioRequest) (*generalpb.ResourceId, error) { + name := req.GetName() + description := req.GetDescription() + rawSteps := req.GetRawSteps() + rawCategories := req.GetRawCategories() + rawTags := req.GetRawTags() + rawVirtualMachines := req.GetRawVms() + rawVmTasks := req.GetRawVmTasks() + keepaliveDuration := req.GetKeepaliveDuration() + pauseDuration := req.GetPauseDuration() + pausable := req.GetPausable() + + requiredStringParams := map[string]string{ + "name": name, + "description": description, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + id := util.GenerateResourceName("s", name, 10) + + scenario := &hfv1.Scenario{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + Labels: make(map[string]string), + }, + Spec: hfv1.ScenarioSpec{ + Name: name, + Description: description, + KeepAliveDuration: keepaliveDuration, + PauseDuration: pauseDuration, + Pauseable: pausable, + }, + } + + if rawSteps != "" { + steps, err := util.GenericUnmarshal[[]hfv1.ScenarioStep](rawSteps, "raw_steps") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "raw_steps") + } + scenario.Spec.Steps = steps + } + if rawCategories != "" { + categories, err := util.GenericUnmarshal[[]string](rawCategories, "raw_categories") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "raw_categories") + } + updatedLabels := labels.UpdateCategoryLabels(scenario.ObjectMeta.Labels, []string{}, categories) + scenario.ObjectMeta.Labels = updatedLabels + scenario.Spec.Categories = categories + } + if rawTags != "" { + tags, err := util.GenericUnmarshal[[]string](rawTags, "raw_tags") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "raw_tags") + } + scenario.Spec.Tags = tags + } + if rawVirtualMachines != "" { + vms, err := util.GenericUnmarshal[[]map[string]string](rawVirtualMachines, "raw_vms") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "raw_vms") + } + scenario.Spec.VirtualMachines = vms + } + if rawVmTasks != "" { + vmTasks, err := util.GenericUnmarshal[[]hfv1.VirtualMachineTasks](rawSteps, "raw_vm_tasks") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "raw_vm_tasks") + } + scenario.Spec.Tasks = vmTasks + } + err := util.VerifyTaskContent(scenario.Spec.Tasks, req) + if err != nil { + return &generalpb.ResourceId{}, err + } + + _, err = s.scenarioClient.Create(ctx, scenario, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: id}, nil +} + +func (s *GrpcScenarioServer) GetScenario(ctx context.Context, req *generalpb.GetRequest) (*scenariopb.Scenario, error) { + scenario, err := util.GenericHfGetter(ctx, req, s.scenarioClient, s.scenarioLister.Scenarios(util.GetReleaseNamespace()), "scenario", s.scenarioSynced()) + if err != nil { + return &scenariopb.Scenario{}, err + } + + scenarioSteps := []*scenariopb.ScenarioStep{} + for _, step := range scenario.Spec.Steps { + scenarioSteps = append(scenarioSteps, &scenariopb.ScenarioStep{Title: step.Title, Content: step.Content}) + } + + vms := []*generalpb.StringMap{} + for _, vm := range scenario.Spec.VirtualMachines { + vms = append(vms, &generalpb.StringMap{Value: vm}) + } + + vmTasks := []*scenariopb.VirtualMachineTasks{} + for _, vmtask := range scenario.Spec.Tasks { + tasks := []*scenariopb.Task{} + for _, task := range vmtask.Tasks { + tasks = append(tasks, &scenariopb.Task{ + Name: task.Name, + Description: task.Description, + Command: task.Command, + ExpectedOutputValue: task.ExpectedOutputValue, + ExpectedReturnCode: int32(task.ExpectedReturnCode), + ReturnType: task.ReturnType, + }) + } + vmTasks = append(vmTasks, &scenariopb.VirtualMachineTasks{ + VmName: vmtask.VMName, + Tasks: tasks, + }) + } + + return &scenariopb.Scenario{ + Id: scenario.Name, + Uid: string(scenario.UID), + Name: scenario.Spec.Name, + Description: scenario.Spec.Description, + Steps: scenarioSteps, + Categories: scenario.Spec.Categories, + Tags: scenario.Spec.Tags, + Vms: vms, + KeepaliveDuration: scenario.Spec.KeepAliveDuration, + PauseDuration: scenario.Spec.PauseDuration, + Pausable: scenario.Spec.Pauseable, + VmTasks: vmTasks, + Labels: scenario.Labels, + }, nil +} + +func (s *GrpcScenarioServer) UpdateScenario(ctx context.Context, req *scenariopb.UpdateScenarioRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + name := req.GetName() + description := req.GetDescription() + rawSteps := req.GetRawSteps() + rawCategories := req.GetRawCategories() + rawTags := req.GetRawTags() + rawVirtualMachines := req.GetRawVms() + rawVmTasks := req.GetRawVmTasks() + keepaliveDuration := req.GetKeepaliveDuration() + pauseDuration := req.GetPauseDuration() + pausable := req.GetPausable() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + scenario, err := s.scenarioClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving scenario %s", + req, + req.GetId(), + ) + } + if name != "" { + scenario.Spec.Name = name + } + if description != "" { + scenario.Spec.Description = description + } + if keepaliveDuration != nil { + scenario.Spec.KeepAliveDuration = keepaliveDuration.GetValue() + } + if pauseDuration != nil { + scenario.Spec.PauseDuration = pauseDuration.GetValue() + } + if pausable != nil { + scenario.Spec.Pauseable = pausable.GetValue() + } + if rawSteps != "" { + steps, err := util.GenericUnmarshal[[]hfv1.ScenarioStep](rawSteps, "raw_steps") + if err != nil { + return hferrors.GrpcParsingError(req, "raw_steps") + } + scenario.Spec.Steps = steps + } + if rawCategories != "" { + newCategories, err := util.GenericUnmarshal[[]string](rawCategories, "raw_categories") + if err != nil { + return hferrors.GrpcParsingError(req, "raw_categories") + } + oldCategories := scenario.Spec.Categories + updatedLabels := labels.UpdateCategoryLabels(scenario.ObjectMeta.Labels, oldCategories, newCategories) + scenario.Spec.Categories = newCategories + scenario.ObjectMeta.Labels = updatedLabels + } + if rawTags != "" { + tags, err := util.GenericUnmarshal[[]string](rawTags, "raw_tags") + if err != nil { + return hferrors.GrpcParsingError(req, "raw_tags") + } + scenario.Spec.Tags = tags + } + if rawVirtualMachines != "" { + vms, err := util.GenericUnmarshal[[]map[string]string](rawVirtualMachines, "raw_vms") + if err != nil { + return hferrors.GrpcParsingError(req, "raw_vms") + } + scenario.Spec.VirtualMachines = vms + } + if rawVmTasks != "" { + vmTasks, err := util.GenericUnmarshal[[]hfv1.VirtualMachineTasks](rawSteps, "raw_vm_tasks") + if err != nil { + return hferrors.GrpcParsingError(req, "raw_vm_tasks") + } + scenario.Spec.Tasks = vmTasks + } + err = util.VerifyTaskContent(scenario.Spec.Tasks, req) + if err != nil { + return err + } + + _, updateErr := s.scenarioClient.Update(ctx, scenario, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcScenarioServer) DeleteScenario(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.scenarioClient, "scenario") +} + +func (s *GrpcScenarioServer) DeleteCollectionScenario(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.scenarioClient, "scenarios") +} + +func (s *GrpcScenarioServer) ListScenario(ctx context.Context, listOptions *generalpb.ListOptions) (*scenariopb.ListScenariosResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var scenarios []hfv1.Scenario + var err error + if !doLoadFromCache { + var scenarioList *hfv1.ScenarioList + scenarioList, err = util.ListByHfClient(ctx, listOptions, s.scenarioClient, "scenarios") + if err == nil { + scenarios = scenarioList.Items + } + } else { + scenarios, err = util.ListByCache(listOptions, s.scenarioLister, "scenarios", s.scenarioSynced()) + } + if err != nil { + glog.Error(err) + return &scenariopb.ListScenariosResponse{}, err + } + + preparedScenarios := []*scenariopb.Scenario{} + + for _, scenario := range scenarios { + + scenarioSteps := []*scenariopb.ScenarioStep{} + for _, step := range scenario.Spec.Steps { + scenarioSteps = append(scenarioSteps, &scenariopb.ScenarioStep{Title: step.Title, Content: step.Content}) + } + + vms := []*generalpb.StringMap{} + for _, vm := range scenario.Spec.VirtualMachines { + vms = append(vms, &generalpb.StringMap{Value: vm}) + } + + vmTasks := []*scenariopb.VirtualMachineTasks{} + for _, vmtask := range scenario.Spec.Tasks { + tasks := []*scenariopb.Task{} + for _, task := range vmtask.Tasks { + tasks = append(tasks, &scenariopb.Task{ + Name: task.Name, + Description: task.Description, + Command: task.Command, + ExpectedOutputValue: task.ExpectedOutputValue, + ExpectedReturnCode: int32(task.ExpectedReturnCode), + ReturnType: task.ReturnType, + }) + } + vmTasks = append(vmTasks, &scenariopb.VirtualMachineTasks{ + VmName: vmtask.VMName, + Tasks: tasks, + }) + } + + preparedScenarios = append(preparedScenarios, &scenariopb.Scenario{ + Id: scenario.Name, + Uid: string(scenario.UID), + Name: scenario.Spec.Name, + Description: scenario.Spec.Description, + Steps: scenarioSteps, + Categories: scenario.Spec.Categories, + Tags: scenario.Spec.Tags, + Vms: vms, + KeepaliveDuration: scenario.Spec.KeepAliveDuration, + PauseDuration: scenario.Spec.PauseDuration, + Pausable: scenario.Spec.Pauseable, + VmTasks: vmTasks, + Labels: scenario.Labels, + }) + } + + return &scenariopb.ListScenariosResponse{Scenarios: preparedScenarios}, nil +} + +func (s *GrpcScenarioServer) CopyScenario(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + glog.V(2).Info("error no id provided for scenario") + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + scenario, err := s.scenarioClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return &emptypb.Empty{}, hferrors.GrpcNotFoundError(req, "scenario") + } + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error while retrieving scenario %s", + req, + id, + ) + } + name, err := base64.StdEncoding.DecodeString(scenario.Spec.Name) + if err != nil { + glog.Errorf("Error decoding title of scenario %s to copy: %v", scenario.Name, err) + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error while retrieving scenario %s", + req, + id, + ) + } + copyName := string(name) + " - Copy" + copyName = base64.StdEncoding.EncodeToString([]byte(copyName)) + copyId := util.GenerateResourceName("s", copyName, 10) + + scenario.Name = copyId + scenario.Spec.Name = copyName + + _, err = s.scenarioClient.Create(ctx, scenario, metav1.CreateOptions{}) + if err != nil { + glog.Errorf("Error attempting to create a copy of scenario %s: %v", id, err) + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to copy scenario %s", + req, + id, + ) + } + return &emptypb.Empty{}, nil +} diff --git a/v3/services/scenariosvc/internal/scenarioservice.go b/v3/services/scenariosvc/internal/scenarioservice.go new file mode 100644 index 00000000..e222a406 --- /dev/null +++ b/v3/services/scenariosvc/internal/scenarioservice.go @@ -0,0 +1,810 @@ +package scenarioservice + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "slices" + "strconv" + "strings" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/protobuf/types/known/wrapperspb" + + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +const ( + idIndex = "scenarioserver.hobbyfarm.io/id-index" + resourcePlural = rbac.ResourcePluralScenario +) + +type PreparedScenarioStep struct { + Title string `json:"title"` + Content string `json:"content"` +} + +type PreparedScenario struct { + Id string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + StepCount int `json:"stepcount"` + VirtualMachines []map[string]string `json:"virtualmachines"` + Pauseable bool `json:"pauseable"` + Printable bool `json:"printable"` + Tasks []*scenariopb.VirtualMachineTasks `json:"vm_tasks"` +} + +type AdminPreparedScenario struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Steps []*scenariopb.ScenarioStep `json:"steps"` + Categories []string `json:"categories"` + Tags []string `json:"tags"` + VirtualMachines []map[string]string `json:"virtualmachines"` + KeepAliveDuration string `json:"keepalive_duration"` + PauseDuration string `json:"pause_duration"` + Pauseable bool `json:"pauseable"` + Tasks []*scenariopb.VirtualMachineTasks `json:"vm_tasks"` +} + +func (s ScenarioServer) prepareScenario(scenario *scenariopb.Scenario, printable bool) PreparedScenario { + return PreparedScenario{ + Id: scenario.GetId(), + Name: scenario.GetName(), + Description: scenario.GetDescription(), + VirtualMachines: util.ConvertToStringMapSlice(scenario.GetVms()), + Pauseable: scenario.GetPausable(), + Printable: printable, + StepCount: len(scenario.GetSteps()), + Tasks: scenario.GetVmTasks(), + } +} + +func (s ScenarioServer) getPreparedScenarioStepById(ctx context.Context, id string, step int) (PreparedScenarioStep, error) { + scenario, err := s.internalScenarioServer.GetScenario(ctx, &generalpb.GetRequest{Id: id, LoadFromCache: true}) + if err != nil { + return PreparedScenarioStep{}, fmt.Errorf("error while retrieving scenario step") + } + + if step >= 0 && len(scenario.GetSteps()) > step { + stepContent := scenario.GetSteps()[step] + return PreparedScenarioStep{stepContent.GetTitle(), stepContent.GetContent()}, nil + } + + return PreparedScenarioStep{}, fmt.Errorf("error while retrieving scenario step, most likely doesn't exist in cache") +} + +func (s ScenarioServer) getPrintableScenarioIds(ctx context.Context, accessCodes []string) []string { + var printableScenarioIds []string + var printableCourseIds []string + accessCodeList, err := s.acClient.GetAccessCodesWithOTACs(ctx, &accesscodepb.ResourceIds{Ids: accessCodes}) + if err != nil { + glog.Errorf("error retrieving access codes: %s", hferrors.GetErrorMessage(err)) + return []string{} + } + for _, accessCode := range accessCodeList.GetAccessCodes() { + if !accessCode.GetPrintable() { + continue + } + printableScenarioIds = append(printableScenarioIds, accessCode.GetScenarios()...) + printableCourseIds = append(printableCourseIds, accessCode.GetCourses()...) + } + printableCourseIds = util.UniqueStringSlice(printableCourseIds) + + for _, courseId := range printableCourseIds { + course, err := s.courseClient.GetCourse(ctx, &generalpb.GetRequest{Id: courseId, LoadFromCache: true}) + if err != nil { + glog.Errorf("error retrieving course %s", hferrors.GetErrorMessage(err)) + continue + } + dynamicScenarios := util.AppendDynamicScenariosByCategories( + ctx, + course.GetScenarios(), + course.GetCategories(), + s.internalScenarioServer.ListScenario, + ) + printableScenarioIds = append(printableScenarioIds, dynamicScenarios...) + } + + printableScenarioIds = util.UniqueStringSlice(printableScenarioIds) + return printableScenarioIds +} + +func (s ScenarioServer) getPreparedScenarioById(ctx context.Context, id string, accessCodes []string) (PreparedScenario, error) { + scenario, err := s.internalScenarioServer.GetScenario(ctx, &generalpb.GetRequest{Id: id, LoadFromCache: true}) + if err != nil { + return PreparedScenario{}, fmt.Errorf("error while retrieving scenario: %s", hferrors.GetErrorMessage(err)) + } + + printableScenarioIds := s.getPrintableScenarioIds(ctx, accessCodes) + printable := slices.Contains(printableScenarioIds, scenario.GetId()) + + preparedScenario := s.prepareScenario(scenario, printable) + + return preparedScenario, nil +} + +func (s ScenarioServer) GetScenarioFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scenarios") + return + } + + vars := mux.Vars(r) + + scenario_id := vars["scenario_id"] + + if len(scenario_id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no scenario id passed in") + return + } + + scenario, err := s.getPreparedScenarioById(r.Context(), scenario_id, user.AccessCodes) + if err != nil { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s not found", vars["scenario_id"])) + return + } + encodedScenario, err := json.Marshal(scenario) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScenario) +} + +func (s ScenarioServer) AdminGetFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no id passed in") + return + } + + scenario, err := s.internalScenarioServer.GetScenario(r.Context(), &generalpb.GetRequest{ + Id: id, + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error while retrieving scenario %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") + return + } + + preparedScenario := AdminPreparedScenario{ + ID: scenario.GetId(), + Name: scenario.GetName(), + Description: scenario.GetDescription(), + Steps: scenario.GetSteps(), + Categories: scenario.GetCategories(), + Tags: scenario.GetTags(), + VirtualMachines: util.ConvertToStringMapSlice(scenario.GetVms()), + KeepAliveDuration: scenario.GetKeepaliveDuration(), + PauseDuration: scenario.GetPauseDuration(), + Pauseable: scenario.GetPausable(), + Tasks: scenario.GetVmTasks(), + } + + encodedScenario, err := json.Marshal(preparedScenario) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScenario) + + glog.V(2).Infof("retrieved scenario %s", scenario.Name) +} + +func (s ScenarioServer) AdminDeleteFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbDelete)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete Scenario") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "error", "no id passed in") + return + } + + // when can we safely a scenario? + // 1. when there are no active scheduled events using the scenario + // 2. when there are no sessions using the scenario + // 3. when there is no course using the scenario + + seList, err := s.scheduledEventClient.ListScheduledEvent(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error retrieving scheduledevent list: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") + return + } + + seInUse := util.FilterScheduledEvents(id, seList, util.FilterByScenario[*scheduledeventpb.ScheduledEvent]) + + sessList, err := s.sessionClient.ListSession(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error retrieving session list: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") + return + } + + sessInUse := util.FilterSessions(id, sessList, util.IsSessionOfScenario) + + courseList, err := s.courseClient.ListCourse(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error retrieving course list: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error while deleting scenario") + return + } + + coursesInUse := filterCourses(id, courseList) + + var msg = "" + toDelete := true + + if len(seInUse) > 0 { + // cannot toDelete, in use. alert the user + msg += "In use by scheduled events:" + for _, se := range seInUse { + msg += " " + se.GetId() + } + toDelete = false + } + + if len(sessInUse) > 0 { + msg += "In use by sessions:" + for _, sess := range sessInUse { + msg += " " + sess.GetId() + } + toDelete = false + } + + if len(coursesInUse) > 0 { + msg += "In use by courses:" + for _, course := range coursesInUse { + msg += " " + course.GetId() + } + toDelete = false + } + + if !toDelete { + util.ReturnHTTPMessage(w, r, 403, "badrequest", msg) + return + } + + _, err = s.internalScenarioServer.DeleteScenario(r.Context(), &generalpb.ResourceId{Id: id}) + + if err != nil { + glog.Errorf("error while deleting scenario %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "scenario could not be deleted") + return + } + util.ReturnHTTPMessage(w, r, 200, "success", "scenario deleted") + glog.V(2).Infof("deleted scenario %s", id) +} + +func (s ScenarioServer) GetScenarioStepFunc(w http.ResponseWriter, r *http.Request) { + _, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scenario steps") + return + } + + vars := mux.Vars(r) + + stepId, err := strconv.Atoi(vars["step_id"]) + if err != nil { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s step %s not found", vars["scenario_id"], vars["step_id"])) + return + } + step, err := s.getPreparedScenarioStepById(r.Context(), vars["scenario_id"], stepId) + if err != nil { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("scenario %s not found", vars["scenario_id"])) + return + } + encodedStep, err := json.Marshal(step) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedStep) + +} + +func (s ScenarioServer) ListScenariosForAccessCode(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios") + return + } + + vars := mux.Vars(r) + accessCode := vars["access_code"] + + if accessCode == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "access_code is missing") + return + } + + if !slices.Contains(user.AccessCodes, accessCode) { + + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios for this AccessCode") + return + } + + // store a list of scenarios linked to courses for filtering + //var courseScenarios []string + var scenarioIds []string + ac, err := s.acClient.GetAccessCodeWithOTACs(r.Context(), &generalpb.ResourceId{Id: accessCode}) + if err != nil { + glog.Errorf("error retrieving access code %s: %s", accessCode, hferrors.GetErrorMessage(err)) + } + scenarioIds = append(scenarioIds, ac.GetScenarios()...) + + var scenarios []PreparedScenario + for _, scenarioId := range scenarioIds { + scenario, err := s.internalScenarioServer.GetScenario(r.Context(), &generalpb.GetRequest{ + Id: scenarioId, + LoadFromCache: true, + }) + if err != nil { + glog.Errorf("error retrieving scenario: %s", hferrors.GetErrorMessage(err)) + continue + } + pScenario := s.prepareScenario(scenario, ac.GetPrintable()) + scenarios = append(scenarios, pScenario) + } + + encodedScenarios, err := json.Marshal(scenarios) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) +} + +func (s ScenarioServer) ListAllFunc(w http.ResponseWriter, r *http.Request) { + s.ListFunc(w, r, "") +} + +func (s ScenarioServer) ListByCategoryFunc(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + category := vars["category"] + + if len(category) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no category passed in") + return + } + + s.ListFunc(w, r, category) +} + +func (s ScenarioServer) ListFunc(w http.ResponseWriter, r *http.Request, category string) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scenarios") + return + } + + categorySelector := &generalpb.ListOptions{} + if category != "" { + categorySelector = &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("category-%s=true", category), + } + } + + scenarioList, err := s.internalScenarioServer.ListScenario(r.Context(), categorySelector) + + if err != nil { + glog.Errorf("error while retrieving scenarios %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scenarios found") + return + } + + preparedScenarios := []AdminPreparedScenario{} + for _, scenario := range scenarioList.GetScenarios() { + pScenario := AdminPreparedScenario{ + ID: scenario.GetId(), + Name: scenario.GetName(), + Description: scenario.GetDescription(), + Steps: nil, + Categories: scenario.GetCategories(), + Tags: scenario.GetTags(), + VirtualMachines: util.ConvertToStringMapSlice(scenario.GetVms()), + KeepAliveDuration: scenario.GetKeepaliveDuration(), + PauseDuration: scenario.GetPauseDuration(), + Pauseable: scenario.GetPausable(), + Tasks: scenario.GetVmTasks(), + } + preparedScenarios = append(preparedScenarios, pScenario) + } + + encodedScenarios, err := json.Marshal(preparedScenarios) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScenarios) + + glog.V(2).Infof("listed scenarios") +} + +func (s ScenarioServer) ListCategories(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list categories") + return + } + + scenarioList, err := s.internalScenarioServer.ListScenario(r.Context(), &generalpb.ListOptions{}) + + if err != nil { + glog.Errorf("error while retrieving scenarios %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scenarios found") + return + } + + categorySlice := []string{} + + for _, scenario := range scenarioList.GetScenarios() { + categories := scenario.GetCategories() + if len(categories) != 0 { + categorySlice = append(categorySlice, categories...) + } + } + + // Sort + Compact creates a unique sorted slice + slices.Sort(categorySlice) + slices.Compact(categorySlice) + + encodedCategories, err := json.Marshal(categorySlice) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedCategories) + + glog.V(2).Infof("listed categories") +} + +func (s ScenarioServer) AdminPrintFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no id passed in") + return + } + + scenario, err := s.internalScenarioServer.GetScenario(r.Context(), &generalpb.GetRequest{ + Id: id, + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error while retrieving scenario: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") + return + } + + content := preparePrintableContent(scenario) + + util.ReturnHTTPRaw(w, r, content) + + glog.V(2).Infof("retrieved scenario and rendered for printability %s", id) +} + +func (s ScenarioServer) PrintFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get Scenario") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no id passed in") + return + } + + printableScenarioIds := s.getPrintableScenarioIds(r.Context(), user.GetAccessCodes()) + + if !slices.Contains(printableScenarioIds, id) { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get this Scenario") + return + } + + scenario, err := s.internalScenarioServer.GetScenario(r.Context(), &generalpb.GetRequest{ + Id: id, + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error while retrieving scenario %s: %s", id, hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scenario found") + return + } + + content := preparePrintableContent(scenario) + + util.ReturnHTTPRaw(w, r, content) + + glog.V(2).Infof("retrieved scenario and rendered for printability %s", id) +} + +func (s ScenarioServer) CopyFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.Authorize(r, s.authrClient, impersonatedUserId, []*authrpb.Permission{ + rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate), + rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet), + }, rbac.OperatorAND) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scenarios") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no id passed in") + return + } + + _, err = s.internalScenarioServer.CopyScenario(r.Context(), &generalpb.ResourceId{Id: id}) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("error attempting to copy: scenario %s not found", id)) + return + } else { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error attempting to copy") + return + } + } + util.ReturnHTTPMessage(w, r, 200, "copied scenario", "") +} + +func (s ScenarioServer) CreateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scenarios") + return + } + + name := r.PostFormValue("name") + if name == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") + return + } + description := r.PostFormValue("description") + if description == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") + return + } + + keepaliveDuration := r.PostFormValue("keepalive_duration") + // we won't error if no keep alive duration is passed in or if it's blank because we'll default elsewhere + + rawSteps := r.PostFormValue("steps") + rawCategories := r.PostFormValue("categories") + rawTags := r.PostFormValue("tags") + rawVirtualMachines := r.PostFormValue("virtualmachines") + rawVMTasks := r.PostFormValue("vm_tasks") + + pauseable := r.PostFormValue("pauseable") + pauseableBool := false + if pauseable != "" { + if strings.ToLower(pauseable) == "true" { + pauseableBool = true + } + } + pauseDuration := r.PostFormValue("pause_duration") + + scenarioId, err := s.internalScenarioServer.CreateScenario(r.Context(), &scenariopb.CreateScenarioRequest{ + Name: name, + Description: description, + RawSteps: rawSteps, + RawCategories: rawCategories, + RawTags: rawTags, + RawVms: rawVirtualMachines, + RawVmTasks: rawVMTasks, + KeepaliveDuration: keepaliveDuration, + PauseDuration: pauseDuration, + Pausable: pauseableBool, + }) + if err != nil { + glog.Errorf("error creating scenario %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scenario") + return + } + + util.ReturnHTTPMessage(w, r, 201, "created", scenarioId.GetId()) +} + +func (s ScenarioServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scenarios") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + name := r.PostFormValue("name") + description := r.PostFormValue("description") + rawSteps := r.PostFormValue("steps") + pauseable := r.PostFormValue("pauseable") + pauseableBool := false + if pauseable != "" { + if strings.ToLower(pauseable) == "true" { + pauseableBool = true + } + } + pauseDuration := r.PostFormValue("pause_duration") + keepaliveDuration := r.PostFormValue("keepalive_duration") + rawVirtualMachines := r.PostFormValue("virtualmachines") + rawCategories := r.PostFormValue("categories") + rawTags := r.PostFormValue("tags") + rawVMTasks := r.PostFormValue("vm_tasks") + + _, err = s.internalScenarioServer.UpdateScenario(r.Context(), &scenariopb.UpdateScenarioRequest{ + Id: id, + Name: name, + Description: description, + RawSteps: rawSteps, + RawCategories: rawCategories, + RawTags: rawTags, + RawVms: rawVirtualMachines, + RawVmTasks: rawVMTasks, + KeepaliveDuration: wrapperspb.String(keepaliveDuration), + PauseDuration: wrapperspb.String(pauseDuration), + Pausable: wrapperspb.Bool(pauseableBool), + }) + + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "") +} + +func filterCourses(scenario string, courseList *coursepb.ListCoursesResponse) []*coursepb.Course { + outList := make([]*coursepb.Course, 0) + for _, course := range courseList.GetCourses() { + if util.FilterByScenario(course, scenario) { + outList = append(outList, course) + } + } + + return outList +} + +func preparePrintableContent(scenario *scenariopb.Scenario) string { + id := scenario.GetId() + var content string + + name, err := base64.StdEncoding.DecodeString(scenario.GetName()) + if err != nil { + glog.Errorf("Error decoding title of scenario %s: %v", id, err) + } + description, err := base64.StdEncoding.DecodeString(scenario.GetDescription()) + if err != nil { + glog.Errorf("Error decoding description of scenario %s: %v", id, err) + } + + content = fmt.Sprintf("# %s\n%s\n\n", name, description) + + for i, s := range scenario.GetSteps() { + + title, err := base64.StdEncoding.DecodeString(s.GetTitle()) + if err != nil { + glog.Errorf("Error decoding title of scenario: %s step %d: %v", id, i, err) + } + + content = content + fmt.Sprintf("## Step %d: %s\n", i+1, string(title)) + + stepContent, err := base64.StdEncoding.DecodeString(s.GetContent()) + if err != nil { + glog.Errorf("Error decoding content of scenario: %s step %d: %v", id, i, err) + } + + content = content + fmt.Sprintf("%s\n", string(stepContent)) + } + return content +} diff --git a/v3/services/scenariosvc/internal/server.go b/v3/services/scenariosvc/internal/server.go new file mode 100644 index 00000000..a48d665f --- /dev/null +++ b/v3/services/scenariosvc/internal/server.go @@ -0,0 +1,60 @@ +package scenarioservice + +import ( + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +type ScenarioServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + acClient accesscodepb.AccessCodeSvcClient + courseClient coursepb.CourseSvcClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + sessionClient sessionpb.SessionSvcClient + internalScenarioServer *GrpcScenarioServer +} + +func NewScenarioServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + acClient accesscodepb.AccessCodeSvcClient, + courseClient coursepb.CourseSvcClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + sessionClient sessionpb.SessionSvcClient, + internalScenarioServer *GrpcScenarioServer, +) ScenarioServer { + return ScenarioServer{ + authnClient: authnClient, + authrClient: authrClient, + acClient: acClient, + courseClient: courseClient, + scheduledEventClient: scheduledEventClient, + sessionClient: sessionClient, + internalScenarioServer: internalScenarioServer, + } +} + +func (s ScenarioServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/scenario/list/{access_code}", s.ListScenariosForAccessCode).Methods("GET") + r.HandleFunc("/a/scenario/categories", s.ListCategories).Methods("GET") + r.HandleFunc("/a/scenario/list/{category}", s.ListByCategoryFunc).Methods("GET") + r.HandleFunc("/a/scenario/list", s.ListAllFunc).Methods("GET") + r.HandleFunc("/a/scenario/{id}", s.AdminGetFunc).Methods("GET") + r.HandleFunc("/a/scenario/{id}", s.AdminDeleteFunc).Methods("DELETE") + r.HandleFunc("/scenario/{scenario_id}", s.GetScenarioFunc).Methods("GET") + r.HandleFunc("/scenario/{id}/printable", s.PrintFunc).Methods("GET") + r.HandleFunc("/a/scenario/{id}/printable", s.AdminPrintFunc).Methods("GET") + r.HandleFunc("/a/scenario/new", s.CreateFunc).Methods("POST") + r.HandleFunc("/a/scenario/copy/{id}", s.CopyFunc).Methods("POST") + r.HandleFunc("/a/scenario/{id}", s.UpdateFunc).Methods("PUT") + r.HandleFunc("/scenario/{scenario_id}/step/{step_id:[0-9]+}", s.GetScenarioStepFunc).Methods("GET") + glog.V(2).Infof("set up route") +} diff --git a/v3/services/scenariosvc/main.go b/v3/services/scenariosvc/main.go new file mode 100644 index 00000000..d3e52c63 --- /dev/null +++ b/v3/services/scenariosvc/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + scenarioservice "github.com/hobbyfarm/gargantua/services/scenariosvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(scenarioservice.ScenarioCRDInstaller{}, cfg, "scenario") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.AccessCode, + microservices.Course, + microservices.ScheduledEvent, + microservices.Session, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + acClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + courseClient := coursepb.NewCourseSvcClient(connections[microservices.Course]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ss := scenarioservice.NewGrpcScenarioServer(hfClient, hfInformerFactory) + scenariopb.RegisterScenarioSvcServer(gs, ss) + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + scenarioServer := scenarioservice.NewScenarioServer( + authnClient, + authrClient, + acClient, + courseClient, + scheduledEventClient, + sessionClient, + ss, + ) + microservices.StartAPIServer(scenarioServer) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/scheduledeventsvc/Dockerfile b/v3/services/scheduledeventsvc/Dockerfile new file mode 100644 index 00000000..474f32fe --- /dev/null +++ b/v3/services/scheduledeventsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/scheduledeventsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/scheduledeventsvc/go.mod b/v3/services/scheduledeventsvc/go.mod new file mode 100644 index 00000000..d65fb1e9 --- /dev/null +++ b/v3/services/scheduledeventsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/scheduledeventsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/scheduledeventsvc/go.sum b/v3/services/scheduledeventsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/scheduledeventsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/scheduledeventsvc/internal/controller.go b/v3/services/scheduledeventsvc/internal/controller.go new file mode 100644 index 00000000..797651de --- /dev/null +++ b/v3/services/scheduledeventsvc/internal/controller.go @@ -0,0 +1,508 @@ +package eventservice + +import ( + "context" + "fmt" + "math/rand" + "os" + "strings" + "time" + + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + controllers "github.com/hobbyfarm/gargantua/v3/pkg/microservices/controller" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/workqueue" +) + +type ScheduledEventController struct { + *controllers.RateLimitingWorkqueueController + controllers.Reconciler + internalScheduledEventServer *GrpcScheduledEventServer + accessCodeClient accesscodepb.AccessCodeSvcClient + sessionClient sessionpb.SessionSvcClient + progressClient progresspb.ProgressSvcClient + environmentClient environmentpb.EnvironmentSvcClient + dbConfigClient dbconfigpb.DynamicBindConfigSvcClient + vmSetClient vmsetpb.VMSetSvcClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient + settingClient settingpb.SettingSvcClient +} + +var baseNameScheduledPrefix string + +const ( + ScheduledEventBaseDelay = 5 * time.Millisecond + ScheduledEventMaxDelay = 300 * time.Second +) + +func init() { + bnsp := os.Getenv("HF_BASENAME_SCHEDULED_PREFIX") + if bnsp == "" { + baseNameScheduledPrefix = "scheduled" + } else { + baseNameScheduledPrefix = bnsp + } +} + +func NewScheduledEventController( + kubeClient *kubernetes.Clientset, + internalScheduledEventServer *GrpcScheduledEventServer, + hfInformerFactory hfInformers.SharedInformerFactory, + acClient accesscodepb.AccessCodeSvcClient, + dbConfigClient dbconfigpb.DynamicBindConfigSvcClient, + environmentClient environmentpb.EnvironmentSvcClient, + progressClient progresspb.ProgressSvcClient, + sessionClient sessionpb.SessionSvcClient, + vmSetClient vmsetpb.VMSetSvcClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + settingClient settingpb.SettingSvcClient, + ctx context.Context, +) (*ScheduledEventController, error) { + scheduledEventInformer := hfInformerFactory.Hobbyfarm().V1().ScheduledEvents().Informer() + rateLimitingWorkqueueController := controllers.NewRateLimitingWorkqueueController( + ctx, + scheduledEventInformer, + kubeClient, + "scheduledevent-controller", + time.Minute*30, + workqueue.NewItemExponentialFailureRateLimiter(ScheduledEventBaseDelay, ScheduledEventMaxDelay), + ) + + scheduledEventController := &ScheduledEventController{ + RateLimitingWorkqueueController: rateLimitingWorkqueueController, + internalScheduledEventServer: internalScheduledEventServer, + accessCodeClient: acClient, + dbConfigClient: dbConfigClient, + environmentClient: environmentClient, + progressClient: progressClient, + sessionClient: sessionClient, + vmSetClient: vmSetClient, + vmTemplateClient: vmTemplateClient, + settingClient: settingClient, + } + scheduledEventController.SetReconciler(scheduledEventController) + scheduledEventController.SetWorkScheduler(scheduledEventController) + + return scheduledEventController, nil +} + +func (sc *ScheduledEventController) Reconcile(objName string) error { + err := sc.reconcileScheduledEvent(objName) + if err != nil { + if !hferrors.IsGrpcNotFound(err) { + sc.GetWorkqueue().Add(objName) + return err + } + } + //s.seWorkqueue.Forget(obj) + glog.V(8).Infof("se %s processed by scheduled event controller", objName) + + return nil +} + +func (sc *ScheduledEventController) completeScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + glog.V(6).Infof("ScheduledEvent %s is done, deleting corresponding VMSets and marking as finished", se.GetId()) + // scheduled event is finished, we need to set the scheduled event to finished and delete the vm's + + err := sc.deleteVMSetsFromScheduledEvent(se) + + if err != nil { + return err + } + + err = sc.finishSessionsFromScheduledEvent(se) + + if err != nil { + return err + } + + // update the scheduled event and set the various flags accordingly (provisioned, ready, finished) + _, err = sc.internalScheduledEventServer.UpdateScheduledEventStatus(sc.Context, &scheduledeventpb.UpdateScheduledEventStatusRequest{ + Id: se.GetId(), + Provisioned: wrapperspb.Bool(true), + Ready: wrapperspb.Bool(false), + Finished: wrapperspb.Bool(true), + }) + + if err != nil { + return err + } + + return nil // break (return) here because we're done with this SE. +} + +func (sc *ScheduledEventController) deleteScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + glog.V(6).Infof("ScheduledEvent %s is done and retention time is over, deleting SE finally", se.GetId()) + + if !se.GetStatus().GetFinished() { + return fmt.Errorf("error attempting to delete SE that is not finished") + } + + // Delete Progress + err := sc.deleteProgressFromScheduledEvent(se) + if err != nil { + return err + } + + _, err = sc.internalScheduledEventServer.DeleteScheduledEvent(sc.Context, &generalpb.ResourceId{Id: se.GetId()}) + if err != nil { + return err + } + return nil // break (return) here because we're done with this SE. +} + +func (sc *ScheduledEventController) deleteVMSetsFromScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + // for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset + _, err := sc.vmSetClient.DeleteCollectionVMSet(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, se.GetId()), + }) + return err +} + +func (sc *ScheduledEventController) deleteProgressFromScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + // for each vmset that belongs to this to-be-stopped scheduled event, delete that vmset + _, err := sc.progressClient.DeleteCollectionProgress(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, se.GetId()), + }) + if err != nil { + return err + } + + return nil +} + +func (sc *ScheduledEventController) deleteAccessCode(seId string) error { + // delete the access code for the corresponding ScheduledEvent + _, err := sc.accessCodeClient.DeleteCollectionAc(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, seId), + }) + return err +} + +func (sc *ScheduledEventController) finishSessionsFromScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + // get a list of sessions for the user + sessionList, err := sc.sessionClient.ListSession(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.AccessCodeLabel, se.GetAccessCode()), + }) + + if err != nil { + glog.Errorf("error listing sessions which are supposed to expire %v", err) + return fmt.Errorf("error attempting to update") + } + + now := time.Now().Format(time.UnixDate) + + for _, session := range sessionList.GetSessions() { + _, err = sc.sessionClient.UpdateSessionStatus(sc.Context, &sessionpb.UpdateSessionStatusRequest{ + Id: session.GetId(), + ExpirationTime: now, + Active: wrapperspb.Bool(false), + }) + + if err != nil { + glog.Errorf("error updating session status %v", err) + return fmt.Errorf("error attempting to update") + } + } + return nil +} + +func (sc *ScheduledEventController) provisionScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + glog.V(6).Infof("ScheduledEvent %s is ready to be provisioned", se.Name) + // start creating resources related to this + vmSets := []string{} + + /** + The general flow here is to calculate how much resources (cpu, mem, storage) are currently + being used, and then compare that to what is needed. If needed > used, we're going to still + provision (for some reason), but at least we'll tell the user about it + e.g. --> glog.Errorf("we are overprovisioning this environment %s by CPU... + */ + + // begin by calculating what is currently being used in the environment + for envId, vmtMap := range se.GetRequiredVms() { + // TODO: actually check for capacity usage + // get the environment we're provisioning into (envName) + // env, err := sc.environmentClient.GetEnvironment(sc.Context, &general.GetRequest{Id: envId}) + // if err != nil { + // glog.Errorf("error retreiving environment %s", err.Error()) + // return err + // } + + // create virtualmachinesets if not on demand + if !se.GetOnDemand() { + for templateName, count := range vmtMap.GetVmTemplateCounts() { + if count > 0 { // only setup vmsets if > 0 VMs are requested, and they aren't ondemand + //1. Find existing VMset that match this SE and the current environment + existingVMSetsList, err := sc.vmSetClient.ListVMSet(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s,%s=%s,virtualmachinetemplate.hobbyfarm.io/%s=true", hflabels.ScheduledEventLabel, se.GetId(), hflabels.EnvironmentLabel, envId, templateName), + }) + + if err != nil || len(existingVMSetsList.GetVmsets()) == 0 { // create new vmset if no existing one was found + vmsRand := fmt.Sprintf("%s-%08x", baseNameScheduledPrefix, rand.Uint32()) + vmsId := strings.Join([]string{"se", se.Name, "vms", vmsRand}, "-") + vmSets = append(vmSets, vmsId) + _, err = sc.vmSetClient.CreateVMSet(sc.Context, &vmsetpb.CreateVMSetRequest{ + Id: vmsId, + Count: count, + Environment: envId, + VmTemplate: templateName, + BaseName: vmsRand, + RestrictedBind: se.GetRestrictedBind(), + RestrictedBindValue: se.GetRestrictedBindValue(), + SeName: se.GetId(), + SeUid: se.GetUid(), + Labels: map[string]string{ + hflabels.EnvironmentLabel: envId, + hflabels.ScheduledEventLabel: se.GetId(), + fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s", templateName): "true", + }, + }) + if err != nil { + glog.Error(err) + return err + } + } else { // update existing vmset + // Todo support multiple VM Sets + existingVMSet := existingVMSetsList.GetVmsets()[0] + vmSets = append(vmSets, existingVMSet.GetId()) + + _, err = sc.vmSetClient.UpdateVMSet(sc.Context, &vmsetpb.UpdateVMSetRequest{ + Id: existingVMSet.GetId(), + Count: wrapperspb.UInt32(count), + RestrictedBind: wrapperspb.Bool(se.GetRestrictedBind()), + Environment: envId, + }) + if err != nil { + glog.Errorf("error updating vmset config %s", err.Error()) + return err + } + } + } + } + } + + // Delete existing DynamicBindConfigurations + _, err := sc.dbConfigClient.DeleteCollectionDynamicBindConfig(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s,environment=%s", hflabels.ScheduledEventLabel, se.GetId(), envId), + }) + if err != nil { + return err + } + + // create the dynamic bind configurations + _, err = sc.dbConfigClient.CreateDynamicBindConfig(sc.Context, &dbconfigpb.CreateDynamicBindConfigRequest{ + SeName: se.GetId(), + SeUid: se.GetUid(), + EnvName: envId, + BurstCountCapacity: vmtMap.GetVmTemplateCounts(), + RestrictedBind: se.GetRestrictedBind(), + RestrictedBindValue: se.GetRestrictedBindValue(), + }) + if err != nil { + glog.Errorf("error creating dynamic bind configuration %v", err) + } + } + + // Delete AccessCode if it exists + _, err := sc.accessCodeClient.GetAc(sc.Context, &generalpb.GetRequest{ + Id: se.GetAccessCode(), + }) + if err == nil { + err = sc.deleteAccessCode(se.GetId()) + if err != nil { + return err + } + } + + err = sc.createAccessCode(se) + if err != nil { + return err + } + + _, err = sc.internalScheduledEventServer.UpdateScheduledEventStatus(sc.Context, &scheduledeventpb.UpdateScheduledEventStatusRequest{ + Id: se.GetId(), + Vmsets: &scheduledeventpb.VMSetsWrapper{ + Value: vmSets, + }, + Provisioned: wrapperspb.Bool(true), + Ready: wrapperspb.Bool(false), + Finished: wrapperspb.Bool(false), + }) + glog.V(4).Infof("updated result for scheduled event %s", se.GetId()) + if err != nil { + return err + } + + return nil +} + +func (sc *ScheduledEventController) createAccessCode(se *scheduledeventpb.ScheduledEvent) error { + _, err := sc.accessCodeClient.CreateAc(sc.Context, &accesscodepb.CreateAcRequest{ + AcName: se.GetAccessCode(), + SeName: se.GetId(), + SeUid: se.GetUid(), + Description: "Generated by ScheduledEventController", + Scenarios: se.GetScenarios(), + Courses: se.GetCourses(), + Expiration: se.GetEndTime(), + RestrictedBind: se.GetRestrictedBind(), + RestrictedBindValue: se.GetRestrictedBindValue(), + Printable: se.GetPrintable(), + }) + if err != nil { + return err + } + + return nil +} + +func (sc *ScheduledEventController) verifyScheduledEvent(se *scheduledeventpb.ScheduledEvent) error { + // check the state of the vmset and mark the sevent as ready if everything is OK + glog.V(6).Infof("ScheduledEvent %s is in provisioned status, checking status of VMSet Provisioning", se.GetId()) + vmsList, err := sc.vmSetClient.ListVMSet(sc.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, se.GetId()), + }) + if err != nil { + return err + } + + for _, vms := range vmsList.GetVmsets() { + if vms.GetStatus().GetProvisioned() < vms.GetCount() { + return fmt.Errorf("scheduled event is not ready yet") + } + } + + // Validate AccessCode existence and has label set + ac, err := sc.accessCodeClient.GetAc(sc.Context, &generalpb.GetRequest{Id: se.GetAccessCode()}) + if err != nil { + err = sc.createAccessCode(se) + + if err != nil { + return err + } + + } else if ac.GetLabels()[hflabels.AccessCodeLabel] != ac.GetId() { + err = sc.deleteAccessCode(se.GetId()) + if err != nil { + return err + } + + err = sc.createAccessCode(se) + + if err != nil { + return err + } + } + + _, err = sc.internalScheduledEventServer.UpdateScheduledEventStatus(sc.Context, &scheduledeventpb.UpdateScheduledEventStatusRequest{ + Id: se.GetId(), + Ready: wrapperspb.Bool(true), + }) + if err != nil { + return err + } + + return nil +} + +func (sc *ScheduledEventController) reconcileScheduledEvent(seName string) error { + glog.V(4).Infof("reconciling scheduled event %s", seName) + + // fetch the scheduled event + + se, err := sc.internalScheduledEventServer.GetScheduledEvent(sc.Context, &generalpb.GetRequest{Id: seName}) + if err != nil { + return err + } + + now := time.Now() + + beginTime, err := time.Parse(time.UnixDate, se.GetStartTime()) + if err != nil { + return err + } + endTime, err := time.Parse(time.UnixDate, se.GetEndTime()) + + if err != nil { + return err + } + + // this means that the scheduled event has ended (endtime.Before(now)), but the status of the event is not finished + // and it is still marked as active. this means we need to finish and deactivate the SE. + if endTime.Before(now) && !se.GetStatus().GetFinished() && se.GetStatus().GetActive() { + return sc.completeScheduledEvent(se) + } + + // if this scheduled event has begun (beginTime.Before(now)), and we haven't already provisioned + // this SE, let's do so + if beginTime.Before(now) && !se.GetStatus().GetProvisioned() && se.GetStatus().GetActive() { + return sc.provisionScheduledEvent(se) + } + + // the SE is ongoing and we should just verify things are good + if beginTime.Before(now) && se.Status.Provisioned && !se.Status.Finished && se.Status.Active { + return sc.verifyScheduledEvent(se) + } + + if endTime.Before(now) && se.Status.Finished { + // scheduled event is finished and nothing to do + setting, err := sc.settingClient.GetSettingValue(sc.Context, &generalpb.ResourceId{Id: string(settingUtil.ScheduledEventRetentionTime)}) + + if set, ok := setting.GetValue().(*settingpb.SettingValue_Int64Value); err != nil || !ok || setting == nil { + return fmt.Errorf("error retreiving retention Time setting") + } else { + retentionTime := endTime.Add(time.Hour * time.Duration(set.Int64Value)) + if retentionTime.Before(now) { + // Really finish the ScheduledEvent + return sc.deleteScheduledEvent(se) + } + } + } + + // The ScheduledEvent is set to OnDemand but still has VMSets + if se.GetOnDemand() && len(se.GetStatus().GetVmsets()) > 0 { + vmSets := []string{} + _, err := sc.internalScheduledEventServer.UpdateScheduledEventStatus(sc.Context, &scheduledeventpb.UpdateScheduledEventStatusRequest{ + Id: se.GetId(), + Vmsets: &scheduledeventpb.VMSetsWrapper{Value: vmSets}, + }) + if err != nil { + return err + } + err = sc.deleteVMSetsFromScheduledEvent(se) + return err + } + + return nil +} + +// @TODO: Integrate this function if it should be used or remove it if not. +func calculateUsedCapacity(env *hfv1.Environment, vmsList *hfv1.VirtualMachineSetList, templates *hfv1.VirtualMachineTemplateList) map[string]int { + usedCount := map[string]int{} + for _, vms := range vmsList.Items { + for _, t := range templates.Items { + if t.Name == vms.Spec.VMTemplate { + usedCount[t.Name] = usedCount[t.Name] + vms.Spec.Count + } + } + } + return usedCount +} diff --git a/v3/services/scheduledeventsvc/internal/crd.go b/v3/services/scheduledeventsvc/internal/crd.go new file mode 100644 index 00000000..c02a2e0b --- /dev/null +++ b/v3/services/scheduledeventsvc/internal/crd.go @@ -0,0 +1,27 @@ +package eventservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// ScheduledEventCRDInstaller is a struct that can generate CRDs for scheduled events. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type ScheduledEventCRDInstaller struct{} + +func (si ScheduledEventCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.ScheduledEvent{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.ScheduledEvent{}, func(cv *crder.Version) { + cv. + WithColumn("AccessCode", ".spec.access_code"). + WithColumn("Active", ".status.active"). + WithColumn("Finished", ".status.finished"). + WithStatus() + }) + }), + } +} diff --git a/v3/services/scheduledeventsvc/internal/grpc.go b/v3/services/scheduledeventsvc/internal/grpc.go new file mode 100644 index 00000000..03d84698 --- /dev/null +++ b/v3/services/scheduledeventsvc/internal/grpc.go @@ -0,0 +1,469 @@ +package eventservice + +import ( + "context" + "fmt" + "time" + + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcScheduledEventServer struct { + scheduledeventpb.UnimplementedScheduledEventSvcServer + eventClient hfClientsetv1.ScheduledEventInterface + eventLister listersv1.ScheduledEventLister + eventSynced cache.InformerSynced + acClient accesscodepb.AccessCodeSvcClient + dbconfigClient dbconfigpb.DynamicBindConfigSvcClient + vmSetClient vmsetpb.VMSetSvcClient +} + +func NewGrpcScheduledEventServer( + hfClientSet hfClientset.Interface, + hfInformerFactory hfInformers.SharedInformerFactory, + acClient accesscodepb.AccessCodeSvcClient, + dbconfigClient dbconfigpb.DynamicBindConfigSvcClient, + vmSetClient vmsetpb.VMSetSvcClient, +) *GrpcScheduledEventServer { + return &GrpcScheduledEventServer{ + eventClient: hfClientSet.HobbyfarmV1().ScheduledEvents(util.GetReleaseNamespace()), + eventLister: hfInformerFactory.Hobbyfarm().V1().ScheduledEvents().Lister(), + eventSynced: hfInformerFactory.Hobbyfarm().V1().ScheduledEvents().Informer().HasSynced, + acClient: acClient, + dbconfigClient: dbconfigClient, + vmSetClient: vmSetClient, + } +} + +func (s *GrpcScheduledEventServer) CreateScheduledEvent(ctx context.Context, req *scheduledeventpb.CreateScheduledEventRequest) (*generalpb.ResourceId, error) { + name := req.GetName() + description := req.GetDescription() + creator := req.GetCreator() + startTime := req.GetStartTime() + endTime := req.GetEndTime() + onDemand := req.GetOnDemand() + printable := req.GetPrintable() + restrictedBind := req.GetRestrictedBind() + reqVmsRaw := req.GetRequiredVmsRaw() + accessCode := req.GetAccessCode() + scenariosRaw := req.GetScenariosRaw() + coursesRaw := req.GetCoursesRaw() + labels := req.GetLabels() + + requiredStringParams := map[string]string{ + "name": name, + "description": description, + "creator": creator, + "startTime": startTime, + "endTime": endTime, + "requiredVmsRaw": reqVmsRaw, + "accessCode": accessCode, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + if scenariosRaw == "" && coursesRaw == "" { + return &generalpb.ResourceId{}, hferrors.GrpcError(codes.InvalidArgument, "no courses or scenarios provided", req) + } + + requiredVms, err := util.GenericUnmarshal[map[string]map[string]int](reqVmsRaw, "required_vms_raw") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "required_vms_raw") + } + + random := util.RandStringRunes(16) + id := util.GenerateResourceName("se", random, 10) + + event := &hfv1.ScheduledEvent{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + Labels: labels, + }, + Spec: hfv1.ScheduledEventSpec{ + Creator: creator, + Name: name, + Description: description, + StartTime: startTime, + EndTime: endTime, + OnDemand: onDemand, + RequiredVirtualMachines: requiredVms, + AccessCode: accessCode, + RestrictedBind: restrictedBind, + Printable: printable, + }, + } + + if restrictedBind { + event.Spec.RestrictedBindValue = event.Name + } + + if coursesRaw != "" { + courses, err := util.GenericUnmarshal[[]string](coursesRaw, "courses_raw") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "courses_raw") + } + event.Spec.Courses = courses + } + if scenariosRaw != "" { + scenarios, err := util.GenericUnmarshal[[]string](scenariosRaw, "scenarios_raw") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "scenarios_raw") + } + event.Spec.Scenarios = scenarios + } + + _, err = s.eventClient.Create(ctx, event, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: id}, nil +} + +func (s *GrpcScheduledEventServer) GetScheduledEvent(ctx context.Context, req *generalpb.GetRequest) (*scheduledeventpb.ScheduledEvent, error) { + event, err := util.GenericHfGetter(ctx, req, s.eventClient, s.eventLister.ScheduledEvents(util.GetReleaseNamespace()), "scheduled event", s.eventSynced()) + if err != nil { + return &scheduledeventpb.ScheduledEvent{}, err + } + + status := &scheduledeventpb.ScheduledEventStatus{ + Vmsets: event.Status.VirtualMachineSets, + Active: event.Status.Active, + Provisioned: event.Status.Provisioned, + Ready: event.Status.Ready, + Finished: event.Status.Finished, + } + + requiredVms := make(map[string]*scheduledeventpb.VMTemplateCountMap) + for environment, vmTemplateCountMap := range event.Spec.RequiredVirtualMachines { + requiredVms[environment] = &scheduledeventpb.VMTemplateCountMap{VmTemplateCounts: util.ConvertIntMap[int, uint32](vmTemplateCountMap)} + } + + return &scheduledeventpb.ScheduledEvent{ + Id: event.Name, + Uid: string(event.UID), + Name: event.Spec.Name, + Description: event.Spec.Description, + Creator: event.Spec.Creator, + StartTime: event.Spec.StartTime, + EndTime: event.Spec.EndTime, + OnDemand: event.Spec.OnDemand, + Printable: event.Spec.Printable, + RestrictedBind: event.Spec.RestrictedBind, + RestrictedBindValue: event.Spec.RestrictedBindValue, + RequiredVms: requiredVms, + AccessCode: event.Spec.AccessCode, + Scenarios: event.Spec.Scenarios, + Courses: event.Spec.Courses, + Labels: event.Labels, + Status: status, + }, nil +} + +func (s *GrpcScheduledEventServer) UpdateScheduledEvent(ctx context.Context, req *scheduledeventpb.UpdateScheduledEventRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + name := req.GetName() + description := req.GetDescription() + startTime := req.GetStartTime() + endTime := req.GetEndTime() + onDemand := req.GetOnDemand() + printable := req.GetPrintable() + restrictedBind := req.GetRestrictedBind() + reqVmsRaw := req.GetRequiredVmsRaw() + accessCode := req.GetAccessCode() + scenariosRaw := req.GetScenariosRaw() + coursesRaw := req.GetCoursesRaw() + + scheduledEventLabelSelector := fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id) + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + event, err := s.eventClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving scheduled event %s", + req, + req.GetId(), + ) + } + if name != "" { + event.Spec.Name = name + } + if description != "" { + event.Spec.Description = description + } + if startTime != "" { + event.Spec.StartTime = startTime + } + if endTime != "" { + event.Spec.EndTime = endTime + } + if onDemand != nil { + onDemandVal := onDemand.GetValue() + if onDemandVal && !event.Spec.OnDemand { + // The on demand setting has been removed completely. + glog.Errorf("scheduled event %s changed to \"on demand\", deleting corresponding vm sets", id) + _, err = s.vmSetClient.DeleteCollectionVMSet(ctx, &generalpb.ListOptions{ + LabelSelector: scheduledEventLabelSelector, + }) + if err != nil { + glog.Errorf("deleting vm sets for scheduled event %s failed: %s", id, hferrors.GetErrorMessage(err)) + return err + } + } + event.Spec.OnDemand = onDemand.GetValue() + } + if printable != nil { + event.Spec.Printable = printable.GetValue() + } + if restrictedBind != nil { + event.Spec.RestrictedBind = restrictedBind.GetValue() + + if event.Spec.RestrictedBind { + event.Spec.RestrictedBindValue = event.Name + } else { + event.Spec.RestrictedBindValue = "" + } + } + if reqVmsRaw != "" { + requiredVms, err := util.GenericUnmarshal[map[string]map[string]int](reqVmsRaw, "required_vms_raw") + if err != nil { + return hferrors.GrpcParsingError(req, "required_vms_raw") + } + event.Spec.RequiredVirtualMachines = requiredVms + } + if accessCode != "" { + event.Spec.AccessCode = accessCode + } + if scenariosRaw != "" { + scenarios, err := util.GenericUnmarshal[[]string](scenariosRaw, "scenarios_raw") + if err != nil { + hferrors.GrpcParsingError(req, "scenarios_raw") + } + event.Spec.Scenarios = scenarios + } + if coursesRaw != "" { + courses, err := util.GenericUnmarshal[[]string](coursesRaw, "courses_raw") + if err != nil { + hferrors.GrpcParsingError(req, "courses_raw") + } + event.Spec.Courses = courses + } + + // if our event is already provisioned, we need to undo that and delete the corresponding access code(s) and DBC(s) + // our scheduledeventcontroller will then provision our scheduledevent with the updated values + if event.Status.Provisioned { + now := time.Now() + + beginTime, err := time.Parse(time.UnixDate, event.Spec.StartTime) + if err != nil { + return err + } + + // The SE's begin time has been rescheduled to the future but was already provisioned. + if now.Before(beginTime) && event.Status.Active { + _, err = s.vmSetClient.DeleteCollectionVMSet(ctx, &generalpb.ListOptions{ + LabelSelector: scheduledEventLabelSelector, + }) + if err != nil { + return err + } + } + glog.V(6).Infof("scheduled event %s is updated, deleting corresponding access code(s) and DBC(s)", id) + _, err = s.dbconfigClient.DeleteCollectionDynamicBindConfig(ctx, &generalpb.ListOptions{ + LabelSelector: scheduledEventLabelSelector, + }) + if err != nil { + return err + } + _, err = s.acClient.DeleteCollectionAc(ctx, &generalpb.ListOptions{ + LabelSelector: scheduledEventLabelSelector, + }) + if err != nil { + return err + } + } + + updatedSe, updateErr := s.eventClient.Update(ctx, event, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + updatedSe.Status.Provisioned = false + updatedSe.Status.Ready = false + updatedSe.Status.Finished = false + _, updateErr = s.eventClient.UpdateStatus(ctx, updatedSe, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcScheduledEventServer) UpdateScheduledEventStatus(ctx context.Context, req *scheduledeventpb.UpdateScheduledEventStatusRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + vmSets := req.GetVmsets() + active := req.GetActive() + provisioned := req.GetProvisioned() + ready := req.GetReady() + finished := req.GetFinished() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + event, err := s.eventClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving scheduled event %s", + req, + req.GetId(), + ) + } + + if vmSets != nil { + event.Status.VirtualMachineSets = vmSets.GetValue() + } + if active != nil { + event.Status.Active = active.GetValue() + } + if provisioned != nil { + event.Status.Provisioned = provisioned.GetValue() + } + if ready != nil { + if ready.GetValue() && (!event.Status.Provisioned || event.Status.Finished) { + glog.Errorf("scheduled event %s is not provisioned. Could not change status to active.", event.Name) + return hferrors.GrpcError( + codes.FailedPrecondition, + "error while updating scheduled event %s: events can only be activated if they are in a provisioned state and not yet finished", + req, + req.GetId(), + ) + } + event.Status.Ready = ready.GetValue() + } + if finished != nil { + event.Status.Finished = finished.GetValue() + } + + _, updateErr := s.eventClient.UpdateStatus(ctx, event, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + glog.V(4).Infof("updated result for scheduled event") + return nil + }) + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update scheduled event status: %v", + req, + retryErr, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcScheduledEventServer) DeleteScheduledEvent(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.eventClient, "scheduled event") +} + +func (s *GrpcScheduledEventServer) DeleteCollectionScheduledEvent(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.eventClient, "scheduled event") +} + +func (s *GrpcScheduledEventServer) ListScheduledEvent(ctx context.Context, listOptions *generalpb.ListOptions) (*scheduledeventpb.ListScheduledEventsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var events []hfv1.ScheduledEvent + var err error + if !doLoadFromCache { + var eventList *hfv1.ScheduledEventList + eventList, err = util.ListByHfClient(ctx, listOptions, s.eventClient, "scheduled events") + if err == nil { + events = eventList.Items + } + } else { + events, err = util.ListByCache(listOptions, s.eventLister, "scheduled events", s.eventSynced()) + } + if err != nil { + glog.Error(err) + return &scheduledeventpb.ListScheduledEventsResponse{}, err + } + + preparedEvents := []*scheduledeventpb.ScheduledEvent{} + + for _, event := range events { + status := &scheduledeventpb.ScheduledEventStatus{ + Vmsets: event.Status.VirtualMachineSets, + Active: event.Status.Active, + Provisioned: event.Status.Provisioned, + Ready: event.Status.Ready, + Finished: event.Status.Finished, + } + + requiredVms := make(map[string]*scheduledeventpb.VMTemplateCountMap) + for environment, vmTemplateCountMap := range event.Spec.RequiredVirtualMachines { + requiredVms[environment] = &scheduledeventpb.VMTemplateCountMap{VmTemplateCounts: util.ConvertIntMap[int, uint32](vmTemplateCountMap)} + } + + preparedEvents = append(preparedEvents, &scheduledeventpb.ScheduledEvent{ + Id: event.Name, + Uid: string(event.UID), + Name: event.Spec.Name, + Description: event.Spec.Description, + Creator: event.Spec.Creator, + StartTime: event.Spec.StartTime, + EndTime: event.Spec.EndTime, + OnDemand: event.Spec.OnDemand, + Printable: event.Spec.Printable, + RestrictedBind: event.Spec.RestrictedBind, + RestrictedBindValue: event.Spec.RestrictedBindValue, + RequiredVms: requiredVms, + AccessCode: event.Spec.AccessCode, + Scenarios: event.Spec.Scenarios, + Courses: event.Spec.Courses, + Labels: event.Labels, + Status: status, + }) + } + + return &scheduledeventpb.ListScheduledEventsResponse{Scheduledevents: preparedEvents}, nil +} diff --git a/v3/services/scheduledeventsvc/internal/scheduledeventservice.go b/v3/services/scheduledeventsvc/internal/scheduledeventservice.go new file mode 100644 index 00000000..575c1641 --- /dev/null +++ b/v3/services/scheduledeventsvc/internal/scheduledeventservice.go @@ -0,0 +1,651 @@ +package eventservice + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +const ( + resourcePlural = rbac.ResourcePluralEvent +) + +type PreparedScheduledEvent struct { + Id string `json:"id"` + Creator string `json:"creator"` + Name string `json:"event_name"` + Description string `json:"description"` + StartTime string `json:"start_time"` + EndTime string `json:"end_time"` + OnDemand bool `json:"on_demand"` // whether or not to provision VMs on-demand + RequiredVirtualMachines map[string]map[string]uint32 `json:"required_vms"` // map of environment to a map of strings it should be environment: vm template: count + AccessCode string `json:"access_code"` + RestrictedBind bool `json:"restricted_bind"` // if restricted_bind is true, we need to make the scenario sessions when they get created only bind to vmsets that are created by this scheduledevent + RestrictedBindValue string `json:"restricted_bind_value"` + Printable bool `json:"printable"` + Scenarios []string `json:"scenarios"` + Courses []string `json:"courses"` + *scheduledeventpb.ScheduledEventStatus +} + +type PreparedOTAC struct { + Id string `json:"name"` + User string `json:"user"` + RedeemedTimestamp string `json:"redeemed_timestamp"` + MaxDuration string `json:"max_duration"` +} + +func (s ScheduledEventServer) getPreparedScheduledEvent(scheduledEvent *scheduledeventpb.ScheduledEvent) PreparedScheduledEvent { + return PreparedScheduledEvent{ + Id: scheduledEvent.GetId(), + Creator: scheduledEvent.GetCreator(), + Name: scheduledEvent.GetName(), + Description: scheduledEvent.GetDescription(), + StartTime: scheduledEvent.GetStartTime(), + EndTime: scheduledEvent.GetEndTime(), + OnDemand: scheduledEvent.GetOnDemand(), + RequiredVirtualMachines: util.ConvertMapStruct(scheduledEvent.GetRequiredVms(), util.GetRawVMTemplateCountMap), + AccessCode: scheduledEvent.GetAccessCode(), + RestrictedBind: scheduledEvent.GetRestrictedBind(), + RestrictedBindValue: scheduledEvent.GetRestrictedBindValue(), + Printable: scheduledEvent.GetPrintable(), + Scenarios: scheduledEvent.GetScenarios(), + Courses: scheduledEvent.GetCourses(), + ScheduledEventStatus: scheduledEvent.GetStatus(), + } + +} + +func (s ScheduledEventServer) GetFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get scheduledEvent") + return + } + + vars := mux.Vars(r) + + scheduledEventId := vars["id"] + + if len(scheduledEventId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no scheduledEvent id passed in") + return + } + + scheduledEvent, err := s.internalScheduledEventServer.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: scheduledEventId}) + + if err != nil { + glog.Errorf("error while retrieving scheduledEvent: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("error while retrieving scheduledEvent: scheduledEvent %s not found", scheduledEventId) + util.ReturnHTTPMessage(w, r, 404, "not found", errMsg) + return + } + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "internal error while retrieving scheduledEvent") + return + } + + preparedScheduledEvent := s.getPreparedScheduledEvent(scheduledEvent) + + encodedScheduledEvent, err := json.Marshal(preparedScheduledEvent) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScheduledEvent) + + glog.V(2).Infof("retrieved scheduledEvent %s", scheduledEvent.GetId()) +} + +func (s ScheduledEventServer) ListFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scheduledEvents") + return + } + + scheduledEventList, err := s.internalScheduledEventServer.ListScheduledEvent(r.Context(), &generalpb.ListOptions{}) + + if err != nil { + glog.Errorf("error while retrieving scheduledevents: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "no scheduledevents found") + return + } + + scheduledEvents := scheduledEventList.GetScheduledevents() + preparedScheduledEvents := make([]PreparedScheduledEvent, 0, len(scheduledEvents)) + for _, event := range scheduledEventList.GetScheduledevents() { + preparedScheduledEvents = append(preparedScheduledEvents, s.getPreparedScheduledEvent(event)) + } + + encodedScheduledEvents, err := json.Marshal(preparedScheduledEvents) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedScheduledEvents) + + glog.V(2).Infof("listed scheduled events") +} + +func (s ScheduledEventServer) CreateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create scheduledevents") + return + } + + name := r.PostFormValue("name") + if name == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no name passed in") + return + } + description := r.PostFormValue("description") + if description == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no description passed in") + return + } + startTime := r.PostFormValue("start_time") + if startTime == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no start time passed in") + return + } + endTime := r.PostFormValue("end_time") + if endTime == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no end time passed in") + return + } + requiredVM := r.PostFormValue("required_vms") + if requiredVM == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no required vm map passed in") + return + } + accessCode := r.PostFormValue("access_code") + if accessCode == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no access code passed in") + return + } + var onDemand bool + onDemandRaw := r.PostFormValue("on_demand") + if onDemandRaw == "" { + glog.Warning("scheduled event without use of on_demand flag is deprecated. please upgrade your client") + onDemand = false + } else { + onDemand, err = strconv.ParseBool(onDemandRaw) + if err != nil { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for on_demand") + return + } + } + + var printable bool + printableRaw := r.PostFormValue("printable") + if printableRaw == "" { + glog.Warning("scheduled event without use of printable flag is deprecated. please upgrade your client") + printable = false + } else { + printable, err = strconv.ParseBool(printableRaw) + if err != nil { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for printable") + return + } + } + + scenariosRaw := r.PostFormValue("scenarios") + coursesRaw := r.PostFormValue("courses") + if scenariosRaw == "" && coursesRaw == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no scenarios or courses passed in") + return + } + + // restrictedBind := strings.ToLower(restrictionDisabledRaw) == "false" || restrictionDisabled == "" + restrictionDisabled := false + restrictionDisabledRaw := r.PostFormValue("disable_restriction") + if restrictionDisabledRaw == "" { + restrictionDisabled = false + } else { + if strings.ToLower(restrictionDisabledRaw) == "false" { + restrictionDisabled = false + } else { + restrictionDisabled = true + } + } + + eventId, err := s.internalScheduledEventServer.CreateScheduledEvent(r.Context(), &scheduledeventpb.CreateScheduledEventRequest{ + Name: name, + Description: description, + Creator: user.GetId(), + StartTime: startTime, + EndTime: endTime, + OnDemand: onDemand, + Printable: printable, + RestrictedBind: !restrictionDisabled, + RequiredVmsRaw: requiredVM, + AccessCode: accessCode, + ScenariosRaw: scenariosRaw, + CoursesRaw: coursesRaw, + }) + + if err != nil { + glog.Errorf("error creating scheduled event: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scheduled event") + return + } + + id := eventId.GetId() + + _, err = s.internalScheduledEventServer.UpdateScheduledEventStatus(r.Context(), &scheduledeventpb.UpdateScheduledEventStatusRequest{ + Id: id, + Vmsets: &scheduledeventpb.VMSetsWrapper{Value: []string{}}, + Active: wrapperspb.Bool(true), + Provisioned: wrapperspb.Bool(false), + Ready: wrapperspb.Bool(false), + Finished: wrapperspb.Bool(false), + }) + + if err != nil { + glog.Errorf("error updating status for scheduled event: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating scheduled event") + return + } + + util.ReturnHTTPMessage(w, r, 201, "created", id) +} + +func (s ScheduledEventServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + name := r.PostFormValue("name") + description := r.PostFormValue("description") + startTime := r.PostFormValue("start_time") + endTime := r.PostFormValue("end_time") + requiredVM := r.PostFormValue("required_vms") + accessCode := r.PostFormValue("access_code") + scenariosRaw := r.PostFormValue("scenarios") + coursesRaw := r.PostFormValue("courses") + onDemandRaw := r.PostFormValue("on_demand") + restrictionDisabledRaw := r.PostFormValue("disable_restriction") + printableRaw := r.PostFormValue("printable") + + var onDemandWrapper *wrapperspb.BoolValue + if onDemandRaw != "" { + onDemand, err := strconv.ParseBool(onDemandRaw) + if err != nil { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for on_demand") + return + } + onDemandWrapper = wrapperspb.Bool(onDemand) + } + + var printableWrapper *wrapperspb.BoolValue + if printableRaw != "" { + printable, err := strconv.ParseBool(printableRaw) + if err != nil { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "invalid value for printable") + return + } + printableWrapper = wrapperspb.Bool(printable) + } + + var restrictedBindWrapper *wrapperspb.BoolValue + if restrictionDisabledRaw != "" { + // if restrictionDisabledRaw == false -> restricted bind is not disabled and thus true + restrictedBind := strings.ToLower(restrictionDisabledRaw) == "false" + restrictedBindWrapper = wrapperspb.Bool(restrictedBind) + } + + _, err = s.internalScheduledEventServer.UpdateScheduledEvent(r.Context(), &scheduledeventpb.UpdateScheduledEventRequest{ + Id: id, + Name: name, + Description: description, + StartTime: startTime, + EndTime: endTime, + OnDemand: onDemandWrapper, + Printable: printableWrapper, + RestrictedBind: restrictedBindWrapper, + RequiredVmsRaw: requiredVM, + AccessCode: accessCode, + ScenariosRaw: scenariosRaw, + CoursesRaw: coursesRaw, + }) + + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "") +} + +func (s ScheduledEventServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbDelete)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete scheduledevents") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + scheduledEvent, err := s.internalScheduledEventServer.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: id}) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("error deleting scheduled event: scheduled event %s not found", id) + util.ReturnHTTPMessage(w, r, 404, "not found", errMsg) + return + } else { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event") + return + } + } + + _, err = s.vmsetClient.DeleteCollectionVMSet(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's VMSets") + return + } + + err = s.finishSessions(r.Context(), scheduledEvent) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error terminating scheduled event's sessions") + return + } + + _, err = s.progressClient.DeleteCollectionProgress(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's progress data") + return + } + + _, err = s.dbconfigClient.DeleteCollectionDynamicBindConfig(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's db configs") + return + } + + _, err = s.acClient.DeleteCollectionAc(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event's access codes") + return + } + + _, err = s.internalScheduledEventServer.DeleteScheduledEvent(r.Context(), &generalpb.ResourceId{Id: id}) + if err != nil { + glog.Errorf("error deleting scheduled event %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting scheduled event") + return + } + + util.ReturnHTTPMessage(w, r, 200, "deleted", fmt.Sprintf("Deleted: %s", id)) +} + +func (s ScheduledEventServer) GetOTACsFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list scheduledevents") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + otacList, err := s.acClient.ListOtac(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id), + }) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error retreiving OTACs") + return + } + + var otacs []PreparedOTAC + for _, otac := range otacList.GetOtacs() { + otacs = append(otacs, PreparedOTAC{ + Id: otac.GetId(), + User: otac.GetUser(), + RedeemedTimestamp: otac.GetRedeemedTimestamp(), + MaxDuration: otac.GetMaxDuration(), + }) + } + + encoded, err := json.Marshal(otacs) + if err != nil { + glog.Errorf("error marshalling prepared otacs: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing otacs") + return + } + + util.ReturnHTTPContent(w, r, 200, "success", encoded) + + glog.V(4).Infof("listed OTACs for SE %s", id) +} + +func (s ScheduledEventServer) DeleteOTACFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") + return + } + + vars := mux.Vars(r) + + otac := vars["otac"] + if otac == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + _, err = s.acClient.DeleteOtac(r.Context(), &generalpb.ResourceId{Id: otac}) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting OTACs") + return + } + + util.ReturnHTTPMessage(w, r, 200, "success", "deleted OTAC") +} + +func (s ScheduledEventServer) GenerateOTACsFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, s.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, s.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update scheduledevents") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return + } + + countFormValue := vars["count"] + if countFormValue == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no count passed in") + return + } + count, err := strconv.Atoi(countFormValue) + if err != nil { + glog.Error(err) + util.ReturnHTTPMessage(w, r, 404, "badrequest", "invalid count given") + return + } + + maxDurationValue := r.PostFormValue("max_duration") + + scheduledEvent, err := s.internalScheduledEventServer.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: id}) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errorMsg := fmt.Sprintf("error generating OTACs: scheduledEvent %s not found", id) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errorMsg) + return + } + errorMsg := fmt.Sprintf("error generating OTACs: error while retrieving scheduledEvent %s", id) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", errorMsg) + return + } + + var otacs []PreparedOTAC + + for i := 0; i < count; i++ { + // Generate an access code that can not be guessed + otac, err := s.acClient.CreateOtac(r.Context(), &accesscodepb.CreateOtacRequest{ + SeName: scheduledEvent.GetId(), + SeUid: scheduledEvent.GetUid(), + MaxDuration: maxDurationValue, + }) + if err != nil { + glog.Errorf("error creating one time access code %s", hferrors.GetErrorMessage(err)) + continue + } + otacs = append(otacs, PreparedOTAC{ + Id: otac.GetId(), + User: otac.GetUser(), + RedeemedTimestamp: otac.GetRedeemedTimestamp(), + MaxDuration: otac.GetMaxDuration(), + }) + } + + encoded, err := json.Marshal(otacs) + if err != nil { + glog.Errorf("error marshalling prepared otacs: %v", err) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing generated otacs") + return + } + + util.ReturnHTTPContent(w, r, 200, "success", encoded) + + glog.V(4).Infof("generated %d new OTACs for SE %s", count, id) +} + +func (s ScheduledEventServer) finishSessions(ctx context.Context, se *scheduledeventpb.ScheduledEvent) error { + // get a list of sessions for the user + sessionList, err := s.sessionClient.ListSession(ctx, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.AccessCodeLabel, se.GetAccessCode()), + }) + if err != nil { + glog.Errorf("error updating session %s", hferrors.GetErrorMessage(err)) + return fmt.Errorf("error attempting to update: failed to list sessions") + } + + now := time.Now().Format(time.UnixDate) + + for _, session := range sessionList.GetSessions() { + _, err = s.sessionClient.UpdateSessionStatus(ctx, &sessionpb.UpdateSessionStatusRequest{ + Id: session.GetId(), + Active: wrapperspb.Bool(false), + Finished: wrapperspb.Bool(false), + ExpirationTime: now, + }) + if err != nil { + glog.Errorf("error updating session %s", hferrors.GetErrorMessage(err)) + return fmt.Errorf("error attempting to update") + } + } + return nil +} diff --git a/v3/services/scheduledeventsvc/internal/server.go b/v3/services/scheduledeventsvc/internal/server.go new file mode 100644 index 00000000..11f9c5fc --- /dev/null +++ b/v3/services/scheduledeventsvc/internal/server.go @@ -0,0 +1,61 @@ +package eventservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" +) + +// session +// vmset +// progress +type ScheduledEventServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + acClient accesscodepb.AccessCodeSvcClient + dbconfigClient dbconfigpb.DynamicBindConfigSvcClient + progressClient progresspb.ProgressSvcClient + sessionClient sessionpb.SessionSvcClient + vmsetClient vmsetpb.VMSetSvcClient + internalScheduledEventServer *GrpcScheduledEventServer +} + +func NewScheduledEventServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + acClient accesscodepb.AccessCodeSvcClient, + dbconfigClient dbconfigpb.DynamicBindConfigSvcClient, + progressClient progresspb.ProgressSvcClient, + sessionClient sessionpb.SessionSvcClient, + vmsetClient vmsetpb.VMSetSvcClient, + internalScheduledEventServer *GrpcScheduledEventServer, +) ScheduledEventServer { + return ScheduledEventServer{ + authnClient: authnClient, + authrClient: authrClient, + acClient: acClient, + dbconfigClient: dbconfigClient, + progressClient: progressClient, + sessionClient: sessionClient, + vmsetClient: vmsetClient, + internalScheduledEventServer: internalScheduledEventServer, + } +} + +func (s ScheduledEventServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/a/scheduledevent/list", s.ListFunc).Methods("GET") + r.HandleFunc("/a/scheduledevent/new", s.CreateFunc).Methods("POST") + r.HandleFunc("/a/scheduledevent/{id}", s.GetFunc).Methods("GET") + r.HandleFunc("/a/scheduledevent/{id}", s.UpdateFunc).Methods("PUT") + r.HandleFunc("/a/scheduledevent/{id}/otacs/add/{count}", s.GenerateOTACsFunc).Methods("POST") + r.HandleFunc("/a/scheduledevent/{id}/otacs/delete/{otac}", s.DeleteOTACFunc).Methods("GET") + r.HandleFunc("/a/scheduledevent/{id}/otacs/list", s.GetOTACsFunc).Methods("GET") + r.HandleFunc("/a/scheduledevent/delete/{id}", s.DeleteFunc).Methods("DELETE") + glog.V(2).Infof("set up routes for admin scheduledevent server") +} diff --git a/v3/services/scheduledeventsvc/main.go b/v3/services/scheduledeventsvc/main.go new file mode 100644 index 00000000..84b01e96 --- /dev/null +++ b/v3/services/scheduledeventsvc/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "context" + "sync" + "time" + + "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + eventservice "github.com/hobbyfarm/gargantua/services/scheduledeventsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + ctx := context.Background() + + cfg, hfClient, kubeClient := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(eventservice.ScheduledEventCRDInstaller{}, cfg, "scheduled event") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.AccessCode, + microservices.DBConfig, + microservices.Environment, + microservices.Progress, + microservices.Session, + microservices.VMSet, + microservices.VMTemplate, + microservices.Setting, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + acClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + dbcClient := dbconfigpb.NewDynamicBindConfigSvcClient(connections[microservices.DBConfig]) + envClient := environmentpb.NewEnvironmentSvcClient(connections[microservices.Environment]) + progressClient := progresspb.NewProgressSvcClient(connections[microservices.Progress]) + sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session]) + vmSetClient := vmsetpb.NewVMSetSvcClient(connections[microservices.VMSet]) + vmTemplateClient := vmtemplatepb.NewVMTemplateSvcClient(connections[microservices.VMTemplate]) + settingClient := settingpb.NewSettingSvcClient(connections[microservices.Setting]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ss := eventservice.NewGrpcScheduledEventServer(hfClient, hfInformerFactory, acClient, dbcClient, vmSetClient) + scheduledeventpb.RegisterScheduledEventSvcServer(gs, ss) + seController, err := eventservice.NewScheduledEventController( + kubeClient, + ss, + hfInformerFactory, + acClient, + dbcClient, + envClient, + progressClient, + sessionClient, + vmSetClient, + vmTemplateClient, + settingClient, + ctx, + ) + if err != nil { + glog.Fatalf("failed creating scheduled event controller: %s", err.Error()) + } + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + scheduledEventServer := eventservice.NewScheduledEventServer( + authnClient, + authrClient, + acClient, + dbcClient, + progressClient, + sessionClient, + vmSetClient, + ss, + ) + microservices.StartAPIServer(scheduledEventServer) + }() + + go func() { + defer wg.Done() + seController.RunSharded(stopCh, microservices.ScheduledEvent) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/sessionsvc/Dockerfile b/v3/services/sessionsvc/Dockerfile new file mode 100644 index 00000000..56b6a3f0 --- /dev/null +++ b/v3/services/sessionsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/sessionsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/sessionsvc/go.mod b/v3/services/sessionsvc/go.mod new file mode 100644 index 00000000..c8b497a7 --- /dev/null +++ b/v3/services/sessionsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/sessionsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/sessionsvc/go.sum b/v3/services/sessionsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/sessionsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/sessionsvc/internal/controller.go b/v3/services/sessionsvc/internal/controller.go new file mode 100644 index 00000000..8f52a731 --- /dev/null +++ b/v3/services/sessionsvc/internal/controller.go @@ -0,0 +1,227 @@ +package sessionservice + +import ( + "context" + "fmt" + "time" + + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + controllers "github.com/hobbyfarm/gargantua/v3/pkg/microservices/controller" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + "k8s.io/client-go/kubernetes" +) + +type SessionController struct { + controllers.DelayingWorkqueueController + controllers.Reconciler + internalSessioServer *GrpcSessionServer + progressClient progresspb.ProgressSvcClient + vmClient vmpb.VMSvcClient + vmClaimClient vmclaimpb.VMClaimSvcClient +} + +func NewSessionController( + kubeClient *kubernetes.Clientset, + internalSessionServer *GrpcSessionServer, + hfInformerFactory hfInformers.SharedInformerFactory, + progressClient progresspb.ProgressSvcClient, + vmClient vmpb.VMSvcClient, + vmClaimClient vmclaimpb.VMClaimSvcClient, + ctx context.Context, +) (*SessionController, error) { + sessionInformer := hfInformerFactory.Hobbyfarm().V1().Sessions().Informer() + delayingWorkqueueController := *controllers.NewDelayingWorkqueueController( + ctx, + sessionInformer, + kubeClient, + "session-controller", + time.Minute*30, + nil, + ) + + sessionController := &SessionController{ + DelayingWorkqueueController: delayingWorkqueueController, + internalSessioServer: internalSessionServer, + progressClient: progressClient, + vmClient: vmClient, + vmClaimClient: vmClaimClient, + } + sessionController.SetReconciler(sessionController) + sessionController.SetWorkScheduler(sessionController) + + return sessionController, nil +} + +func (s *SessionController) Reconcile(objName string) error { + err := s.reconcileSession(objName) + + if err != nil { + glog.Error(err) + } + //s.ssWorkqueue.Forget(obj) + glog.V(8).Infof("ss processed by session controller %v", objName) + + return nil +} + +func (s *SessionController) reconcileSession(ssName string) error { + glog.V(4).Infof("reconciling session %s", ssName) + + ss, err := s.internalSessioServer.GetSession(s.Context, &generalpb.GetRequest{ + Id: ssName, + LoadFromCache: true, + }) + + if err != nil { + return err + } + + now := time.Now() + + expires, err := time.Parse(time.UnixDate, ss.GetStatus().GetExpirationTime()) + + if err != nil { + return err + } + + timeUntilExpires := expires.Sub(now) + + // clean up sessions if they are finished + if ss.GetStatus().GetFinished() { + glog.V(6).Infof("deleted finished session %s", ss.GetId()) + + // now that the vmclaims are deleted, go ahead and delete the session + _, err = s.internalSessioServer.DeleteSession(s.Context, &generalpb.ResourceId{Id: ss.GetId()}) + + if err != nil { + return fmt.Errorf("error deleting session %s: %v", ss.GetId(), err) + } + + glog.V(6).Infof("deleted old session %s", ss.GetId()) + + s.FinishProgress(ss.GetId(), ss.GetUser()) + + return nil + } + + if expires.Before(now) && !ss.GetStatus().GetFinished() { + // we need to set the session to finished and delete the vm's + if ss.Status.Active && ss.Status.Paused && ss.Status.PausedTime != "" { + pausedExpiration, err := time.Parse(time.UnixDate, ss.Status.PausedTime) + if err != nil { + glog.Error(err) + } + + if pausedExpiration.After(now) { + glog.V(4).Infof("Session %s was paused, and the pause expiration is after now, skipping clean up.", ss.GetId()) + return nil + } + + glog.V(4).Infof("Session %s was paused, but the pause expiration was before now, so cleaning up.", ss.GetId()) + } + for _, vmc := range ss.GetVmClaim() { + vmcObj, err := s.vmClaimClient.GetVMClaim(s.Context, &generalpb.GetRequest{ + Id: vmc, + LoadFromCache: true, + }) + + if err != nil { + break + } + + for _, vm := range vmcObj.GetVms() { + if len(vm.GetVmId()) == 0 { + // VM was not even provisioned / assigned yet. + continue + } + taintErr := s.taintVM(vm.GetVmId()) + if taintErr != nil { + glog.Error(taintErr) + } + } + + taintErr := s.taintVMC(vmcObj.GetId()) + if taintErr != nil { + glog.Error(taintErr) + } + } + + _, err = s.internalSessioServer.UpdateSessionStatus(s.Context, &sessionpb.UpdateSessionStatusRequest{ + Id: ssName, + Finished: wrapperspb.Bool(true), + Active: wrapperspb.Bool(false), + }) + glog.V(4).Infof("updated result for session") + if err != nil { + return err + } + } else if expires.Before(now) && ss.GetStatus().GetFinished() { + glog.V(8).Infof("session %s is finished and expired before now", ssName) + } else { + glog.V(8).Infof("adding session %s to workqueue after %s", ssName, timeUntilExpires.String()) + ssWorkqueue, err := s.GetDelayingWorkqueue() + if err != nil { + return fmt.Errorf("unable to requeue session: %v", err) + } + ssWorkqueue.AddAfter(ssName, timeUntilExpires) + glog.V(8).Infof("added session %s to workqueue", ssName) + } + + return nil +} + +func (s *SessionController) taintVM(vmName string) error { + glog.V(5).Infof("tainting VM %s", vmName) + _, err := s.vmClient.UpdateVMStatus(s.Context, &vmpb.UpdateVMStatusRequest{ + Id: vmName, + Tainted: wrapperspb.Bool(true), + }) + glog.V(4).Infof("updated result for vm") + + return err +} + +func (s *SessionController) taintVMC(vmcName string) error { + glog.V(5).Infof("tainting VMC %s", vmcName) + _, err := s.vmClaimClient.UpdateVMClaimStatus(s.Context, &vmclaimpb.UpdateVMClaimStatusRequest{ + Id: vmcName, + Tainted: wrapperspb.Bool(true), + }) + glog.V(4).Infof("updated result for vmc") + + return err +} + +func (s *SessionController) FinishProgress(sessionId string, userId string) { + now := time.Now() + + progressList, err := s.progressClient.ListProgress(s.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s,%s=%s,finished=false", hflabels.SessionLabel, sessionId, hflabels.UserLabel, userId), + }) + + if err != nil { + glog.Errorf("error while retrieving progress %v", err) + return + } + + for _, p := range progressList.GetProgresses() { + _, err = s.progressClient.UpdateProgress(s.Context, &progresspb.UpdateProgressRequest{ + Id: p.GetId(), + LastUpdate: now.Format(time.UnixDate), + Finished: "true", + }) + glog.V(4).Infof("updated progress with ID %s", p.GetId()) + if err != nil { + glog.Errorf("error finishing progress %v", err) + return + } + } +} diff --git a/v3/services/sessionsvc/internal/crd.go b/v3/services/sessionsvc/internal/crd.go new file mode 100644 index 00000000..1810227d --- /dev/null +++ b/v3/services/sessionsvc/internal/crd.go @@ -0,0 +1,29 @@ +package sessionservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// SessionCRDInstaller is a struct that can generate CRDs for sessions. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type SessionCRDInstaller struct{} + +func (si SessionCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.Session{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.Session{}, func(cv *crder.Version) { + cv. + WithColumn("Paused", ".status.paused"). + WithColumn("Active", ".status.active"). + WithColumn("Finished", ".status.finished"). + WithColumn("StartTime", ".status.start_time"). + WithColumn("ExpirationTime", ".status.end_time"). + WithStatus() + }) + }), + } +} diff --git a/v3/services/sessionsvc/internal/grpc.go b/v3/services/sessionsvc/internal/grpc.go new file mode 100644 index 00000000..a7930f2a --- /dev/null +++ b/v3/services/sessionsvc/internal/grpc.go @@ -0,0 +1,280 @@ +package sessionservice + +import ( + "context" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcSessionServer struct { + sessionpb.UnimplementedSessionSvcServer + sessionClient hfClientsetv1.SessionInterface + sessionLister listersv1.SessionLister + sessionSynced cache.InformerSynced +} + +func NewGrpcSessionServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcSessionServer { + return &GrpcSessionServer{ + sessionClient: hfClientSet.HobbyfarmV1().Sessions(util.GetReleaseNamespace()), + sessionLister: hfInformerFactory.Hobbyfarm().V1().Sessions().Lister(), + sessionSynced: hfInformerFactory.Hobbyfarm().V1().Sessions().Informer().HasSynced, + } +} + +func (s *GrpcSessionServer) CreateSession(ctx context.Context, req *sessionpb.CreateSessionRequest) (*generalpb.ResourceId, error) { + scenario := req.GetScenario() + course := req.GetCourse() + keepCourseVm := req.GetKeepCourseVm() + userId := req.GetUser() + vmClaims := req.GetVmClaim() + accessCode := req.GetAccessCode() + labels := req.GetLabels() + + if scenario == "" && course == "" { + return &generalpb.ResourceId{}, hferrors.GrpcError(codes.InvalidArgument, "no course/scenario id provided", req) + } + + requiredStringParams := map[string]string{ + "user": userId, + "accessCode": accessCode, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + random := util.RandStringRunes(10) + id := util.GenerateResourceName("ss", random, 10) + + session := &hfv1.Session{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + Labels: labels, + }, + Spec: hfv1.SessionSpec{ + ScenarioId: scenario, + CourseId: course, + KeepCourseVM: keepCourseVm, + UserId: userId, + VmClaimSet: vmClaims, + AccessCode: accessCode, + }, + } + + _, err := s.sessionClient.Create(ctx, session, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: id}, nil +} + +func (s *GrpcSessionServer) GetSession(ctx context.Context, req *generalpb.GetRequest) (*sessionpb.Session, error) { + session, err := util.GenericHfGetter(ctx, req, s.sessionClient, s.sessionLister.Sessions(util.GetReleaseNamespace()), "session", s.sessionSynced()) + if err != nil { + return &sessionpb.Session{}, err + } + + status := &sessionpb.SessionStatus{ + Paused: session.Status.Paused, + PausedTime: session.Status.PausedTime, + Active: session.Status.Active, + Finished: session.Status.Finished, + StartTime: session.Status.StartTime, + ExpirationTime: session.Status.ExpirationTime, + } + + return &sessionpb.Session{ + Id: session.Name, + Uid: string(session.UID), + Scenario: session.Spec.ScenarioId, + Course: session.Spec.CourseId, + KeepCourseVm: session.Spec.KeepCourseVM, + User: session.Spec.UserId, + VmClaim: session.Spec.VmClaimSet, + AccessCode: session.Spec.AccessCode, + Labels: session.Labels, + Status: status, + }, nil +} + +func (s *GrpcSessionServer) UpdateSession(ctx context.Context, req *sessionpb.UpdateSessionRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + scenario := req.GetScenario() + if scenario == "" { + return &emptypb.Empty{}, hferrors.GrpcNotSpecifiedError(req, "scenario") + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + session, err := s.sessionClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving session %s", + req, + req.GetId(), + ) + } + + session.Spec.ScenarioId = scenario + + _, updateErr := s.sessionClient.Update(ctx, session, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcSessionServer) UpdateSessionStatus(ctx context.Context, req *sessionpb.UpdateSessionStatusRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + paused := req.GetPaused() + pausedTime := req.GetPausedTime() + active := req.GetActive() + finished := req.GetFinished() + startTime := req.GetStartTime() + expirationTime := req.GetExpirationTime() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + session, err := s.sessionClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving session %s", + req, + req.GetId(), + ) + } + + if paused != nil { + session.Status.Paused = paused.GetValue() + } + + if pausedTime != nil { + session.Status.PausedTime = pausedTime.GetValue() + } + + if active != nil { + session.Status.Active = active.GetValue() + } + + if finished != nil { + session.Status.Finished = finished.GetValue() + } + + if startTime != "" { + session.Status.StartTime = startTime + } + + if expirationTime != "" { + session.Status.ExpirationTime = expirationTime + } + + _, updateErr := s.sessionClient.UpdateStatus(ctx, session, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + // @TODO: verify result like in util.go + glog.V(4).Infof("updated result for session") + return nil + }) + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update session status: %v", + req, + retryErr, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcSessionServer) DeleteSession(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.sessionClient, "session") +} + +func (s *GrpcSessionServer) DeleteCollectionSession(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.sessionClient, "session") +} + +func (s *GrpcSessionServer) ListSession(ctx context.Context, listOptions *generalpb.ListOptions) (*sessionpb.ListSessionsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var sessions []hfv1.Session + var err error + if !doLoadFromCache { + var sessionList *hfv1.SessionList + sessionList, err = util.ListByHfClient(ctx, listOptions, s.sessionClient, "sessions") + if err == nil { + sessions = sessionList.Items + } + } else { + sessions, err = util.ListByCache(listOptions, s.sessionLister, "sessions", s.sessionSynced()) + } + if err != nil { + glog.Error(err) + return &sessionpb.ListSessionsResponse{}, err + } + + preparedSessions := []*sessionpb.Session{} + + for _, session := range sessions { + status := &sessionpb.SessionStatus{ + Paused: session.Status.Paused, + PausedTime: session.Status.PausedTime, + Active: session.Status.Active, + Finished: session.Status.Finished, + StartTime: session.Status.StartTime, + ExpirationTime: session.Status.ExpirationTime, + } + + preparedSessions = append(preparedSessions, &sessionpb.Session{ + Id: session.Name, + Uid: string(session.UID), + Scenario: session.Spec.ScenarioId, + Course: session.Spec.CourseId, + KeepCourseVm: session.Spec.KeepCourseVM, + User: session.Spec.UserId, + VmClaim: session.Spec.VmClaimSet, + AccessCode: session.Spec.AccessCode, + Labels: session.Labels, + Status: status, + }) + } + + return &sessionpb.ListSessionsResponse{Sessions: preparedSessions}, nil +} diff --git a/v3/services/sessionsvc/internal/server.go b/v3/services/sessionsvc/internal/server.go new file mode 100644 index 00000000..6b7eb46c --- /dev/null +++ b/v3/services/sessionsvc/internal/server.go @@ -0,0 +1,60 @@ +package sessionservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" +) + +type SessionServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + acClient accesscodepb.AccessCodeSvcClient + courseClient coursepb.CourseSvcClient + progressClient progresspb.ProgressSvcClient + scenarioClient scenariopb.ScenarioSvcClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + vmclaimClient vmclaimpb.VMClaimSvcClient + internalSessionServer *GrpcSessionServer +} + +func NewSessionServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + acClient accesscodepb.AccessCodeSvcClient, + courseClient coursepb.CourseSvcClient, + progressClient progresspb.ProgressSvcClient, + scenarioClient scenariopb.ScenarioSvcClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + vmclaimClient vmclaimpb.VMClaimSvcClient, + internalSessionServer *GrpcSessionServer, +) SessionServer { + return SessionServer{ + authnClient: authnClient, + authrClient: authrClient, + acClient: acClient, + courseClient: courseClient, + progressClient: progressClient, + scenarioClient: scenarioClient, + scheduledEventClient: scheduledEventClient, + vmclaimClient: vmclaimClient, + internalSessionServer: internalSessionServer, + } +} + +func (sss SessionServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/session/new", sss.NewSessionFunc).Methods("POST") + r.HandleFunc("/session/{session_id}", sss.GetSessionFunc).Methods("GET") + r.HandleFunc("/session/{session_id}/finished", sss.FinishedSessionFunc).Methods("PUT") + r.HandleFunc("/session/{session_id}/keepalive", sss.KeepAliveSessionFunc).Methods("PUT") + r.HandleFunc("/session/{session_id}/pause", sss.PauseSessionFunc).Methods("PUT") + r.HandleFunc("/session/{session_id}/resume", sss.ResumeSessionFunc).Methods("PUT") + glog.V(2).Infof("set up routes for session server") +} diff --git a/v3/services/sessionsvc/internal/sessionservice.go b/v3/services/sessionsvc/internal/sessionservice.go new file mode 100644 index 00000000..4ab00d8f --- /dev/null +++ b/v3/services/sessionsvc/internal/sessionservice.go @@ -0,0 +1,700 @@ +package sessionservice + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "time" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +const ( + ssIndex = "sss.hobbyfarm.io/session-id-index" + newSSTimeout = "5m" + keepaliveSSTimeout = "5m" + pauseSSTimeout = "2h" + resourcePlural = rbac.ResourcePluralSession +) + +type preparedSession struct { + Id string `json:"id"` + ScenarioId string `json:"scenario"` + CourseId string `json:"course"` + KeepCourseVM bool `json:"keep_course_vm"` + UserId string `json:"user"` + VmClaimSet []string `json:"vm_claim"` + AccessCode string `json:"access_code"` +} + +func (sss SessionServer) NewSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create sessions") + return + } + + courseid := r.PostFormValue("course") + scenarioid := r.PostFormValue("scenario") + + if courseid == "" && scenarioid == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no course/scenario id passed in") + return + } + + accessCodeId := r.PostFormValue("access_code") + + restrictedBind := false + restrictedBindVal := "" + + if accessCodeId == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "An accesscode has to be given in order so start a session") + return + } + + // we should validate the user can use this access code + // let's figure out the restricted bind value + accessCodeObj, err := sss.acClient.GetAccessCodeWithOTACs(r.Context(), &generalpb.ResourceId{Id: accessCodeId}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "could not retrieve access code") + return + } + if accessCodeObj.GetRestrictedBind() { + restrictedBind = accessCodeObj.GetRestrictedBind() + restrictedBindVal = accessCodeObj.GetRestrictedBindValue() + } + scheduledEventId := accessCodeObj.Labels[hflabels.ScheduledEventLabel] + + course, scenario, ok := sss.getCourseAndScenarioFromCache(w, r, courseid, scenarioid) + if !ok { + // we encountered an error and already returned an HTTPMessage in getCourseAndScenarioFromCache() + return + } + + // now we should check for existing sessions for the user + sessionList, err := sss.internalSessionServer.ListSession(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.UserLabel, user.GetId()), + }) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + } + now := time.Now() + + // should we check the sessions list for the restricted bind value and match if one is passed in? probably... + for _, sess := range sessionList.GetSessions() { + expires, err := time.Parse(time.UnixDate, sess.GetStatus().GetExpirationTime()) + if err != nil { + continue + } + if sess.GetUser() == user.GetId() && + (sess.GetCourse() == courseid || sess.GetScenario() == scenarioid) && + !sess.GetStatus().GetFinished() && + sess.GetStatus().GetActive() && expires.After(now) { + // we should just return this session... + + // if this is a course, return the same scenario id that was given to us + // i.e., reuse the course id and give them the scenario they asked for + if sess.GetCourse() != "" { + _, err = sss.internalSessionServer.UpdateSession(r.Context(), &sessionpb.UpdateSessionRequest{ + Id: sess.GetId(), + Scenario: scenarioid, + }) + if err != nil { + glog.Errorf("error updating session %s", hferrors.GetErrorMessage(err)) + errMsg := fmt.Sprintf("error retrieving new session: could not update session to new scenario %s", scenarioid) + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + return + } + + err = sss.FinishProgress(r.Context(), sess.GetId(), user.GetId()) + if err != nil { + glog.Errorf("error finishing progress %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving new session: unable to clean up progress data") + } + createdProgress, err := sss.progressClient.CreateProgress(r.Context(), &progresspb.CreateProgressRequest{ + CurrentStep: 0, + MaxStep: 0, + TotalStep: uint32(len(scenario.GetSteps())), + Scenario: scenarioid, + Course: courseid, + User: user.GetId(), + Labels: map[string]string{ + hflabels.SessionLabel: sess.GetId(), // map to session + hflabels.ScheduledEventLabel: scheduledEventId, // map to scheduledevent + hflabels.UserLabel: user.GetId(), // map to user + "finished": "false", // default is in progress, finished = false + }, + }) + if err != nil { + glog.Errorf("error creating progress %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving new session: unable to recreate progress") + } + glog.V(2).Infof("created progress with ID %s", createdProgress.GetId()) + } + + preparedSession := preparedSession{ + Id: sess.GetId(), + ScenarioId: scenarioid, + CourseId: sess.GetCourse(), + KeepCourseVM: sess.GetKeepCourseVm(), + UserId: sess.GetUser(), + VmClaimSet: sess.GetVmClaim(), + AccessCode: sess.GetAccessCode(), + } + encodedSS, err := json.Marshal(preparedSession) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "exists", encodedSS) + return + } + } + schedEvent, err := sss.scheduledEventClient.GetScheduledEvent(r.Context(), &generalpb.GetRequest{Id: scheduledEventId}) + if err != nil { + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("error retrieving new session: scheduled event %s not found", scheduledEventId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving new session: failed to retrieve scheduled event %s", scheduledEventId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", errMsg) + } + + var bindMode string + var baseName string + if schedEvent.GetOnDemand() { + bindMode = "dynamic" + bndp := os.Getenv("HF_BASENAME_DYNAMIC_PREFIX") + if bndp == "" { + baseName = "vmc" + } else { + baseName = bndp + } + } else { + bindMode = "static" + bnsp := os.Getenv("HF_BASENAME_SCHEDULED_PREFIX") + if bnsp == "" { + baseName = "scheduled" + } else { + baseName = bnsp + } + } + + wrappedVms := course.GetVms() + if len(wrappedVms) == 0 { + wrappedVms = scenario.GetVms() + } + vms := util.ConvertToStringMapSlice(wrappedVms) + + lenVms := len(vms) + sessionVmClaimSet := make([]string, 0, lenVms) + vmClaimRequests := make([]*vmclaimpb.CreateVMClaimRequest, 0, lenVms) + for _, vmset := range vms { + vmClaimId := util.GenerateResourceName(baseName, util.RandStringRunes(10), 10) + sessionVmClaimSet = append(sessionVmClaimSet, vmClaimId) + vmClaimRequests = append(vmClaimRequests, &vmclaimpb.CreateVMClaimRequest{ + Id: vmClaimId, + UserName: user.GetId(), + Vmset: vmset, + RestrictedBind: restrictedBind, + RestrictedBindValue: restrictedBindVal, + DynamicCapable: true, + Labels: map[string]string{ + hflabels.SessionLabel: "", + hflabels.UserLabel: user.GetId(), + hflabels.AccessCodeLabel: accessCodeObj.GetId(), + hflabels.ScheduledEventLabel: scheduledEventId, + }, + }) + } + keepVm := course.GetKeepVm() + + createdSessionId, err := sss.internalSessionServer.CreateSession(r.Context(), &sessionpb.CreateSessionRequest{ + Scenario: scenarioid, + Course: courseid, + KeepCourseVm: keepVm, + User: user.GetId(), + VmClaim: sessionVmClaimSet, + AccessCode: accessCodeId, + Labels: map[string]string{ + hflabels.AccessCodeLabel: accessCodeObj.GetId(), + hflabels.UserLabel: user.GetId(), + }, + }) + if err != nil { + glog.Errorf("error creating session %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error creating new session") + return + } + sessionId := createdSessionId.GetId() + expirationTime, err := calculateExpiration(newSSTimeout, course.GetKeepaliveDuration(), scenario.GetKeepaliveDuration()) + if err != nil { + glog.Errorf("Unable to calculate session expiration: %v", err) + errMsg := "Failed to calculate session expiration. Please check your course/scenario keepalive settings." + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + } + _, err = sss.internalSessionServer.UpdateSessionStatus(r.Context(), &sessionpb.UpdateSessionStatusRequest{ + Id: sessionId, + Active: wrapperspb.Bool(true), + Finished: wrapperspb.Bool(false), + StartTime: now.Format(time.UnixDate), + ExpirationTime: expirationTime, + }) + + if err != nil { + glog.Errorf("error updating session status: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error while creating session: could not update session status") + return + } + glog.V(2).Infof("created session %s", sessionId) + + for _, vmClaimCreateReq := range vmClaimRequests { + vmClaimId := vmClaimCreateReq.GetId() + vmClaimCreateReq.Labels[hflabels.SessionLabel] = sessionId + _, err = sss.vmclaimClient.CreateVMClaim(r.Context(), vmClaimCreateReq) + if err != nil { + glog.Errorf("error creating vm claim: %s", hferrors.GetErrorMessage(err)) + errMsg := fmt.Sprintf("error creating vm claim %s", vmClaimId) + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + return + } + _, err = sss.vmclaimClient.UpdateVMClaimStatus(r.Context(), &vmclaimpb.UpdateVMClaimStatusRequest{ + Id: vmClaimId, + BindMode: bindMode, + Bound: wrapperspb.Bool(false), + Ready: wrapperspb.Bool(false), + }) + if err != nil { + glog.Errorf("error updating vm claim status %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error while creating vm claim: could not update vm claim status") + return + } + } + + createdProgress, err := sss.progressClient.CreateProgress(r.Context(), &progresspb.CreateProgressRequest{ + CurrentStep: 0, + MaxStep: 0, + TotalStep: uint32(len(scenario.GetSteps())), + Scenario: scenarioid, + Course: courseid, + User: user.GetId(), + Labels: map[string]string{ + hflabels.SessionLabel: sessionId, // map to session + hflabels.ScheduledEventLabel: scheduledEventId, // map to scheduledevent + hflabels.UserLabel: user.GetId(), // map to user + "finished": "false", // default is in progress, finished = false + }, + }) + if err != nil { + glog.Errorf("error creating progress %s", hferrors.GetErrorMessage(err)) + return + } + glog.V(2).Infof("created progress with ID %s", createdProgress.GetId()) + + preparedSession := preparedSession{ + Id: sessionId, + ScenarioId: scenarioid, + CourseId: courseid, + KeepCourseVM: keepVm, + UserId: user.GetId(), + VmClaimSet: sessionVmClaimSet, + AccessCode: accessCodeId, + } + encodedSS, err := json.Marshal(preparedSession) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 201, "created", encodedSS) +} + +func (sss SessionServer) FinishProgress(ctx context.Context, sessionId string, userId string) error { + now := time.Now() + + _, err := sss.progressClient.UpdateCollectionProgress(ctx, &progresspb.UpdateCollectionProgressRequest{ + Labelselector: fmt.Sprintf("%s=%s,%s=%s,finished=false", hflabels.SessionLabel, sessionId, hflabels.UserLabel, userId), + Finished: "true", + LastUpdate: now.Format(time.UnixDate), + }) + // If the error is a NotFoundError, let's ignore it. There simply did not exist any progress for this session. + if err != nil && !hferrors.IsGrpcNotFound(err) { + glog.Errorf("error while finishing progress %s", hferrors.GetErrorMessage(err)) + return err + } + return nil +} + +func (sss SessionServer) FinishedSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to finish sessions") + return + } + impersonatedUserId := user.GetId() + + vars := mux.Vars(r) + + sessionId := vars["session_id"] + if len(sessionId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") + return + } + + ss, err := sss.internalSessionServer.GetSession(r.Context(), &generalpb.GetRequest{Id: sessionId, LoadFromCache: true}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving session") + return + } + if ss.GetUser() != impersonatedUserId { + // check if the user has access to write sessions + authrResponse, err := rbac.AuthorizeSimple(r, sss.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "access denied to update session") + return + } + } + + now := time.Now().Format(time.UnixDate) + + _, err = sss.internalSessionServer.UpdateSessionStatus(r.Context(), &sessionpb.UpdateSessionStatusRequest{ + Id: sessionId, + Active: wrapperspb.Bool(false), + ExpirationTime: now, + }) + + if err != nil { + glog.Errorf("error marking session as expired: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error terminating session") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "updated session") +} + +func (sss SessionServer) KeepAliveSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to sessions") + return + } + + vars := mux.Vars(r) + + sessionId := vars["session_id"] + if len(sessionId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no session id passed in") + return + } + + ss, err := sss.internalSessionServer.GetSession(r.Context(), &generalpb.GetRequest{Id: sessionId, LoadFromCache: true}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving session") + return + } + if ss.GetUser() != user.GetId() { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") + return + } + + if ss.GetStatus().GetFinished() { + util.ReturnHTTPMessage(w, r, 404, "notfound", "session was finished") + return + } + + if ss.GetStatus().GetPaused() { + glog.V(4).Infof("session %s was paused, returning paused", ss.GetId()) + + now := time.Now() + pauseExpiration, err := time.Parse(time.UnixDate, ss.GetStatus().GetPausedTime()) + + if err != nil { + glog.Error(err) + util.ReturnHTTPMessage(w, r, 304, "paused", "session is paused") + return + } + + timeUntilExpiration := pauseExpiration.Sub(now) + + util.ReturnHTTPMessage(w, r, 202, "paused", timeUntilExpiration.String()) + return + } + + sessionAc := ss.GetAccessCode() // the session's access code + if sessionAc != "" { + // If we receive an AccessCodeObj from the accessCode Client the AC from this session is still valid, if we find no AccessCode it was deleted or time ran out. + // We will gracefully end this session by just not increasing the Session ExpirationTime anymore. This will end the session at maximum after the AC expired + _, err := sss.acClient.GetAccessCodeWithOTACs(r.Context(), &generalpb.ResourceId{Id: sessionAc}) + if err != nil { + util.ReturnHTTPMessage(w, r, 400, "error", "Session is overdue, can not increase duration") + return + } + } + + scenarioId := ss.GetScenario() // the session's scenario ID + courseId := ss.GetCourse() // the session's course ID + course, scenario, ok := sss.getCourseAndScenarioFromCache(w, r, courseId, scenarioId) + if !ok { + // we encountered an error and already returned an HTTPMessage in getCourseAndScenarioFromCache() + return + } + + expiration, err := calculateExpiration(newSSTimeout, course.GetKeepaliveDuration(), scenario.GetKeepaliveDuration()) + if err != nil { + glog.Errorf("Unable to calculate session expiration: %v", err) + errMsg := "Failed to calculate session expiration. Please check your course/scenario keepalive settings." + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + } + + _, err = sss.internalSessionServer.UpdateSessionStatus(r.Context(), &sessionpb.UpdateSessionStatusRequest{ + Id: sessionId, + ExpirationTime: expiration, + }) + + if err != nil { + glog.Errorf("error updating expiration of session status: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "Error: Unable to extend session lifetime.") + return + } + + util.ReturnHTTPMessage(w, r, 202, "keepalived", "keepalive successful") +} + +func (sss SessionServer) PauseSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to pause sessions") + return + } + + vars := mux.Vars(r) + + sessionId := vars["session_id"] + if len(sessionId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "bad request", "no session id passed in") + return + } + + ss, err := sss.internalSessionServer.GetSession(r.Context(), &generalpb.GetRequest{Id: sessionId, LoadFromCache: true}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving session") + return + } + if ss.GetUser() != user.GetId() { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") + return + } + + scenarioId := ss.GetScenario() // the session's scenario ID + courseId := ss.GetCourse() // the session's course ID + + course, scenario, ok := sss.getCourseAndScenarioFromCache(w, r, courseId, scenarioId) + if !ok { + // we encountered an error and already returned an HTTPMessage in getCourseAndScenarioFromCache() + return + } + + // We always use the Getter functions to retrieve struct fields since they provide a fallback if the object is nil + if !course.GetPausable() && !scenario.GetPausable() { + // either course and scenario are not pausable or the session does not contain any course/scenario + glog.Error("session is not pauseable") + util.ReturnHTTPMessage(w, r, 500, "error", "not pauseable") + return + } + + pauseExpiration, err := calculateExpiration(pauseSSTimeout, course.GetPauseDuration(), scenario.GetPauseDuration()) + if err != nil { + glog.Errorf("Unable to calculate pause expiration: %v", err) + errMsg := "Failed to calculate pause expiration. Please check your course/scenario pause duration settings." + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + } + + _, err = sss.internalSessionServer.UpdateSessionStatus(r.Context(), &sessionpb.UpdateSessionStatusRequest{ + Id: sessionId, + Paused: wrapperspb.Bool(true), + PausedTime: wrapperspb.String(pauseExpiration), + }) + + if err != nil { + glog.Errorf("error updating pause duration of session status %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "Error: Unable to extend pause duration") + return + } + + util.ReturnHTTPMessage(w, r, 204, "updated", "updated session") +} + +func (sss SessionServer) ResumeSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to resume sessions") + return + } + + vars := mux.Vars(r) + + sessionId := vars["session_id"] + if len(sessionId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") + return + } + + ss, err := sss.internalSessionServer.GetSession(r.Context(), &generalpb.GetRequest{Id: sessionId, LoadFromCache: true}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error retrieving session") + return + } + if ss.GetUser() != user.GetId() { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") + return + } + + course, scenario, ok := sss.getCourseAndScenarioFromCache(w, r, ss.GetScenario(), ss.GetCourse()) + if !ok { + // we encountered an error and already returned an HTTPMessage in getCourseAndScenarioFromCache() + return + } + + newExpiration, err := calculateExpiration(keepaliveSSTimeout, course.GetKeepaliveDuration(), scenario.GetKeepaliveDuration()) + if err != nil { + glog.Errorf("Unable to calculate session expiration: %v", err) + errMsg := "Failed to calculate session expiration. Please check your course/scenario keepalive settings." + util.ReturnHTTPMessage(w, r, 500, "error", errMsg) + } + + _, err = sss.internalSessionServer.UpdateSessionStatus(r.Context(), &sessionpb.UpdateSessionStatusRequest{ + Id: sessionId, + Paused: wrapperspb.Bool(false), + PausedTime: wrapperspb.String(""), + ExpirationTime: newExpiration, + }) + + if err != nil { + glog.Errorf("error updating session status: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "Error: Failed to resume session, unable to update session expiration!") + return + } + + util.ReturnHTTPMessage(w, r, 204, "updated", "resumed session") +} + +func (sss SessionServer) GetSessionFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, sss.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get sessions") + return + } + impersonatedUserId := user.GetId() + + vars := mux.Vars(r) + + sessionId := vars["session_id"] + if len(sessionId) == 0 { + util.ReturnHTTPMessage(w, r, 500, "error", "no session id passed in") + return + } + + ss, err := sss.internalSessionServer.GetSession(r.Context(), &generalpb.GetRequest{Id: sessionId, LoadFromCache: true}) + + if err != nil { + glog.Errorf("did not find a coressponding session with the given ID") + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "error", "no session found") + return + } + + if ss.GetUser() != impersonatedUserId { + authrResponse, err := rbac.AuthorizeSimple(r, sss.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no session found that matches this user") + return + } + } + + preparedSession := preparedSession{ + Id: sessionId, + ScenarioId: ss.GetScenario(), + CourseId: ss.GetCourse(), + KeepCourseVM: ss.GetKeepCourseVm(), + UserId: ss.GetUser(), + VmClaimSet: ss.GetVmClaim(), + AccessCode: ss.GetAccessCode(), + } + encodedSS, err := json.Marshal(preparedSession) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedSS) + + glog.V(2).Infof("retrieved session %s", ss.GetId()) +} + +// returns (courseObj, scenarioObj, ok) +func (sss SessionServer) getCourseAndScenarioFromCache( + w http.ResponseWriter, + r *http.Request, + courseId string, + scenarioId string, +) (*coursepb.Course, *scenariopb.Scenario, bool) { + var scenario *scenariopb.Scenario + var course *coursepb.Course + var err error + + if scenarioId != "" { + scenario, err = sss.scenarioClient.GetScenario(r.Context(), &generalpb.GetRequest{ + Id: scenarioId, + LoadFromCache: true, + }) + if err != nil { + glog.Errorf("error retrieving scenario: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error getting scenario") + return nil, nil, false + } + } + if courseId != "" { + course, err = sss.courseClient.GetCourse(r.Context(), &generalpb.GetRequest{ + Id: courseId, + LoadFromCache: true, + }) + if err != nil { + glog.Errorf("error retrieving course: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error getting course") + return nil, nil, false + } + } + return course, scenario, true +} + +// this function can be used to either calculate the session expiration or the pause expiration +func calculateExpiration(defaultVal string, courseDuration string, scenarioDuration string) (string, error) { + ssTimeout := keepaliveSSTimeout // the default value if course/scenario keepalive is not set + + courseKeepAlive := courseDuration // course keepalive/pause duration takes precedence over scenario's keepalive/pause duration + scenarioKeepAlive := scenarioDuration + if courseKeepAlive != "" { + ssTimeout = courseKeepAlive + } else if scenarioKeepAlive != "" { + ssTimeout = scenarioKeepAlive + } + + now := time.Now() + duration, err := time.ParseDuration(ssTimeout) + if err != nil { + return "", err + } + + newExpiration := now.Add(duration).Format(time.UnixDate) + return newExpiration, nil +} diff --git a/v3/services/sessionsvc/main.go b/v3/services/sessionsvc/main.go new file mode 100644 index 00000000..3a1dc8e3 --- /dev/null +++ b/v3/services/sessionsvc/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "context" + "sync" + "time" + + "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + sessionservice "github.com/hobbyfarm/gargantua/services/sessionsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + coursepb "github.com/hobbyfarm/gargantua/v3/protos/course" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scenariopb "github.com/hobbyfarm/gargantua/v3/protos/scenario" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + ctx := context.Background() + + cfg, hfClient, kubeClient := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(sessionservice.SessionCRDInstaller{}, cfg, "session") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.AccessCode, + microservices.Course, + microservices.Progress, + microservices.Scenario, + microservices.ScheduledEvent, + microservices.VM, + microservices.VMClaim, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + acClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + courseClient := coursepb.NewCourseSvcClient(connections[microservices.Course]) + progressClient := progresspb.NewProgressSvcClient(connections[microservices.Progress]) + scenarioClient := scenariopb.NewScenarioSvcClient(connections[microservices.Scenario]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + vmClient := vmpb.NewVMSvcClient(connections[microservices.VM]) + vmClaimClient := vmclaimpb.NewVMClaimSvcClient(connections[microservices.VMClaim]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ss := sessionservice.NewGrpcSessionServer(hfClient, hfInformerFactory) + sessionpb.RegisterSessionSvcServer(gs, ss) + sessionController, err := sessionservice.NewSessionController( + kubeClient, + ss, + hfInformerFactory, + progressClient, + vmClient, + vmClaimClient, + ctx, + ) + if err != nil { + glog.Fatalf("failed creating scheduled event controller: %s", err.Error()) + } + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + sessionServer := sessionservice.NewSessionServer( + authnClient, + authrClient, + acClient, + courseClient, + progressClient, + scenarioClient, + scheduledEventClient, + vmClaimClient, + ss, + ) + microservices.StartAPIServer(sessionServer) + }() + + go func() { + defer wg.Done() + sessionController.RunSharded(stopCh, microservices.ScheduledEvent) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/settingsvc/go.mod b/v3/services/settingsvc/go.mod index ec04a4c6..6a569575 100644 --- a/v3/services/settingsvc/go.mod +++ b/v3/services/settingsvc/go.mod @@ -65,7 +65,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/client-go v12.0.0+incompatible // indirect + k8s.io/client-go v12.0.0+incompatible k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect diff --git a/v3/services/settingsvc/internal/crd.go b/v3/services/settingsvc/internal/crd.go index 99779965..d224e055 100644 --- a/v3/services/settingsvc/internal/crd.go +++ b/v3/services/settingsvc/internal/crd.go @@ -16,14 +16,18 @@ const ( namespaceNameLabel = "kubernetes.io/metadata.name" ) -func GenerateSettingCRD(caBundle string, reference crd.ServiceReference) []crder.CRD { +// SettingCRDInstaller is a struct that can generate CRDs for settings. +// It implements the CrdInstallerWithServiceReference interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type SettingCRDInstaller struct{} + +func (si SettingCRDInstaller) GenerateCRDs(caBundle string, reference crd.ServiceReference) []crder.CRD { return []crder.CRD{ - hobbyfarmCRD(&v1.Scope{}, func(c *crder.CRD) { + crd.HobbyfarmCRD(&v1.Scope{}, func(c *crder.CRD) { c.IsNamespaced(true).AddVersion("v1", &v1.Scope{}, func(cv *crder.Version) { cv.WithColumn("DisplayName", ".displayName").IsServed(true).IsStored(true) }) }), - hobbyfarmCRD(&v1.Setting{}, func(c *crder.CRD) { + crd.HobbyfarmCRD(&v1.Setting{}, func(c *crder.CRD) { c.IsNamespaced(true).AddVersion("v1", &v1.Setting{}, func(cv *crder.Version) { cv. WithColumn("DisplayName", ".displayName"). @@ -57,7 +61,3 @@ func GenerateSettingCRD(caBundle string, reference crd.ServiceReference) []crder }), } } - -func hobbyfarmCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { - return *crder.NewCRD(obj, "hobbyfarm.io", customize) -} diff --git a/v3/services/settingsvc/internal/grpc.go b/v3/services/settingsvc/internal/grpc.go index 7ffa6422..db8c2a47 100644 --- a/v3/services/settingsvc/internal/grpc.go +++ b/v3/services/settingsvc/internal/grpc.go @@ -2,39 +2,51 @@ package settingservice import ( "context" - "fmt" "strconv" "github.com/golang/glog" hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" labels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/property" settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" "github.com/hobbyfarm/gargantua/v3/pkg/util" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - empty "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/wrapperspb" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" ) type GrpcSettingServer struct { - settingProto.UnimplementedSettingSvcServer - hfClientSet hfClientset.Interface - ctx context.Context + settingpb.UnimplementedSettingSvcServer + settingClient hfClientsetv1.SettingInterface + settingLister listersv1.SettingLister + settingSynced cache.InformerSynced + scopeClient hfClientsetv1.ScopeInterface + scopeLister listersv1.ScopeLister + scopeSynced cache.InformerSynced } -func NewGrpcSettingServer(hfClientSet hfClientset.Interface, ctx context.Context) *GrpcSettingServer { +func NewGrpcSettingServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcSettingServer { + ns := util.GetReleaseNamespace() return &GrpcSettingServer{ - hfClientSet: hfClientSet, - ctx: ctx, + settingClient: hfClientSet.HobbyfarmV1().Settings(ns), + settingLister: hfInformerFactory.Hobbyfarm().V1().Settings().Lister(), + settingSynced: hfInformerFactory.Hobbyfarm().V1().Settings().Informer().HasSynced, + scopeClient: hfClientSet.HobbyfarmV1().Scopes(ns), + scopeLister: hfInformerFactory.Hobbyfarm().V1().Scopes().Lister(), + scopeSynced: hfInformerFactory.Hobbyfarm().V1().Scopes().Informer().HasSynced, } } -func (s *GrpcSettingServer) CreateScope(ctx context.Context, creq *settingProto.CreateScopeRequest) (*empty.Empty, error) { +func (s *GrpcSettingServer) CreateScope(ctx context.Context, creq *settingpb.CreateScopeRequest) (*emptypb.Empty, error) { hfScope := &hfv1.Scope{ ObjectMeta: metav1.ObjectMeta{ Name: creq.GetName(), @@ -42,62 +54,57 @@ func (s *GrpcSettingServer) CreateScope(ctx context.Context, creq *settingProto. }, DisplayName: creq.GetDisplayName(), } - _, err := s.hfClientSet.HobbyfarmV1().Scopes(util.GetReleaseNamespace()).Create(ctx, hfScope, metav1.CreateOptions{}) + _, err := s.scopeClient.Create(ctx, hfScope, metav1.CreateOptions{}) if err != nil { - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, err.Error(), + creq, ) - newErr, wde := newErr.WithDetails(creq) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (s *GrpcSettingServer) GetScope(ctx context.Context, id *settingProto.Id) (*settingProto.Scope, error) { - scope, err := s.hfClientSet.HobbyfarmV1().Scopes(util.GetReleaseNamespace()).Get(s.ctx, id.GetName(), metav1.GetOptions{}) - if errors.IsNotFound(err) { - glog.Errorf("scope %s not found", id.GetName()) - newErr := status.Newf( - codes.NotFound, - "scope %s not found", - id.GetName(), - ) - newErr, wde := newErr.WithDetails(id) - if wde != nil { - return &settingProto.Scope{}, wde - } - return &settingProto.Scope{}, newErr.Err() +func (s *GrpcSettingServer) GetScope(ctx context.Context, req *generalpb.GetRequest) (*settingpb.Scope, error) { + scope, err := util.GenericHfGetter(ctx, req, s.scopeClient, s.scopeLister.Scopes(util.GetReleaseNamespace()), "scope", s.scopeSynced()) + if err != nil { + return &settingpb.Scope{}, err } - return &settingProto.Scope{Name: scope.Name, DisplayName: scope.DisplayName}, nil + + return &settingpb.Scope{Name: scope.Name, Uid: string(scope.UID), DisplayName: scope.DisplayName}, nil } -func (s *GrpcSettingServer) ListScopes(ctx context.Context, empty *empty.Empty) (*settingProto.Scopes, error) { - scopes, err := s.hfClientSet.HobbyfarmV1().Scopes(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{}) +func (s *GrpcSettingServer) ListScopes(ctx context.Context, listOptions *generalpb.ListOptions) (*settingpb.Scopes, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var scopes []hfv1.Scope + var err error + if !doLoadFromCache { + var scopeList *hfv1.ScopeList + scopeList, err = util.ListByHfClient(ctx, listOptions, s.scopeClient, "scopes") + if err == nil { + scopes = scopeList.Items + } + } else { + scopes, err = util.ListByCache(listOptions, s.scopeLister, "scopes", s.scopeSynced()) + } if err != nil { - glog.Errorf("error while listing scopes: %s", err.Error()) - newErr := status.Newf( - codes.Internal, - "error listing scopes", - ) - return &settingProto.Scopes{}, newErr.Err() + glog.Error(err) + return &settingpb.Scopes{}, err } - var preparedScopes = make([]*settingProto.Scope, len(scopes.Items)) + var preparedScopes = make([]*settingpb.Scope, len(scopes)) - for i, s := range scopes.Items { - preparedScopes[i] = &settingProto.Scope{ + for i, s := range scopes { + preparedScopes[i] = &settingpb.Scope{ Name: s.Name, + Uid: string(s.UID), DisplayName: s.DisplayName, } } - return &settingProto.Scopes{Scopes: preparedScopes}, nil + return &settingpb.Scopes{Scopes: preparedScopes}, nil } -func (s *GrpcSettingServer) CreateSetting(ctx context.Context, creq *settingProto.CreateSettingRequest) (*empty.Empty, error) { +func (s *GrpcSettingServer) CreateSetting(ctx context.Context, creq *settingpb.CreateSettingRequest) (*emptypb.Empty, error) { hfSetting := &hfv1.Setting{ ObjectMeta: metav1.ObjectMeta{ Name: creq.GetName(), @@ -111,101 +118,86 @@ func (s *GrpcSettingServer) CreateSetting(ctx context.Context, creq *settingProt DisplayName: creq.GetProperty().GetDisplayName(), }, } - _, err := s.hfClientSet.HobbyfarmV1().Settings(util.GetReleaseNamespace()).Create(ctx, hfSetting, metav1.CreateOptions{}) + _, err := s.settingClient.Create(ctx, hfSetting, metav1.CreateOptions{}) if err != nil { - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, err.Error(), + creq, ) - newErr, wde := newErr.WithDetails(creq) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (s *GrpcSettingServer) GetSettingValue(ctx context.Context, sreq *settingProto.Id) (*settingProto.SettingValue, error) { - resp := &settingProto.SettingValue{} - setting, err := GetSetting(settingUtil.SettingName(sreq.GetName())) +func (s *GrpcSettingServer) GetSettingValue(ctx context.Context, sreq *generalpb.ResourceId) (*settingpb.SettingValue, error) { + resp := &settingpb.SettingValue{} + setting, err := GetSetting(settingUtil.SettingName(sreq.GetId())) if err != nil { - newErr := status.Newf( + return &settingpb.SettingValue{}, hferrors.GrpcError( codes.InvalidArgument, err.Error(), + sreq, ) - newErr, wde := newErr.WithDetails(sreq) - if wde != nil { - return resp, wde - } - return resp, newErr.Err() } settingValue, err := setting.FromJSON(setting.Value) if err != nil { glog.Error("could not parse JSON value") - newErr := status.Newf( + return &settingpb.SettingValue{}, hferrors.GrpcError( codes.Internal, "error parsing JSON value for setting %s", - sreq.GetName(), + sreq, + sreq.GetId(), ) - newErr, wde := newErr.WithDetails(sreq) - if wde != nil { - return resp, wde - } - return resp, newErr.Err() } switch v := settingValue.(type) { case bool: - resp.Value = &settingProto.SettingValue_BoolValue{BoolValue: v} + resp.Value = &settingpb.SettingValue_BoolValue{BoolValue: v} case string: - resp.Value = &settingProto.SettingValue_StringValue{StringValue: v} + resp.Value = &settingpb.SettingValue_StringValue{StringValue: v} case float64: - resp.Value = &settingProto.SettingValue_Float64Value{Float64Value: v} + resp.Value = &settingpb.SettingValue_Float64Value{Float64Value: v} case int: - resp.Value = &settingProto.SettingValue_Int64Value{Int64Value: int64(v)} + resp.Value = &settingpb.SettingValue_Int64Value{Int64Value: int64(v)} default: - newErr := status.Newf( + return &settingpb.SettingValue{}, hferrors.GrpcError( codes.Internal, "error setting %s did not match any of the following types: bool, string, float64, int", - sreq.GetName(), + sreq, + sreq.GetId(), ) - newErr, wde := newErr.WithDetails(sreq) - if wde != nil { - return resp, wde - } - return resp, newErr.Err() } return resp, nil } -func (s *GrpcSettingServer) ListSettings(ctx context.Context, lreq *settingProto.ListSettingsRequest) (*settingProto.ListSettingsResponse, error) { - kSettings, err := s.hfClientSet.HobbyfarmV1().Settings(util.GetReleaseNamespace()).List(s.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", labels.SettingScope, lreq.GetScope()), - }) - if err != nil { - glog.Errorf("error listing settings: %s", err.Error()) - newErr := status.Newf( - codes.Internal, - "error listing settings", - ) - newErr, wde := newErr.WithDetails(lreq) - if wde != nil { - return &settingProto.ListSettingsResponse{}, wde +func (s *GrpcSettingServer) ListSettings(ctx context.Context, listOptions *generalpb.ListOptions) (*settingpb.ListSettingsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var settings []hfv1.Setting + var err error + if !doLoadFromCache { + var settingList *hfv1.SettingList + settingList, err = util.ListByHfClient(ctx, listOptions, s.settingClient, "settings") + if err == nil { + settings = settingList.Items } - return &settingProto.ListSettingsResponse{}, newErr.Err() + } else { + settings, err = util.ListByCache(listOptions, s.settingLister, "settings", s.settingSynced()) + } + if err != nil { + glog.Error(err) + return &settingpb.ListSettingsResponse{}, err } - var settings []*settingProto.PreparedListSetting - for _, ks := range kSettings.Items { + var preparedSettings []*settingpb.PreparedListSetting + for _, ks := range settings { scope := ks.Labels[labels.SettingScope] weight := ks.Labels[labels.SettingWeight] group := ks.Labels[labels.SettingGroup] iweight, _ := strconv.Atoi(weight) - prepListSetting := &settingProto.PreparedListSetting{Name: ks.Name, Property: &settingProto.Property{ + prepListSetting := &settingpb.PreparedListSetting{Name: ks.Name, Uid: string(ks.UID), Property: &settingpb.Property{ DataType: settingUtil.DataTypeMappingToProto[ks.Property.DataType], ValueType: settingUtil.ValueTypeMappingToProto[ks.Property.ValueType], DisplayName: ks.DisplayName, @@ -234,134 +226,95 @@ func (s *GrpcSettingServer) ListSettings(ctx context.Context, lreq *settingProto if ks.Default != nil { prepListSetting.Property.Default = wrapperspb.String(*ks.Property.Default) } - settings = append(settings, prepListSetting) + preparedSettings = append(preparedSettings, prepListSetting) } - return &settingProto.ListSettingsResponse{Settings: settings}, nil - + return &settingpb.ListSettingsResponse{Settings: preparedSettings}, nil } -func (s *GrpcSettingServer) GetSetting(ctx context.Context, id *settingProto.Id) (*settingProto.Setting, error) { - kSetting, err := s.hfClientSet.HobbyfarmV1().Settings(util.GetReleaseNamespace()).Get(s.ctx, id.GetName(), metav1.GetOptions{}) - if errors.IsNotFound(err) { - glog.Errorf("setting %s not found", id.GetName()) - newErr := status.Newf( - codes.NotFound, - "setting %s not found", - id.GetName(), - ) - newErr, wde := newErr.WithDetails(id) - if wde != nil { - return &settingProto.Setting{}, wde - } - return &settingProto.Setting{}, newErr.Err() - } +func (s *GrpcSettingServer) GetSetting(ctx context.Context, req *generalpb.GetRequest) (*settingpb.Setting, error) { + setting, err := util.GenericHfGetter(ctx, req, s.settingClient, s.settingLister.Settings(util.GetReleaseNamespace()), "setting", s.settingSynced()) if err != nil { - glog.Errorf("error getting setting from database: %s", err.Error()) - newErr := status.Newf( - codes.Internal, - "error retrieving setting", - ) - newErr, wde := newErr.WithDetails(id) - if wde != nil { - return &settingProto.Setting{}, wde - } - return &settingProto.Setting{}, newErr.Err() + return &settingpb.Setting{}, err } // check if the user has permissions to do this action - scope, ok := kSetting.Labels[labels.SettingScope] + scope, ok := setting.Labels[labels.SettingScope] if !ok { - glog.Errorf("setting %s does not have scope label", kSetting.Name) - newErr := status.Newf( + glog.Errorf("setting %s does not have scope label", setting.Name) + return &settingpb.Setting{}, hferrors.GrpcError( codes.Internal, "error retrieving scope label", + req, ) - newErr, wde := newErr.WithDetails(id) - if wde != nil { - return &settingProto.Setting{}, wde - } - return &settingProto.Setting{}, newErr.Err() } - prepSetting := &settingProto.Setting{Name: kSetting.Name, Property: &settingProto.Property{ - DataType: settingUtil.DataTypeMappingToProto[kSetting.Property.DataType], - ValueType: settingUtil.ValueTypeMappingToProto[kSetting.Property.ValueType], - DisplayName: kSetting.DisplayName, - Required: kSetting.Required, - Enum: kSetting.Enum, - UniqueItems: kSetting.UniqueItems, - }, Value: kSetting.Value, Scope: scope} + prepSetting := &settingpb.Setting{Name: setting.Name, Uid: string(setting.UID), Property: &settingpb.Property{ + DataType: settingUtil.DataTypeMappingToProto[setting.Property.DataType], + ValueType: settingUtil.ValueTypeMappingToProto[setting.Property.ValueType], + DisplayName: setting.DisplayName, + Required: setting.Required, + Enum: setting.Enum, + UniqueItems: setting.UniqueItems, + }, Value: setting.Value, Scope: scope} - if kSetting.Maximum != nil { - prepSetting.Property.Maximum = wrapperspb.Double(*kSetting.Property.Maximum) + if setting.Maximum != nil { + prepSetting.Property.Maximum = wrapperspb.Double(*setting.Property.Maximum) } - if kSetting.Minimum != nil { - prepSetting.Property.Minimum = wrapperspb.Double(*kSetting.Property.Minimum) + if setting.Minimum != nil { + prepSetting.Property.Minimum = wrapperspb.Double(*setting.Property.Minimum) } - if kSetting.MaxLength != nil { - prepSetting.Property.MaxLength = wrapperspb.Int64(*kSetting.Property.MaxLength) + if setting.MaxLength != nil { + prepSetting.Property.MaxLength = wrapperspb.Int64(*setting.Property.MaxLength) } - if kSetting.MinLength != nil { - prepSetting.Property.MinLength = wrapperspb.Int64(*kSetting.Property.MinLength) + if setting.MinLength != nil { + prepSetting.Property.MinLength = wrapperspb.Int64(*setting.Property.MinLength) } - if kSetting.Format != nil { - prepSetting.Property.Format = wrapperspb.String(*kSetting.Property.Format) + if setting.Format != nil { + prepSetting.Property.Format = wrapperspb.String(*setting.Property.Format) } - if kSetting.Pattern != nil { - prepSetting.Property.Pattern = wrapperspb.String(*kSetting.Property.Pattern) + if setting.Pattern != nil { + prepSetting.Property.Pattern = wrapperspb.String(*setting.Property.Pattern) } - if kSetting.Default != nil { - prepSetting.Property.Default = wrapperspb.String(*kSetting.Property.Default) + if setting.Default != nil { + prepSetting.Property.Default = wrapperspb.String(*setting.Property.Default) } return prepSetting, nil } -func (s *GrpcSettingServer) UpdateSetting(ctx context.Context, setting *settingProto.Setting) (*empty.Empty, error) { - kSetting, err := s.hfClientSet.HobbyfarmV1().Settings(util.GetReleaseNamespace()).Get(s.ctx, setting.GetName(), metav1.GetOptions{}) +func (s *GrpcSettingServer) UpdateSetting(ctx context.Context, setting *settingpb.Setting) (*emptypb.Empty, error) { + kSetting, err := s.settingClient.Get(ctx, setting.GetName(), metav1.GetOptions{}) if err != nil { - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "error updating setting: %s", + setting, err.Error(), ) - newErr, wde := newErr.WithDetails(setting) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } // validate the value if err := kSetting.Validate(setting.GetValue()); err != nil { glog.Errorf("error validating value: %s", err.Error()) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.InvalidArgument, "error updating setting: %s", + setting, err.Error(), ) - newErr, wde := newErr.WithDetails(setting) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } kSetting.Value = setting.GetValue() - _, err = s.hfClientSet.HobbyfarmV1().Settings(util.GetReleaseNamespace()).Update(s.ctx, kSetting, metav1.UpdateOptions{}) + _, err = s.settingClient.Update(ctx, kSetting, metav1.UpdateOptions{}) if err != nil { glog.Errorf("error updating setting: %s", err.Error()) - newErr := status.Newf( + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "error updating setting", + setting, ) - newErr, wde := newErr.WithDetails(setting) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } diff --git a/v3/services/settingsvc/internal/preinstall.go b/v3/services/settingsvc/internal/preinstall.go index a4793869..fc281bcb 100644 --- a/v3/services/settingsvc/internal/preinstall.go +++ b/v3/services/settingsvc/internal/preinstall.go @@ -5,12 +5,12 @@ import ( "sync" "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" "github.com/hobbyfarm/gargantua/v3/pkg/labels" settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" "github.com/hobbyfarm/gargantua/v3/pkg/util" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" ) func Preinstall(ctx context.Context, internalSettingServer *GrpcSettingServer) { @@ -32,8 +32,8 @@ func installResources(ctx context.Context, internalSettingServer *GrpcSettingSer defer wg.Done() for _, scope := range scopes() { - _, err := internalSettingServer.GetScope(ctx, &settingProto.Id{Name: scope.GetName()}) - if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound { + _, err := internalSettingServer.GetScope(ctx, &generalpb.GetRequest{Id: scope.GetName()}) + if hferrors.IsGrpcNotFound(err) { if _, err := internalSettingServer.CreateScope(ctx, scope); err != nil { return err } @@ -45,8 +45,8 @@ func installResources(ctx context.Context, internalSettingServer *GrpcSettingSer } for _, setting := range predefinedSettings() { - _, err := internalSettingServer.GetSetting(ctx, &settingProto.Id{Name: setting.GetName()}) - if s, ok := status.FromError(err); ok && s.Code() == codes.NotFound { + _, err := internalSettingServer.GetSetting(ctx, &generalpb.GetRequest{Id: setting.GetName()}) + if hferrors.IsGrpcNotFound(err) { if _, err := internalSettingServer.CreateSetting(ctx, setting); err != nil { return err } @@ -59,8 +59,8 @@ func installResources(ctx context.Context, internalSettingServer *GrpcSettingSer return nil } -func scopes() []*settingProto.CreateScopeRequest { - return []*settingProto.CreateScopeRequest{ +func scopes() []*settingpb.CreateScopeRequest { + return []*settingpb.CreateScopeRequest{ { Name: "public", Namespace: util.GetReleaseNamespace(), @@ -84,8 +84,8 @@ func scopes() []*settingProto.CreateScopeRequest { } } -func predefinedSettings() []*settingProto.CreateSettingRequest { - return []*settingProto.CreateSettingRequest{ +func predefinedSettings() []*settingpb.CreateSettingRequest { + return []*settingpb.CreateSettingRequest{ { Name: string(settingUtil.SettingAdminUIMOTD), Namespace: util.GetReleaseNamespace(), @@ -93,9 +93,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "admin-ui", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Admin UI MOTD", }, }, @@ -106,9 +106,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "public", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "User UI MOTD", }, }, @@ -119,9 +119,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "public", }, Value: "false", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_BOOLEAN, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_BOOLEAN, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Registration Disabled", }, }, @@ -133,9 +133,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "gargantua", }, Value: "24", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_INTEGER, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_INTEGER, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "ScheduledEvent retention time (h)", }, }, @@ -148,9 +148,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingWeight: "3", }, Value: "false", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_BOOLEAN, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_BOOLEAN, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Require Privacy Policy acception", }, }, @@ -163,9 +163,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingWeight: "2", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "URL to Privacy Policy Agreement", }, }, @@ -178,9 +178,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingWeight: "1", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Privacy Policy URL Display Name", }, }, @@ -193,9 +193,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingWeight: "1", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "URL to Imprint", }, }, @@ -208,9 +208,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingWeight: "2", }, Value: "", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Imprint URL Display Name", }, }, @@ -222,9 +222,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingGroup: "about-modal", }, Value: "{\"HobbyFarm Project\":\"https://github.com/hobbyfarm\"}", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_STRING, - ValueType: settingProto.ValueType_VALUE_TYPE_MAP, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_STRING, + ValueType: settingpb.ValueType_VALUE_TYPE_MAP, DisplayName: "About Modal Buttons (Title -> URL)", }, }, @@ -235,9 +235,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "gargantua", }, Value: "false", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_BOOLEAN, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_BOOLEAN, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "Strict AccessCode Validation", }, }, @@ -248,9 +248,9 @@ func predefinedSettings() []*settingProto.CreateSettingRequest { labels.SettingScope: "gargantua", }, Value: "24", - Property: &settingProto.Property{ - DataType: settingProto.DataType_DATA_TYPE_INTEGER, - ValueType: settingProto.ValueType_VALUE_TYPE_SCALAR, + Property: &settingpb.Property{ + DataType: settingpb.DataType_DATA_TYPE_INTEGER, + ValueType: settingpb.ValueType_VALUE_TYPE_SCALAR, DisplayName: "User Token Expiration (hours)", }, }, diff --git a/v3/services/settingsvc/internal/server.go b/v3/services/settingsvc/internal/server.go index 9c30f1e5..64e74fc1 100644 --- a/v3/services/settingsvc/internal/server.go +++ b/v3/services/settingsvc/internal/server.go @@ -5,17 +5,17 @@ import ( "github.com/golang/glog" "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" ) type SettingServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient internalSettingServer *GrpcSettingServer } -func NewSettingServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, internalSettingServer *GrpcSettingServer) (SettingServer, error) { +func NewSettingServer(authnClient authnpb.AuthNClient, authrClient authrpb.AuthRClient, internalSettingServer *GrpcSettingServer) (SettingServer, error) { s := SettingServer{} s.authnClient = authnClient s.authrClient = authrClient diff --git a/v3/services/settingsvc/internal/settingservice.go b/v3/services/settingsvc/internal/settingservice.go index cba9296d..423a2990 100644 --- a/v3/services/settingsvc/internal/settingservice.go +++ b/v3/services/settingsvc/internal/settingservice.go @@ -2,20 +2,24 @@ package settingservice import ( "encoding/json" + "fmt" "io" "net/http" "strings" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/golang/glog" "github.com/gorilla/mux" + "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/property" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" settingUtil "github.com/hobbyfarm/gargantua/v3/pkg/setting" "github.com/hobbyfarm/gargantua/v3/pkg/util" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" ) const ( @@ -25,7 +29,7 @@ const ( type PreparedSetting struct { Name string `json:"name"` - *settingProto.Property + *settingpb.Property DataType property.DataType `json:"dataType"` ValueType property.ValueType `json:"valueType"` Value any `json:"value"` @@ -61,7 +65,8 @@ func (s SettingServer) ListFunc(w http.ResponseWriter, r *http.Request) { } } - kSettings, err := s.internalSettingServer.ListSettings(r.Context(), &settingProto.ListSettingsRequest{Scope: scope}) + labelSelector := fmt.Sprintf("%s=%s", labels.SettingScope, scope) + kSettings, err := s.internalSettingServer.ListSettings(r.Context(), &generalpb.ListOptions{LabelSelector: labelSelector}) if err != nil { glog.Errorf("error listing settings: %s", err.Error()) util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing settings") @@ -147,14 +152,10 @@ func (s SettingServer) UpdateCollection(w http.ResponseWriter, r *http.Request) } func (s SettingServer) update(w http.ResponseWriter, r *http.Request, updatedSetting PreparedSetting) bool { - setting, err := s.internalSettingServer.GetSetting(r.Context(), &settingProto.Id{Name: updatedSetting.Name}) + setting, err := s.internalSettingServer.GetSetting(r.Context(), &generalpb.GetRequest{Id: updatedSetting.Name}) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.NotFound { - util.ReturnHTTPMessage(w, r, 404, "error", "setting not found") - return false - } - util.ReturnHTTPMessage(w, r, 500, "internalerror", "error retrieving setting for update") + if hferrors.IsGrpcNotFound(err) { + util.ReturnHTTPMessage(w, r, 404, "error", "setting not found") return false } util.ReturnHTTPMessage(w, r, 500, "internalerror", "error retrieving setting for update") @@ -177,7 +178,7 @@ func (s SettingServer) update(w http.ResponseWriter, r *http.Request, updatedSet val, err := json.Marshal(updatedSetting.Value) // json marshalled strings have quotes before & after, we don't need or want that - if setting.Property.GetDataType() == settingProto.DataType_DATA_TYPE_STRING && setting.Property.GetValueType() == settingProto.ValueType_VALUE_TYPE_SCALAR { + if setting.Property.GetDataType() == settingpb.DataType_DATA_TYPE_STRING && setting.Property.GetValueType() == settingpb.ValueType_VALUE_TYPE_SCALAR { val = []byte(strings.Replace(string(val), "\"", "", 2)) } @@ -191,12 +192,9 @@ func (s SettingServer) update(w http.ResponseWriter, r *http.Request, updatedSet _, err = s.internalSettingServer.UpdateSetting(r.Context(), setting) if err != nil { - if s, ok := status.FromError(err); ok { - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, 400, "error", s.Message()) - return false - } - util.ReturnHTTPMessage(w, r, 500, "internalerror", s.Message()) + statusErr := status.Convert(err) + if statusErr.Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, 400, "error", statusErr.Message()) return false } util.ReturnHTTPMessage(w, r, 500, "internalerror", "error updating setting") @@ -224,7 +222,7 @@ func (s SettingServer) ListScopeFunc(w http.ResponseWriter, r *http.Request) { return } - scopes, err := s.internalSettingServer.ListScopes(r.Context(), &emptypb.Empty{}) + scopes, err := s.internalSettingServer.ListScopes(r.Context(), &generalpb.ListOptions{}) if err != nil { util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "internalerror", "error listing scopes") glog.Errorf("error while listing scopes: %s", err.Error()) diff --git a/v3/services/settingsvc/main.go b/v3/services/settingsvc/main.go index 1e090d0a..1278be8f 100644 --- a/v3/services/settingsvc/main.go +++ b/v3/services/settingsvc/main.go @@ -2,11 +2,9 @@ package main import ( "context" - "os" "sync" "time" - "github.com/ebauman/crder" "github.com/hobbyfarm/gargantua/v3/pkg/crd" "github.com/hobbyfarm/gargantua/v3/pkg/microservices" "github.com/hobbyfarm/gargantua/v3/pkg/signals" @@ -16,9 +14,9 @@ import ( settingservice "github.com/hobbyfarm/gargantua/services/settingsvc/v3/internal" hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - settingProto "github.com/hobbyfarm/gargantua/v3/protos/setting" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + settingpb "github.com/hobbyfarm/gargantua/v3/protos/setting" ) var ( @@ -36,22 +34,7 @@ func main() { hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) - ca, err := os.ReadFile(serviceConfig.WebhookTLSCA) - if err != nil { - glog.Fatalf("error reading ca certificate: %s", err.Error()) - } - - crds := settingservice.GenerateSettingCRD(string(ca), crd.ServiceReference{ - Namespace: util.GetReleaseNamespace(), - Name: "hobbyfarm-webhook", - }) - - glog.Info("installing/updating setting CRD") - err = crder.InstallUpdateCRDs(cfg, crds...) - if err != nil { - glog.Fatalf("failed installing/updating setting crd: %s", err.Error()) - } - glog.Info("finished installing/updating setting CRD") + crd.InstallCrdsWithServiceReference(settingservice.SettingCRDInstaller{}, cfg, "setting", serviceConfig.WebhookTLSCA) services := []microservices.MicroService{ microservices.AuthN, @@ -62,29 +45,29 @@ func main() { defer conn.Close() } - authnClient := authn.NewAuthNClient(connections[microservices.AuthN]) - authrClient := authr.NewAuthRClient(connections[microservices.AuthR]) + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) ctx := context.Background() - err = settingservice.WatchSettings(ctx, hfClient, hfInformerFactory) + err := settingservice.WatchSettings(ctx, hfClient, hfInformerFactory) if err != nil { glog.Info("watching settings failed: ", err) } gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) - ss := settingservice.NewGrpcSettingServer(hfClient, ctx) - settingProto.RegisterSettingSvcServer(gs, ss) + ss := settingservice.NewGrpcSettingServer(hfClient, hfInformerFactory) + settingpb.RegisterSettingSvcServer(gs, ss) settingservice.Preinstall(ctx, ss) var wg sync.WaitGroup - + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates wg.Add(1) + go func() { defer wg.Done() microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) }() - wg.Add(1) go func() { defer wg.Done() settingServer, err := settingservice.NewSettingServer(authnClient, authrClient, ss) diff --git a/v3/services/terraformsvc/Dockerfile b/v3/services/terraformsvc/Dockerfile new file mode 100644 index 00000000..d730a389 --- /dev/null +++ b/v3/services/terraformsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/terraformsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/terraformsvc/go.mod b/v3/services/terraformsvc/go.mod new file mode 100644 index 00000000..4c8ad6f7 --- /dev/null +++ b/v3/services/terraformsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/terraformsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/terraformsvc/go.sum b/v3/services/terraformsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/terraformsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/terraformsvc/internal/crd.go b/v3/services/terraformsvc/internal/crd.go new file mode 100644 index 00000000..86796f22 --- /dev/null +++ b/v3/services/terraformsvc/internal/crd.go @@ -0,0 +1,46 @@ +package terraformsvc + +import ( + "github.com/ebauman/crder" + terraformv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/terraformcontroller.cattle.io/v1" +) + +// TerraformCRDInstaller is a struct that generates necessary CRDs for terraform. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type TerraformCRDInstaller struct{} + +func (ti TerraformCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + terraformCRD(&terraformv1.Module{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &terraformv1.Module{}, func(cv *crder.Version) { + cv. + WithColumn("CheckTime", ".status.time") + }) + }), + terraformCRD(&terraformv1.State{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &terraformv1.State{}, func(cv *crder.Version) { + cv. + WithColumn("LastRunHash", ".status.lasRunHash"). + WithColumn("ExecutionName", ".status.executionName"). + WithColumn("StatePlanName", ".status.executionPlanName") + }) + }), + terraformCRD(&terraformv1.Execution{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &terraformv1.Execution{}, func(cv *crder.Version) { + cv. + WithColumn("JobName", ".status.jobName"). + WithColumn("PlanConfirmed", ".status.planConfirmed") + }) + }), + } +} + +func terraformCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { + return *crder.NewCRD(obj, "terraformcontroller.cattle.io", customize) +} diff --git a/v3/services/terraformsvc/internal/grpc.go b/v3/services/terraformsvc/internal/grpc.go new file mode 100644 index 00000000..0a14f27e --- /dev/null +++ b/v3/services/terraformsvc/internal/grpc.go @@ -0,0 +1,376 @@ +package terraformsvc + +import ( + "context" + "fmt" + "math/rand" + "strings" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + terraformpb "github.com/hobbyfarm/gargantua/v3/protos/terraform" + + "github.com/golang/glog" + tfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/terraformcontroller.cattle.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + tfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/terraformcontroller.cattle.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/terraformcontroller.cattle.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/timestamppb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +type GrpcTerraformServer struct { + terraformpb.UnimplementedTerraformSvcServer + stateClient tfClientsetv1.StateInterface + stateLister listersv1.StateLister + stateSynced cache.InformerSynced + executionClient tfClientsetv1.ExecutionInterface + executionLister listersv1.ExecutionLister + executionSynced cache.InformerSynced +} + +func NewGrpcTerraformServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcTerraformServer { + return &GrpcTerraformServer{ + stateClient: hfClientSet.TerraformcontrollerV1().States(util.GetReleaseNamespace()), + stateLister: hfInformerFactory.Terraformcontroller().V1().States().Lister(), + stateSynced: hfInformerFactory.Terraformcontroller().V1().States().Informer().HasSynced, + executionClient: hfClientSet.TerraformcontrollerV1().Executions(util.GetReleaseNamespace()), + executionLister: hfInformerFactory.Terraformcontroller().V1().Executions().Lister(), + executionSynced: hfInformerFactory.Terraformcontroller().V1().Executions().Informer().HasSynced, + } +} + +func (s *GrpcTerraformServer) CreateState(ctx context.Context, req *terraformpb.CreateStateRequest) (*generalpb.ResourceId, error) { + vmId := req.GetVmId() + img := req.GetImage() + variables := req.GetVariables() + moduleName := req.GetModuleName() + data := req.GetData() + autoConfirm := req.GetAutoConfirm() + destroyOnDelete := req.GetDestroyOnDelete() + version := req.GetVersion() + + requiredStringParams := map[string]string{ + "vmId": vmId, + "image": img, + "moduleName": moduleName, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + if variables == nil || len(variables.GetConfigNames()) == 0 { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.InvalidArgument, + "invalid value \"%v\" for property %s", + req, + req.GetVariables(), + "variables", + ) + } + + random := fmt.Sprintf("%08x", rand.Uint32()) + id := strings.Join([]string{vmId + "-tfs", random}, "-") + + tfs := &tfv1.State{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + }, + Spec: tfv1.StateSpec{ + Variables: tfv1.Variables{ + EnvConfigName: variables.GetEnvConfigNames(), + EnvSecretNames: variables.GetEnvSecretNames(), + ConfigNames: variables.GetConfigNames(), + SecretNames: variables.GetSecretNames(), + }, + Image: img, + AutoConfirm: autoConfirm, + DestroyOnDelete: destroyOnDelete, + ModuleName: moduleName, + Data: data, + Version: version, + }, + } + + _, err := s.stateClient.Create(ctx, tfs, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: tfs.Name}, nil +} + +func (s *GrpcTerraformServer) GetState(ctx context.Context, req *generalpb.GetRequest) (*terraformpb.State, error) { + state, err := util.GenericHfGetter(ctx, req, s.stateClient, s.stateLister.States(util.GetReleaseNamespace()), "state", s.stateSynced()) + if err != nil { + return &terraformpb.State{}, err + } + + tfConditions := []*terraformpb.Condition{} + + for _, condition := range state.Status.Conditions { + tfCondition := &terraformpb.Condition{ + Type: condition.Type, + LastUpdateTime: condition.LastUpdateTime, + LastTransitionTime: condition.LastTransitionTime, + Reason: condition.Reason, + Message: condition.Message, + } + tfConditions = append(tfConditions, tfCondition) + } + + status := &terraformpb.StateStatus{ + Conditions: tfConditions, + LastRunHash: state.Status.LastRunHash, + ExecutionName: state.Status.ExecutionName, + ExecutionPlanName: state.Status.ExecutionName, + } + + var creationTimeStamp *timestamppb.Timestamp + if !state.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(state.CreationTimestamp.Time) + } + + return &terraformpb.State{ + Id: state.Name, + Image: state.Spec.Image, + Variables: &terraformpb.Variables{ + EnvConfigNames: state.Spec.Variables.EnvConfigName, + EnvSecretNames: state.Spec.Variables.EnvSecretNames, + ConfigNames: state.Spec.Variables.ConfigNames, + SecretNames: state.Spec.Variables.SecretNames, + }, + ModuleName: state.Spec.ModuleName, + Data: state.Spec.Data, + AutoConfirm: state.Spec.AutoConfirm, + DestroyOnDelete: state.Spec.DestroyOnDelete, + Version: state.Spec.Version, + Status: status, + CreationTimestamp: creationTimeStamp, + }, nil +} + +func (s *GrpcTerraformServer) DeleteState(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.stateClient, "state") +} + +func (s *GrpcTerraformServer) DeleteCollectionState(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.stateClient, "state") +} + +func (s *GrpcTerraformServer) ListState(ctx context.Context, listOptions *generalpb.ListOptions) (*terraformpb.ListStateResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var states []tfv1.State + var err error + if !doLoadFromCache { + var stateList *tfv1.StateList + stateList, err = util.ListByHfClient(ctx, listOptions, s.stateClient, "states") + if err == nil { + states = stateList.Items + } + } else { + states, err = util.ListByCache(listOptions, s.stateLister, "states", s.stateSynced()) + } + if err != nil { + glog.Error(err) + return &terraformpb.ListStateResponse{}, err + } + + preparedStates := []*terraformpb.State{} + + for _, state := range states { + tfConditions := []*terraformpb.Condition{} + + for _, condition := range state.Status.Conditions { + tfCondition := &terraformpb.Condition{ + Type: condition.Type, + LastUpdateTime: condition.LastUpdateTime, + LastTransitionTime: condition.LastTransitionTime, + Reason: condition.Reason, + Message: condition.Message, + } + tfConditions = append(tfConditions, tfCondition) + } + + status := &terraformpb.StateStatus{ + Conditions: tfConditions, + LastRunHash: state.Status.LastRunHash, + ExecutionName: state.Status.ExecutionName, + ExecutionPlanName: state.Status.ExecutionName, + } + + var creationTimeStamp *timestamppb.Timestamp + if !state.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(state.CreationTimestamp.Time) + } + + preparedStates = append(preparedStates, &terraformpb.State{ + Id: state.Name, + Image: state.Spec.Image, + Variables: &terraformpb.Variables{ + EnvConfigNames: state.Spec.Variables.EnvConfigName, + EnvSecretNames: state.Spec.Variables.EnvSecretNames, + ConfigNames: state.Spec.Variables.ConfigNames, + SecretNames: state.Spec.Variables.SecretNames, + }, + ModuleName: state.Spec.ModuleName, + Data: state.Spec.Data, + AutoConfirm: state.Spec.AutoConfirm, + DestroyOnDelete: state.Spec.DestroyOnDelete, + Version: state.Spec.Version, + Status: status, + CreationTimestamp: creationTimeStamp, + }) + } + + return &terraformpb.ListStateResponse{States: preparedStates}, nil +} + +func (s *GrpcTerraformServer) GetExecution(ctx context.Context, req *generalpb.GetRequest) (*terraformpb.Execution, error) { + execution, err := util.GenericHfGetter(ctx, req, s.executionClient, s.executionLister.Executions(util.GetReleaseNamespace()), "execution", s.executionSynced()) + if err != nil { + return &terraformpb.Execution{}, err + } + + tfConditions := []*terraformpb.Condition{} + + for _, condition := range execution.Status.Conditions { + tfCondition := &terraformpb.Condition{ + Type: condition.Type, + LastUpdateTime: condition.LastUpdateTime, + LastTransitionTime: condition.LastTransitionTime, + Reason: condition.Reason, + Message: condition.Message, + } + tfConditions = append(tfConditions, tfCondition) + } + + status := &terraformpb.ExecutionStatus{ + Conditions: tfConditions, + JobName: execution.Status.JobName, + JobLogs: execution.Status.JobLogs, + PlanOutput: execution.Status.PlanOutput, + PlanConfirmed: execution.Status.PlanConfirmed, + ApplyOutput: execution.Status.ApplyOutput, + Outputs: execution.Status.Outputs, + } + + content := &terraformpb.ModuleContent{ + Content: execution.Spec.Content.Content, + Git: &terraformpb.GitLocation{ + Url: execution.Spec.Content.Git.URL, + Branch: execution.Spec.Content.Git.Branch, + Tag: execution.Spec.Content.Git.Tag, + Commit: execution.Spec.Content.Git.Commit, + SecretName: execution.Spec.Content.Git.SecretName, + IntervalSeconds: int64(execution.Spec.Content.Git.IntervalSeconds), + }, + } + + var creationTimeStamp *timestamppb.Timestamp + if !execution.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(execution.CreationTimestamp.Time) + } + + return &terraformpb.Execution{ + Id: execution.Name, + AutoConfirm: execution.Spec.AutoConfirm, + Content: content, + ContentHash: execution.Spec.ContentHash, + RunHash: execution.Spec.RunHash, + Data: execution.Spec.Data, + ExecutionName: execution.Spec.ExecutionName, + ExecutionVersion: execution.Spec.ExecutionVersion, + SecretName: execution.Spec.SecretName, + Status: status, + CreationTimestamp: creationTimeStamp, + }, nil +} + +func (s *GrpcTerraformServer) ListExecution(ctx context.Context, listOptions *generalpb.ListOptions) (*terraformpb.ListExecutionResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var executions []tfv1.Execution + var err error + if !doLoadFromCache { + var executionList *tfv1.ExecutionList + executionList, err = util.ListByHfClient(ctx, listOptions, s.executionClient, "executions") + if err == nil { + executions = executionList.Items + } + } else { + executions, err = util.ListByCache(listOptions, s.executionLister, "executions", s.executionSynced()) + } + if err != nil { + glog.Error(err) + return &terraformpb.ListExecutionResponse{}, err + } + + preparedExecutions := []*terraformpb.Execution{} + + for _, execution := range executions { + tfConditions := []*terraformpb.Condition{} + + for _, condition := range execution.Status.Conditions { + tfCondition := &terraformpb.Condition{ + Type: condition.Type, + LastUpdateTime: condition.LastUpdateTime, + LastTransitionTime: condition.LastTransitionTime, + Reason: condition.Reason, + Message: condition.Message, + } + tfConditions = append(tfConditions, tfCondition) + } + + status := &terraformpb.ExecutionStatus{ + Conditions: tfConditions, + JobName: execution.Status.JobName, + JobLogs: execution.Status.JobLogs, + PlanOutput: execution.Status.PlanOutput, + PlanConfirmed: execution.Status.PlanConfirmed, + ApplyOutput: execution.Status.ApplyOutput, + Outputs: execution.Status.Outputs, + } + + content := &terraformpb.ModuleContent{ + Content: execution.Spec.Content.Content, + Git: &terraformpb.GitLocation{ + Url: execution.Spec.Content.Git.URL, + Branch: execution.Spec.Content.Git.Branch, + Tag: execution.Spec.Content.Git.Tag, + Commit: execution.Spec.Content.Git.Commit, + SecretName: execution.Spec.Content.Git.SecretName, + IntervalSeconds: int64(execution.Spec.Content.Git.IntervalSeconds), + }, + } + + var creationTimeStamp *timestamppb.Timestamp + if !execution.CreationTimestamp.IsZero() { + creationTimeStamp = timestamppb.New(execution.CreationTimestamp.Time) + } + + preparedExecutions = append(preparedExecutions, &terraformpb.Execution{ + Id: execution.Name, + AutoConfirm: execution.Spec.AutoConfirm, + Content: content, + ContentHash: execution.Spec.ContentHash, + RunHash: execution.Spec.RunHash, + Data: execution.Spec.Data, + ExecutionName: execution.Spec.ExecutionName, + ExecutionVersion: execution.Spec.ExecutionVersion, + SecretName: execution.Spec.SecretName, + Status: status, + CreationTimestamp: creationTimeStamp, + }) + } + + return &terraformpb.ListExecutionResponse{Executions: preparedExecutions}, nil +} diff --git a/v3/services/terraformsvc/main.go b/v3/services/terraformsvc/main.go new file mode 100644 index 00000000..500f266f --- /dev/null +++ b/v3/services/terraformsvc/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + terraformservice "github.com/hobbyfarm/gargantua/services/terraformsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + terraformpb "github.com/hobbyfarm/gargantua/v3/protos/terraform" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(terraformservice.TerraformCRDInstaller{}, cfg, "terraform") + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + ts := terraformservice.NewGrpcTerraformServer(hfClient, hfInformerFactory) + terraformpb.RegisterTerraformSvcServer(gs, ts) + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/usersvc/internal/crd.go b/v3/services/usersvc/internal/crd.go index 7d50fbaa..57aa1ac0 100644 --- a/v3/services/usersvc/internal/crd.go +++ b/v3/services/usersvc/internal/crd.go @@ -7,9 +7,13 @@ import ( "github.com/hobbyfarm/gargantua/v3/pkg/crd" ) -func GenerateUserCRD(caBundle string, reference crd.ServiceReference) []crder.CRD { +// UserCRDInstaller is a struct that can generate CRDs for users. +// It implements the CrdInstallerWithServiceReference interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type UserCRDInstaller struct{} + +func (ui UserCRDInstaller) GenerateCRDs(caBundle string, reference crd.ServiceReference) []crder.CRD { return []crder.CRD{ - hobbyfarmCRD(&v1.User{}, func(c *crder.CRD) { + crd.HobbyfarmCRD(&v1.User{}, func(c *crder.CRD) { c. IsNamespaced(true). AddVersion("v1", &v1.User{}, func(cv *crder.Version) { @@ -35,7 +39,3 @@ func GenerateUserCRD(caBundle string, reference crd.ServiceReference) []crder.CR }), } } - -func hobbyfarmCRD(obj interface{}, customize func(c *crder.CRD)) crder.CRD { - return *crder.NewCRD(obj, "hobbyfarm.io", customize) -} diff --git a/v3/services/usersvc/internal/grpc.go b/v3/services/usersvc/internal/grpc.go index fa0c4197..c24b6c01 100644 --- a/v3/services/usersvc/internal/grpc.go +++ b/v3/services/usersvc/internal/grpc.go @@ -9,19 +9,22 @@ import ( "time" "github.com/golang/glog" - hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" hfv2 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v2" hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv2 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v2" hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" listerv2 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v2" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" "github.com/hobbyfarm/gargantua/v3/pkg/util" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" "golang.org/x/crypto/bcrypt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - empty "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/emptypb" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/retry" ) @@ -31,14 +34,15 @@ const ( ) type GrpcUserServer struct { - userProto.UnimplementedUserSvcServer - hfClientSet hfClientset.Interface - userIndexer cache.Indexer - userLister listerv2.UserLister - ctx context.Context + userpb.UnimplementedUserSvcServer + userClient hfClientsetv2.UserInterface + userIndexer cache.Indexer + userLister listerv2.UserLister + userSynced cache.InformerSynced + sessionClient sessionpb.SessionSvcClient } -func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, ctx context.Context) (*GrpcUserServer, error) { +func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, sessionClient sessionpb.SessionSvcClient) (*GrpcUserServer, error) { inf := hfInformerFactory.Hobbyfarm().V2().Users().Informer() indexers := map[string]cache.IndexFunc{emailIndex: emailIndexer} err := inf.AddIndexers(indexers) @@ -47,10 +51,11 @@ func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfIn return nil, err } return &GrpcUserServer{ - hfClientSet: hfClientSet, - userIndexer: inf.GetIndexer(), - userLister: hfInformerFactory.Hobbyfarm().V2().Users().Lister(), - ctx: ctx, + userClient: hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()), + userIndexer: inf.GetIndexer(), + userLister: hfInformerFactory.Hobbyfarm().V2().Users().Lister(), + userSynced: inf.HasSynced, + sessionClient: sessionClient, }, nil } @@ -63,33 +68,25 @@ func emailIndexer(obj interface{}) ([]string, error) { return []string{strings.ToLower(user.Spec.Email)}, nil } -func (u *GrpcUserServer) CreateUser(c context.Context, cur *userProto.CreateUserRequest) (*userProto.UserId, error) { +func (u *GrpcUserServer) CreateUser(ctx context.Context, cur *userpb.CreateUserRequest) (*generalpb.ResourceId, error) { if len(cur.GetEmail()) == 0 || len(cur.GetPassword()) == 0 { - newErr := status.Newf( + return &generalpb.ResourceId{}, hferrors.GrpcError( codes.InvalidArgument, "error creating user, email or password field blank", + cur, ) - newErr, wde := newErr.WithDetails(cur) - if wde != nil { - return &userProto.UserId{}, wde - } - return &userProto.UserId{}, newErr.Err() } - _, err := u.GetUserByEmail(context.Background(), &userProto.GetUserByEmailRequest{Email: cur.GetEmail()}) + _, err := u.GetUserByEmail(context.Background(), &userpb.GetUserByEmailRequest{Email: cur.GetEmail()}) if err == nil { // the user was found, we should return info - newErr := status.Newf( + return &generalpb.ResourceId{}, hferrors.GrpcError( codes.AlreadyExists, "user %s already exists", + cur, cur.GetEmail(), ) - newErr, wde := newErr.WithDetails(cur) - if wde != nil { - return &userProto.UserId{}, wde - } - return &userProto.UserId{}, newErr.Err() } newUser := hfv2.User{} @@ -108,149 +105,107 @@ func (u *GrpcUserServer) CreateUser(c context.Context, cur *userProto.CreateUser passwordHash, err := bcrypt.GenerateFromPassword([]byte(cur.GetPassword()), bcrypt.DefaultCost) if err != nil { - newErr := status.Newf( + return &generalpb.ResourceId{}, hferrors.GrpcError( codes.Internal, "error while hashing password for email %s", + cur, cur.GetEmail(), ) - newErr, wde := newErr.WithDetails(cur) - if wde != nil { - return &userProto.UserId{}, wde - } - return &userProto.UserId{}, newErr.Err() } newUser.Spec.Password = string(passwordHash) newUser.Spec.LastLoginTimestamp = time.Now().Format(time.UnixDate) - _, err = u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).Create(u.ctx, &newUser, metav1.CreateOptions{}) + _, err = u.userClient.Create(ctx, &newUser, metav1.CreateOptions{}) if err != nil { - newErr := status.Newf( + return &generalpb.ResourceId{}, hferrors.GrpcError( codes.Internal, "error creating user", + cur, ) - newErr, wde := newErr.WithDetails(cur) - if wde != nil { - return &userProto.UserId{}, wde - } - return &userProto.UserId{}, newErr.Err() } - return &userProto.UserId{Id: id}, nil + return &generalpb.ResourceId{Id: id}, nil } -func (u *GrpcUserServer) getUser(id string) (*userProto.User, error) { - if len(id) == 0 { - return &userProto.User{}, fmt.Errorf("user id passed in was empty") - } - obj, err := u.userLister.Users(util.GetReleaseNamespace()).Get(id) +func (u *GrpcUserServer) GetUserById(ctx context.Context, req *generalpb.GetRequest) (*userpb.User, error) { + user, err := util.GenericHfGetter(ctx, req, u.userClient, u.userLister.Users(util.GetReleaseNamespace()), "user", u.userSynced()) if err != nil { - return &userProto.User{}, fmt.Errorf("error while retrieving User by id: %s with error: %v", id, err) + return &userpb.User{}, err } - return &userProto.User{ - Id: obj.Name, - Email: obj.Spec.Email, - Password: obj.Spec.Password, - AccessCodes: obj.Spec.AccessCodes, - Settings: obj.Spec.Settings, - LastLoginTimestamp: obj.Spec.LastLoginTimestamp, - RegisteredTimestamp: obj.GetCreationTimestamp().Time.Format(time.UnixDate), + glog.V(2).Infof("retrieved user %s", user.Name) + + return &userpb.User{ + Id: user.Name, + Uid: string(user.UID), + Email: user.Spec.Email, + Password: user.Spec.Password, + AccessCodes: user.Spec.AccessCodes, + Settings: user.Spec.Settings, + LastLoginTimestamp: user.Spec.LastLoginTimestamp, + RegisteredTimestamp: user.GetCreationTimestamp().Time.Format(time.UnixDate), }, nil } -func (u *GrpcUserServer) GetUserById(ctx context.Context, gur *userProto.UserId) (*userProto.User, error) { - if len(gur.GetId()) == 0 { - newErr := status.Newf( - codes.InvalidArgument, - "no id passed in", - ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() - } - - user, err := u.getUser(gur.GetId()) - - if err != nil { - glog.Errorf("error while retrieving user %v", err) - newErr := status.Newf( - codes.NotFound, - "no user %s found", - gur.GetId(), - ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde +func (u *GrpcUserServer) ListUser(ctx context.Context, listOptions *generalpb.ListOptions) (*userpb.ListUsersResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var users []hfv2.User + var err error + if !doLoadFromCache { + var userList *hfv2.UserList + userList, err = util.ListByHfClient(ctx, listOptions, u.userClient, "users") + if err == nil { + users = userList.Items } - return &userProto.User{}, newErr.Err() + } else { + users, err = util.ListByCache(listOptions, u.userLister, "users", u.userSynced()) } - glog.V(2).Infof("retrieved user %s", user.GetId()) - return user, nil -} - -func (u *GrpcUserServer) ListUser(ctx context.Context, empty *empty.Empty) (*userProto.ListUsersResponse, error) { - //users, err := u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).List(u.ctx, metav1.ListOptions{}) - users, err := u.userLister.Users(util.GetReleaseNamespace()).List(labels.Everything()) - if err != nil { - glog.Errorf("error while retrieving users %v", err) - newErr := status.Newf( - codes.Internal, - "no users found", - ) - return &userProto.ListUsersResponse{}, newErr.Err() + glog.Error(err) + return &userpb.ListUsersResponse{}, err } - preparedUsers := []*userProto.User{} // must be declared this way so as to JSON marshal into [] instead of null - for _, s := range users { - preparedUsers = append(preparedUsers, &userProto.User{ - Id: s.Name, - Email: s.Spec.Email, - Password: s.Spec.Password, - AccessCodes: s.Spec.AccessCodes, - Settings: s.Spec.Settings, - LastLoginTimestamp: s.Spec.LastLoginTimestamp, - RegisteredTimestamp: s.GetCreationTimestamp().Time.Format(time.UnixDate), + preparedUsers := []*userpb.User{} // must be declared this way so as to JSON marshal into [] instead of null + for _, user := range users { + preparedUsers = append(preparedUsers, &userpb.User{ + Id: user.Name, + Uid: string(user.UID), + Email: user.Spec.Email, + Password: user.Spec.Password, + AccessCodes: user.Spec.AccessCodes, + Settings: user.Spec.Settings, + LastLoginTimestamp: user.Spec.LastLoginTimestamp, + RegisteredTimestamp: user.GetCreationTimestamp().Time.Format(time.UnixDate), }) } glog.V(2).Infof("listed users") - return &userProto.ListUsersResponse{Users: preparedUsers}, nil + return &userpb.ListUsersResponse{Users: preparedUsers}, nil } -func (u *GrpcUserServer) UpdateUser(ctx context.Context, userRequest *userProto.User) (*userProto.User, error) { +func (u *GrpcUserServer) UpdateUser(ctx context.Context, userRequest *userpb.User) (*userpb.User, error) { id := userRequest.GetId() if id == "" { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.InvalidArgument, "no ID passed in", + userRequest, ) - newErr, wde := newErr.WithDetails(userRequest) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { user, err := u.userLister.Users(util.GetReleaseNamespace()).Get(id) if err != nil { - newErr := status.Newf( + glog.Error(err) + return hferrors.GrpcError( codes.Internal, "error while retrieving user %s", + userRequest, userRequest.GetId(), ) - newErr, wde := newErr.WithDetails(userRequest) - if wde != nil { - return wde - } - glog.Error(err) - return newErr.Err() } if userRequest.GetEmail() != "" { @@ -272,53 +227,41 @@ func (u *GrpcUserServer) UpdateUser(ctx context.Context, userRequest *userProto. user.Spec.Settings = userRequest.GetSettings() } - _, updateErr := u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).Update(u.ctx, user, metav1.UpdateOptions{}) + _, updateErr := u.userClient.Update(ctx, user, metav1.UpdateOptions{}) return updateErr }) if retryErr != nil { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.Internal, "error attempting to update", + userRequest, ) - newErr, wde := newErr.WithDetails(userRequest) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } return userRequest, nil } -func (u *GrpcUserServer) UpdateAccessCodes(ctx context.Context, updateAccessCodesRequest *userProto.UpdateAccessCodesRequest) (*userProto.User, error) { +func (u *GrpcUserServer) UpdateAccessCodes(ctx context.Context, updateAccessCodesRequest *userpb.UpdateAccessCodesRequest) (*userpb.User, error) { id := updateAccessCodesRequest.GetId() if id == "" { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.InvalidArgument, "no ID passed in", + updateAccessCodesRequest, ) - newErr, wde := newErr.WithDetails(updateAccessCodesRequest) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { user, err := u.userLister.Users(util.GetReleaseNamespace()).Get(id) if err != nil { - newErr := status.Newf( + glog.Error(err) + return hferrors.GrpcError( codes.Internal, "error while retrieving user %s", + updateAccessCodesRequest, updateAccessCodesRequest.GetId(), ) - newErr, wde := newErr.WithDetails(updateAccessCodesRequest) - if wde != nil { - return wde - } - glog.Error(err) - return newErr.Err() } if updateAccessCodesRequest.GetAccessCodes() != nil { @@ -327,38 +270,26 @@ func (u *GrpcUserServer) UpdateAccessCodes(ctx context.Context, updateAccessCode user.Spec.AccessCodes = make([]string, 0) } - _, updateErr := u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).Update(u.ctx, user, metav1.UpdateOptions{}) + _, updateErr := u.userClient.Update(ctx, user, metav1.UpdateOptions{}) return updateErr }) if retryErr != nil { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.Internal, "error attempting to update", + updateAccessCodesRequest, ) - newErr, wde := newErr.WithDetails(updateAccessCodesRequest) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } - return &userProto.User{}, nil + return &userpb.User{}, nil } -func (u *GrpcUserServer) SetLastLoginTimestamp(ctx context.Context, userId *userProto.UserId) (*empty.Empty, error) { +func (u *GrpcUserServer) SetLastLoginTimestamp(ctx context.Context, userId *generalpb.ResourceId) (*emptypb.Empty, error) { id := userId.GetId() if len(id) == 0 { - newErr := status.Newf( - codes.InvalidArgument, - "no id passed in", - ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(userId) } retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { @@ -379,7 +310,7 @@ func (u *GrpcUserServer) SetLastLoginTimestamp(ctx context.Context, userId *user user.Spec.LastLoginTimestamp = time.Now().Format(time.UnixDate) - _, updateErr := u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).Update(u.ctx, user, metav1.UpdateOptions{}) + _, updateErr := u.userClient.Update(ctx, user, metav1.UpdateOptions{}) return updateErr }) @@ -390,73 +321,57 @@ func (u *GrpcUserServer) SetLastLoginTimestamp(ctx context.Context, userId *user ) newErr, wde := newErr.WithDetails(userId) if wde != nil { - return &empty.Empty{}, wde + return &emptypb.Empty{}, wde } - return &empty.Empty{}, newErr.Err() + return &emptypb.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (u *GrpcUserServer) GetUserByEmail(c context.Context, gur *userProto.GetUserByEmailRequest) (*userProto.User, error) { +func (u *GrpcUserServer) GetUserByEmail(ctx context.Context, gur *userpb.GetUserByEmailRequest) (*userpb.User, error) { if len(gur.GetEmail()) == 0 { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.InvalidArgument, "email passed in was empty", + gur, ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } userMail := strings.ToLower(gur.GetEmail()) obj, err := u.userIndexer.ByIndex(emailIndex, userMail) if err != nil { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.Internal, "error while retrieving user by e-mail: %s with error: %v", - userMail, + gur, + gur.GetEmail(), err, ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } if len(obj) < 1 { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.NotFound, "user not found by email: %s", - userMail, + gur, + gur.GetEmail(), ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } user, ok := obj[0].(*hfv2.User) if !ok { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.Internal, "error while converting user found by email to object: %s", - userMail, + gur, + gur.GetEmail(), ) - newErr, wde := newErr.WithDetails(gur) - if wde != nil { - return &userProto.User{}, wde - } - return &userProto.User{}, newErr.Err() } - return &userProto.User{ + return &userpb.User{ Id: user.Name, Email: user.Spec.Email, Password: user.Spec.Password, @@ -465,111 +380,78 @@ func (u *GrpcUserServer) GetUserByEmail(c context.Context, gur *userProto.GetUse }, nil } -func (u *GrpcUserServer) DeleteUser(c context.Context, userId *userProto.UserId) (*empty.Empty, error) { +func (u *GrpcUserServer) DeleteUser(ctx context.Context, userId *generalpb.ResourceId) (*emptypb.Empty, error) { id := userId.GetId() - - if len(id) == 0 { - newErr := status.Newf( - codes.InvalidArgument, - "no id passed in", - ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() - } - - user, err := u.userLister.Users(util.GetReleaseNamespace()).Get(id) + user, err := util.GenericHfGetter( + ctx, &generalpb.GetRequest{Id: id}, + u.userClient, + u.userLister.Users(util.GetReleaseNamespace()), + "user", + u.userSynced(), + ) if err != nil { - newErr := status.Newf( - codes.Internal, - "error fetching user %s from server", - userId.GetId(), - ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - glog.Errorf("error fetching user %s from server during delete request: %s", id, err) - return &empty.Empty{}, newErr.Err() + return &emptypb.Empty{}, err } - // get a list of sessions for the user - sessionList, err := u.hfClientSet.HobbyfarmV1().Sessions(util.GetReleaseNamespace()).List(u.ctx, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", util.UserLabel, id), + sessionList, err := u.sessionClient.ListSession(ctx, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.UserLabel, id), }) if err != nil { - newErr := status.Newf( + glog.Errorf("error retrieving session list for user %s during delete: %s", id, err) + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "error retrieving session list for user %s", + userId, userId.GetId(), ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - glog.Errorf("error retrieving session list for user %s during delete: %s", id, err) - return &empty.Empty{}, newErr.Err() } - if len(sessionList.Items) > 0 { + if len(sessionList.Sessions) > 0 { // there are sessions present but they may be expired. let's check - for _, v := range sessionList.Items { - if !v.Status.Finished { - newErr := status.Newf( + for _, s := range sessionList.Sessions { + if !s.Status.Finished { + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "cannot delete user, existing sessions found", + userId, ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - return &empty.Empty{}, newErr.Err() } } // getting here means there are sessions present but they are not active // let's delete them for cleanliness' sake - if ok, err := u.deleteSessions(sessionList.Items); !ok { - newErr := status.Newf( + if ok, err := u.deleteSessions(ctx, sessionList.Sessions); !ok { + glog.Errorf("error deleting old sessions for user %s: %s", id, err) + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "cannot delete user, error removing old sessions", + userId, ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - glog.Errorf("error deleting old sessions for user %s: %s", id, err) - return &empty.Empty{}, newErr.Err() } } // at this point we have either delete all old sessions, or there were no sessions to begin with // so we should be safe to delete the user - deleteErr := u.hfClientSet.HobbyfarmV2().Users(util.GetReleaseNamespace()).Delete(u.ctx, user.Name, metav1.DeleteOptions{}) + deleteErr := u.userClient.Delete(ctx, user.Name, metav1.DeleteOptions{}) if deleteErr != nil { - newErr := status.Newf( + glog.Errorf("error deleting user %s: %s", id, deleteErr) + return &emptypb.Empty{}, hferrors.GrpcError( codes.Internal, "error deleting user %s", + userId, userId.GetId(), ) - newErr, wde := newErr.WithDetails(userId) - if wde != nil { - return &empty.Empty{}, wde - } - glog.Errorf("error deleting user %s: %s", id, deleteErr) - return &empty.Empty{}, newErr.Err() } - return &empty.Empty{}, nil + return &emptypb.Empty{}, nil } -func (u *GrpcUserServer) deleteSessions(sessions []hfv1.Session) (bool, error) { - for _, v := range sessions { +func (u *GrpcUserServer) deleteSessions(ctx context.Context, sessions []*sessionpb.Session) (bool, error) { + for _, s := range sessions { retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - err := u.hfClientSet.HobbyfarmV1().Sessions(util.GetReleaseNamespace()).Delete(u.ctx, v.Name, metav1.DeleteOptions{}) + // @TODO: Use gRPC SessionClient here! + _, err := u.sessionClient.DeleteSession(ctx, &generalpb.ResourceId{Id: s.Id}) return err }) diff --git a/v3/services/usersvc/internal/server.go b/v3/services/usersvc/internal/server.go index b6fc0467..3de6fc65 100644 --- a/v3/services/usersvc/internal/server.go +++ b/v3/services/usersvc/internal/server.go @@ -3,25 +3,25 @@ package userservice import ( "github.com/golang/glog" "github.com/gorilla/mux" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - "github.com/hobbyfarm/gargantua/v3/protos/rbac" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" ) type UserServer struct { - authnClient authn.AuthNClient - authrClient authr.AuthRClient - rbacClient rbac.RbacSvcClient + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + rbacClient rbacpb.RbacSvcClient internalUserServer *GrpcUserServer } -func NewUserServer(authnClient authn.AuthNClient, authrClient authr.AuthRClient, rbacClient rbac.RbacSvcClient, internalUserServer *GrpcUserServer) (UserServer, error) { - u := UserServer{} - u.authnClient = authnClient - u.authrClient = authrClient - u.rbacClient = rbacClient - u.internalUserServer = internalUserServer - return u, nil +func NewUserServer(authnClient authnpb.AuthNClient, authrClient authrpb.AuthRClient, rbacClient rbacpb.RbacSvcClient, internalUserServer *GrpcUserServer) UserServer { + return UserServer{ + authnClient: authnClient, + authrClient: authrClient, + rbacClient: rbacClient, + internalUserServer: internalUserServer, + } } func (u UserServer) SetupRoutes(r *mux.Router) { diff --git a/v3/services/usersvc/internal/userservice.go b/v3/services/usersvc/internal/userservice.go index eda3e0da..61958497 100644 --- a/v3/services/usersvc/internal/userservice.go +++ b/v3/services/usersvc/internal/userservice.go @@ -6,13 +6,14 @@ import ( "github.com/golang/glog" "github.com/gorilla/mux" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" "github.com/hobbyfarm/gargantua/v3/pkg/rbac" "github.com/hobbyfarm/gargantua/v3/pkg/util" - rbacProto "github.com/hobbyfarm/gargantua/v3/protos/rbac" - userProto "github.com/hobbyfarm/gargantua/v3/protos/user" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" ) const ( @@ -55,19 +56,16 @@ func (u UserServer) GetFunc(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] - user, err := u.internalUserServer.GetUserById(r.Context(), &userProto.UserId{Id: id}) + user, err := u.internalUserServer.GetUserById(r.Context(), &generalpb.GetRequest{Id: id}) if err != nil { - if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*userProto.UserId) - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") - return - } - glog.Errorf("error while retrieving user %s: %s", details.Id, s.Message()) - util.ReturnHTTPMessage(w, r, 500, "error", "no user found") + s := status.Convert(err) + details, _ := hferrors.ExtractDetail[*generalpb.GetRequest](s) + if s.Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, 500, "error", "no id passed in") + return } - glog.Errorf("error while retrieving user: %s", err) + glog.Errorf("error while retrieving user %s: %s", details.Id, s.Message()) util.ReturnHTTPMessage(w, r, 500, "error", "no user found") } @@ -109,7 +107,7 @@ func (u UserServer) ListFunc(w http.ResponseWriter, r *http.Request) { return } - users, err := u.internalUserServer.ListUser(r.Context(), &emptypb.Empty{}) + users, err := u.internalUserServer.ListUser(r.Context(), &generalpb.ListOptions{}) if err != nil { glog.Errorf("error while retrieving users %v", err) @@ -171,19 +169,16 @@ func (u UserServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { } } - _, err = u.internalUserServer.UpdateUser(r.Context(), &userProto.User{Id: id, Email: email, Password: password, AccessCodes: acUnmarshaled}) + _, err = u.internalUserServer.UpdateUser(r.Context(), &userpb.User{Id: id, Email: email, Password: password, AccessCodes: acUnmarshaled}) if err != nil { - if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*userProto.User) - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") - return - } - glog.Errorf("error while updating user %s: %s", details.Id, s.Message()) - util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") + s := status.Convert(err) + details, _ := hferrors.ExtractDetail[*userpb.User](s) + if s.Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no ID passed in") + return } - glog.Errorf("error while updating user: %s", err) + glog.Errorf("error while updating user %s: %s", details.Id, s.Message()) util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update") } @@ -217,19 +212,16 @@ func (u UserServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { return } - _, err = u.internalUserServer.DeleteUser(r.Context(), &userProto.UserId{Id: id}) + _, err = u.internalUserServer.DeleteUser(r.Context(), &generalpb.ResourceId{Id: id}) if err != nil { - if s, ok := status.FromError(err); ok { - details := s.Details()[0].(*userProto.UserId) - if s.Code() == codes.InvalidArgument { - util.ReturnHTTPMessage(w, r, 400, "error", "no id passed in") - return - } - glog.Errorf("error deleting user %s: %s", details.Id, s.Message()) - util.ReturnHTTPMessage(w, r, 500, "error", s.Message()) + s := status.Convert(err) + details, _ := hferrors.ExtractDetail[*generalpb.ResourceId](s) + if s.Code() == codes.InvalidArgument { + util.ReturnHTTPMessage(w, r, 400, "error", "no id passed in") + return } - glog.Errorf("error deleting user: %s", err) + glog.Errorf("error deleting user %s: %s", details.Id, s.Message()) util.ReturnHTTPMessage(w, r, 500, "error", "error deleting user") } @@ -254,7 +246,7 @@ func (u UserServer) ListRoleBindingsForUser(w http.ResponseWriter, r *http.Reque user := vars["user"] - bindings, err := u.rbacClient.GetHobbyfarmRoleBindings(r.Context(), &userProto.UserId{ + bindings, err := u.rbacClient.GetHobbyfarmRoleBindings(r.Context(), &generalpb.ResourceId{ Id: user, }) @@ -279,7 +271,7 @@ func (u UserServer) ListRoleBindingsForUser(w http.ResponseWriter, r *http.Reque util.ReturnHTTPContent(w, r, http.StatusOK, "content", data) } -func (s UserServer) prepareRoleBinding(roleBinding *rbacProto.RoleBinding) PreparedRoleBinding { +func (s UserServer) prepareRoleBinding(roleBinding *rbacpb.RoleBinding) PreparedRoleBinding { prb := PreparedRoleBinding{ Name: roleBinding.GetName(), Role: roleBinding.GetRole(), diff --git a/v3/services/usersvc/main.go b/v3/services/usersvc/main.go index 409af263..5237989a 100644 --- a/v3/services/usersvc/main.go +++ b/v3/services/usersvc/main.go @@ -1,12 +1,9 @@ package main import ( - "context" - "os" "sync" "time" - "github.com/ebauman/crder" "github.com/hobbyfarm/gargantua/v3/pkg/crd" "github.com/hobbyfarm/gargantua/v3/pkg/microservices" "github.com/hobbyfarm/gargantua/v3/pkg/signals" @@ -16,10 +13,11 @@ import ( userservice "github.com/hobbyfarm/gargantua/services/usersvc/v3/internal" hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" - "github.com/hobbyfarm/gargantua/v3/protos/authn" - "github.com/hobbyfarm/gargantua/v3/protos/authr" - "github.com/hobbyfarm/gargantua/v3/protos/rbac" - "github.com/hobbyfarm/gargantua/v3/protos/user" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + userpb "github.com/hobbyfarm/gargantua/v3/protos/user" ) var ( @@ -36,63 +34,46 @@ func main() { namespace := util.GetReleaseNamespace() hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) - ca, err := os.ReadFile(serviceConfig.WebhookTLSCA) - if err != nil { - glog.Fatalf("error reading ca certificate: %s", err.Error()) - } - - crds := userservice.GenerateUserCRD(string(ca), crd.ServiceReference{ - Namespace: util.GetReleaseNamespace(), - Name: "hobbyfarm-webhook", - }) - - glog.Info("installing/updating user CRD") - err = crder.InstallUpdateCRDs(cfg, crds...) - if err != nil { - glog.Fatalf("failed installing/updating user crd: %s", err.Error()) - } - glog.Info("finished installing/updating user CRD") + crd.InstallCrdsWithServiceReference(userservice.UserCRDInstaller{}, cfg, "user", serviceConfig.WebhookTLSCA) services := []microservices.MicroService{ microservices.Rbac, microservices.AuthN, microservices.AuthR, + microservices.Session, } connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) for _, conn := range connections { defer conn.Close() } - rbacClient := rbac.NewRbacSvcClient(connections[microservices.Rbac]) - authnClient := authn.NewAuthNClient(connections[microservices.AuthN]) - authrClient := authr.NewAuthRClient(connections[microservices.AuthR]) + rbacClient := rbacpb.NewRbacSvcClient(connections[microservices.Rbac]) + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session]) gs := microservices.CreateGRPCServer(serviceConfig.ServerCert) - ctx := context.Background() - us, err := userservice.NewGrpcUserServer(hfClient, hfInformerFactory, ctx) + us, err := userservice.NewGrpcUserServer(hfClient, hfInformerFactory, sessionClient) if err != nil { glog.Fatalf("starting grpc user server failed: %v", err) } - user.RegisterUserSvcServer(gs, us) + userpb.RegisterUserSvcServer(gs, us) var wg sync.WaitGroup - + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates wg.Add(1) + go func() { defer wg.Done() microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) }() - wg.Add(1) go func() { defer wg.Done() - userServer, err := userservice.NewUserServer(authnClient, authrClient, rbacClient, us) - if err != nil { - glog.Fatalf("Error creating userserver: %v", err) - } + userServer := userservice.NewUserServer(authnClient, authrClient, rbacClient, us) microservices.StartAPIServer(userServer) }() diff --git a/v3/services/vmclaimsvc/Dockerfile b/v3/services/vmclaimsvc/Dockerfile new file mode 100644 index 00000000..b27420c7 --- /dev/null +++ b/v3/services/vmclaimsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/vmclaimsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/vmclaimsvc/go.mod b/v3/services/vmclaimsvc/go.mod new file mode 100644 index 00000000..57c94572 --- /dev/null +++ b/v3/services/vmclaimsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/vmclaimsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/vmclaimsvc/go.sum b/v3/services/vmclaimsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/vmclaimsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/vmclaimsvc/internal/controller.go b/v3/services/vmclaimsvc/internal/controller.go new file mode 100644 index 00000000..30e79333 --- /dev/null +++ b/v3/services/vmclaimsvc/internal/controller.go @@ -0,0 +1,652 @@ +package vmclaimservice + +import ( + "context" + "fmt" + "math/rand" + "time" + + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + controllers "github.com/hobbyfarm/gargantua/v3/pkg/microservices/controller" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes" +) + +const ( + StaticBindAttemptThreshold int = 3 + DynamicBindAttemptThreshold int = 2 +) + +type VMClaimController struct { + controllers.DelayingWorkqueueController + controllers.Reconciler + internalVmClaimServer *GrpcVMClaimServer + accessCodeClient accesscodepb.AccessCodeSvcClient + sessionClient sessionpb.SessionSvcClient + progressClient progresspb.ProgressSvcClient + environmentClient environmentpb.EnvironmentSvcClient + dbConfigClient dbconfigpb.DynamicBindConfigSvcClient + vmClient vmpb.VMSvcClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient + eventClient scheduledeventpb.ScheduledEventSvcClient +} + +func NewVMClaimController( + kubeClient *kubernetes.Clientset, + internalVmClaimServer *GrpcVMClaimServer, + hfInformerFactory hfInformers.SharedInformerFactory, + acClient accesscodepb.AccessCodeSvcClient, + dbConfigClient dbconfigpb.DynamicBindConfigSvcClient, + environmentClient environmentpb.EnvironmentSvcClient, + eventClient scheduledeventpb.ScheduledEventSvcClient, + progressClient progresspb.ProgressSvcClient, + sessionClient sessionpb.SessionSvcClient, + vmClient vmpb.VMSvcClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + ctx context.Context, +) (*VMClaimController, error) { + vmClaimInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer() + delayingWorkqueueController := *controllers.NewDelayingWorkqueueController( + ctx, + vmClaimInformer, + kubeClient, + "vmclaim-controller", + time.Minute*30, + internalVmClaimServer.vmClaimWorkqueue, + ) + + vmClaimController := &VMClaimController{ + DelayingWorkqueueController: delayingWorkqueueController, + internalVmClaimServer: internalVmClaimServer, + accessCodeClient: acClient, + dbConfigClient: dbConfigClient, + environmentClient: environmentClient, + eventClient: eventClient, + progressClient: progressClient, + sessionClient: sessionClient, + vmClient: vmClient, + vmTemplateClient: vmTemplateClient, + } + vmClaimController.SetReconciler(vmClaimController) + vmClaimController.SetWorkScheduler(vmClaimController) + + return vmClaimController, nil +} + +func (v *VMClaimController) Reconcile(objName string) error { + glog.V(8).Infof("reconciling vmclaim %s inside vm claim controller", objName) + // fetch vmClaim + vmClaim, err := v.internalVmClaimServer.GetVMClaim(v.Context, &generalpb.GetRequest{Id: objName}) + if err != nil { + if hferrors.IsGrpcNotFound(err) { + glog.Infof("vmClaim %s not found on queue.. ignoring", objName) + return nil + } else { + return fmt.Errorf("error while retrieving vmclaim %s from queue with err %v", objName, err) + } + } + + // ignore vm objects which are being deleted + if vmClaim.GetDeletionTimestamp() == nil { + return v.processVMClaim(vmClaim) + } + return nil +} + +func (v *VMClaimController) updateVMClaimStatus(bound bool, ready bool, vmc *vmclaimpb.VMClaim) error { + _, err := v.internalVmClaimServer.UpdateVMClaimStatus(v.Context, &vmclaimpb.UpdateVMClaimStatusRequest{ + Id: vmc.GetId(), + Bound: wrapperspb.Bool(bound), + Ready: wrapperspb.Bool(ready), + }) + + return err +} + +func (v *VMClaimController) processVMClaim(vmc *vmclaimpb.VMClaim) (err error) { + if vmc.Status.Tainted { + glog.Infof("vmclaim %s is tainted.. cleaning it up", vmc.GetId()) + _, err := v.internalVmClaimServer.DeleteVMClaim(v.Context, &generalpb.ResourceId{Id: vmc.GetId()}) + return err + } + + if !vmc.Status.Bound && !vmc.Status.Ready { + // submit VM requests // + // update status + if vmc.Status.BindMode == "dynamic" { + err = v.submitVirtualMachines(vmc) + if err != nil { + // VirtualMachines could not be submitted. Delete Session + glog.Errorf("error processing vmc %s, taint session: %v", vmc.GetId(), err) + return v.taintSession(vmc.Labels[hflabels.SessionLabel]) + } + } else if vmc.Status.BindMode == "static" { + err = v.findVirtualMachines(vmc) + if err != nil { + // VirtualMachines could not be bound. Delete Session + glog.Errorf("error processing vmc %s, taint session: %v", vmc.GetId(), err) + return v.taintSession(vmc.Labels[hflabels.SessionLabel]) + } + } else { + glog.Errorf("vmc bind mode needs to be either dynamic or static.. ignoring this object %s", vmc.GetId()) + return nil + } + + return v.updateVMClaimStatus(true, false, vmc) + } + + if vmc.Status.Bound && !vmc.Status.Ready { + // reconcile triggered by VM being ready + // lets check the VM's + ready, err := v.checkVMStatus(vmc) + if err != nil { + glog.Errorf("error checking vmStatus for vmc: %s %v", vmc.GetId(), err) + return err + } + // update status + glog.V(4).Infof("vm's have been requested for vmclaim: %s", vmc.GetId()) + return v.updateVMClaimStatus(true, ready, vmc) + } + + if vmc.Status.Bound && vmc.Status.Ready { + // nothing else needs to be done.. ignore and move along + glog.V(4).Infof("vmclaim %s is ready", vmc.GetId()) + } + + return nil +} + +func (v *VMClaimController) taintSession(session string) error { + _, err := v.sessionClient.UpdateSessionStatus(v.Context, &sessionpb.UpdateSessionStatusRequest{ + Id: session, + ExpirationTime: time.Now().Format(time.UnixDate), + Active: wrapperspb.Bool(false), + }) + if err != nil { + return err + } + + // Remove outstanding Progresses as there was an error with this session + _, err = v.progressClient.DeleteCollectionProgress(v.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s,finished=false", hflabels.SessionLabel, session), + }) + + return err +} + +type VMEnvironment struct { + Environment *environmentpb.Environment + DynamicBindConfiguration *dbconfigpb.DynamicBindConfig +} + +func (v *VMClaimController) submitVirtualMachines(vmc *vmclaimpb.VMClaim) (err error) { + accessCode, ok := vmc.Labels[hflabels.AccessCodeLabel] + if !ok { + glog.Error("accessCode label not set on vmc, aborting") + return fmt.Errorf("accessCode label not set on vmc, aborting") + } + + environments, seName, dbcList, err := v.findEnvironmentsForVM(accessCode, vmc) + if err != nil { + glog.Errorf("error fetching environment for access code %s %v", accessCode, err) + return err + } + + // Calculate required VMs per template + requiredTemplateCount := make(map[string]int) + for _, vmDetails := range vmc.GetVms() { + if count, found := requiredTemplateCount[vmDetails.Template]; found { + requiredTemplateCount[vmDetails.Template] = count + 1 + } else { + requiredTemplateCount[vmDetails.Template] = 1 + } + } + + environmentMap := make(map[string]VMEnvironment) // Maps node to the environment it should use + bestDBC, err := v.findBestDBCForVMs(dbcList, requiredTemplateCount, vmc.Labels[hflabels.ScheduledEventLabel]) // Try to find if one environment can provision all VMs + + if err != nil { + // We can not provision all VirtualMachines in one environment. Figure out which environments we want to use + + reservedCapacity := make(map[string]map[string]int) // EnvironmentID -> TemplateID -> Count + // Initialize reservedCapacity with 0 for all environments + associated templates + for _, environment := range environments { + reserved := make(map[string]int) + for template := range environment.GetTemplateMapping() { + reserved[template] = 0 + } + reservedCapacity[environment.GetId()] = reserved + } + for vmName, vmDetails := range vmc.GetVms() { + env, dbc, err := v.findSuitableEnvironmentForVMTemplate(environments, dbcList, vmDetails.Template, reservedCapacity, vmc.Labels[hflabels.ScheduledEventLabel]) + if err != nil { + glog.Errorf("no suitable environment for %s (%s): %v", vmName, vmDetails.GetTemplate(), err) + return err + } + environmentMap[vmName] = VMEnvironment{env, dbc} + reservedCapacity[env.GetId()][vmDetails.GetTemplate()] += 1 + } + } else { + // One DBC for them all + enviroment := &environmentpb.Environment{} + for _, e := range environments { + if e.GetId() == bestDBC.GetEnvironment() { + enviroment = e + break + } + } + for vmName := range vmc.GetVms() { + environmentMap[vmName] = VMEnvironment{enviroment, bestDBC} + } + } + + vmMap := make(map[string]*vmclaimpb.VMClaimVM) + for vmName, vmDetails := range vmc.GetVms() { + genName := fmt.Sprintf("%s-%08x", vmc.GetBaseName(), rand.Uint32()) + environment := environmentMap[vmName].Environment + dbc := environmentMap[vmName].DynamicBindConfiguration + vm := &vmpb.CreateVMRequest{ + Id: genName, + VmTemplateId: vmDetails.Template, + Protocol: "ssh", + SecretName: "", + VmClaimId: vmc.GetId(), + VmClaimUid: vmc.GetUid(), + User: vmc.GetUserId(), + Provision: true, + Labels: map[string]string{ + "dynamic": "true", + "vmc": vmc.GetId(), + hflabels.EnvironmentLabel: environment.GetId(), + "bound": "true", + "ready": "false", + hflabels.VirtualMachineTemplate: vmDetails.Template, + hflabels.ScheduledEventLabel: seName, + "restrictedbind": fmt.Sprintf("%t", dbc.GetRestrictedBind()), + }, + } + // used to later repopulate the info back // + vmMap[vmName] = &vmclaimpb.VMClaimVM{ + Template: vmDetails.Template, + VmId: genName, + } + + vmt, err := v.vmTemplateClient.GetVMTemplate(v.Context, &generalpb.GetRequest{Id: vmDetails.Template, LoadFromCache: true}) + if err != nil { + glog.Errorf("error getting vmt %v", err) + return err + } + + config := util.GetVMConfig(environment, vmt) + + protocol, exists := config["protocol"] + if exists { + vm.Protocol = protocol + } + + sshUser, exists := config["ssh_username"] + if exists { + vm.SshUsername = sshUser + } + + // extra label to indicate external provisioning so tfpcontroller ignores this request // + if provisionMethod, ok := environment.Annotations["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { + vm.Labels["hobbyfarm.io/provisioner"] = provisionMethod + vm.Provision = false + } + + if dbc.RestrictedBind { + vm.Labels["restrictedbindvalue"] = dbc.RestrictedBindValue + } + + _, err = v.vmClient.CreateVM(v.Context, vm) + if err != nil { + return err + } + + _, err = v.vmClient.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: genName, + Status: string(hfv1.VmStatusRFP), + Allocated: wrapperspb.Bool(true), + Tainted: wrapperspb.Bool(false), + WsEndpoint: environment.GetWsEndpoint(), + EnvironmentId: environment.GetId(), + PublicIp: wrapperspb.String(""), + PrivateIp: wrapperspb.String(""), + }) + if err != nil { + return err + } + } + + _, err = v.internalVmClaimServer.UpdateVMClaim(v.Context, &vmclaimpb.UpdateVMClaimRequest{ + Id: vmc.GetId(), + Vmset: vmMap, + }) + if err != nil { + return err + } + + return nil +} + +// Based on the given VirtualMachineClaim and ScheduledEvent find all suitable Environments (e.g. environment provides required VMTeplate & ScheduledEvents allows this environment and VMTemplate configuration etc.) +func (v *VMClaimController) findEnvironmentsForVM(accessCode string, vmc *vmclaimpb.VMClaim) (environments []*environmentpb.Environment, seName string, dbc []*dbconfigpb.DynamicBindConfig, err error) { + seName, _, err = v.findScheduledEvent(accessCode) + if err != nil { + return environments, seName, dbc, err + } + + dbcList, err := v.dbConfigClient.ListDynamicBindConfig(v.Context, &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, seName), + }) + + if err != nil { + glog.Errorf("error listing dbc %v", err) + return environments, seName, dbc, err + } + + for _, dbc := range dbcList.GetDbConfig() { + env, err := v.environmentClient.GetEnvironment(v.Context, &generalpb.GetRequest{Id: dbc.GetEnvironment()}) + if err != nil { + glog.Errorf("error fetching environment: %s", hferrors.GetErrorMessage(err)) + return environments, seName, dbcList.GetDbConfig(), err + } + environments = append(environments, env) + } + + if len(dbcList.GetDbConfig()) < 1 { + return environments, seName, dbc, fmt.Errorf("incorrect number of dbc matching sessionName found") + } + + return environments, seName, dbcList.GetDbConfig(), err +} + +// Can one DBC provide all VMs when considering the limits? Return the DBC if there exists one +func (v *VMClaimController) findBestDBCForVMs(dbcList []*dbconfigpb.DynamicBindConfig, requiredTemplateCount map[string]int, scheduledEvent string) (*dbconfigpb.DynamicBindConfig, error) { + // Try to find best possible environment / DBC = All required VMs can be provisioned here + for _, dbc := range dbcList { + satisfiedDBC := true + env, err := v.environmentClient.GetEnvironment(v.Context, &generalpb.GetRequest{Id: dbc.Environment}) + if err != nil { + return &dbconfigpb.DynamicBindConfig{}, fmt.Errorf("error fetching environment") + } + for requiredTemplate, requiredCount := range requiredTemplateCount { + dbcCapacity, foundDBC := dbc.BurstCountCapacity[requiredTemplate] + envCapacity, foundEnv := env.CountCapacity[requiredTemplate] + if foundDBC && foundEnv { + // Does the DBC satisfy this amount? + count, err := util.CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(v.Context, v.vmClient, requiredTemplate, dbc.Environment, scheduledEvent) + if err != nil { + satisfiedDBC = false + break + } + if requiredCount >= (int(dbcCapacity) - count) { + satisfiedDBC = false + break + } + + // Does the environment satisfy this amount? + count, err = util.CountMachinesPerTemplateAndEnvironment(v.Context, v.vmClient, requiredTemplate, dbc.Environment) + if err != nil { + satisfiedDBC = false + break + } + if requiredCount >= (int(envCapacity) - count) { + satisfiedDBC = false + break + } + + } else { + satisfiedDBC = false + break + } + } + + if satisfiedDBC { + // This DBC works for all templates and has the required Counts available! + glog.V(4).Infof("found best environment suitable for all VMs: %s", dbc.GetEnvironment()) + return dbc, nil + } + } + return &dbconfigpb.DynamicBindConfig{}, fmt.Errorf("there is no best environment") +} + +func (v *VMClaimController) findSuitableEnvironmentForVMTemplate(environments []*environmentpb.Environment, dbcList []*dbconfigpb.DynamicBindConfig, template string, reservedCapacity map[string]map[string]int, scheduledEvent string) (*environmentpb.Environment, *dbconfigpb.DynamicBindConfig, error) { + for _, environment := range environments { + countEnv, err := util.CountMachinesPerTemplateAndEnvironment(v.Context, v.vmClient, template, environment.GetId()) + if err != nil { + continue + } + // We have also reserved capacity for other VMs + countEnv += reservedCapacity[environment.GetId()][template] + + if countEnv >= int(environment.GetCountCapacity()[template]) { + // Environment is at limit + continue + } + + countDBC, err := util.CountMachinesPerTemplateAndEnvironmentAndScheduledEvent(v.Context, v.vmClient, template, environment.GetId(), scheduledEvent) + if err != nil { + continue + } + // We have also reserved capacity for other VMs + countDBC += reservedCapacity[environment.GetId()][template] + + // found environment that satisfies capacity for this template + for _, dbc := range dbcList { + if dbc.GetEnvironment() == environment.GetId() { + if capacity, found := dbc.GetBurstCountCapacity()[template]; found { + if countDBC < int(capacity) { + // Capacity also satisfied for environment + scheduledEvent via DBC + return environment, dbc, nil + } + } + break + } + } + + } + + return &environmentpb.Environment{}, &dbconfigpb.DynamicBindConfig{}, fmt.Errorf("no suitable environment found. capacity reached") +} + +func (v *VMClaimController) checkVMStatus(vmc *vmclaimpb.VMClaim) (ready bool, err error) { + ready = true + for _, vmTemplate := range vmc.Vms { + vm, err := v.vmClient.GetVM(v.Context, &generalpb.GetRequest{Id: vmTemplate.GetVmId()}) + if err != nil { + return ready, err + } + if vm.Status != nil && vm.Status.Status == string(hfv1.VmStatusRunning) { + ready = ready && true + } else { + ready = ready && false + } + } + + return ready, err +} + +func (v *VMClaimController) findScheduledEvent(accessCode string) (schedEvent string, environments map[string]*scheduledeventpb.VMTemplateCountMap, err error) { + ac, err := v.accessCodeClient.GetAccessCodeWithOTACs(v.Context, &generalpb.ResourceId{Id: accessCode}) + if err != nil { + return schedEvent, environments, err + } + + se, err := v.eventClient.GetScheduledEvent(v.Context, &generalpb.GetRequest{Id: ac.Labels[hflabels.ScheduledEventLabel]}) + + if err != nil { + return schedEvent, environments, err + } + + schedEvent = se.GetId() + environments = se.GetRequiredVms() + return schedEvent, environments, nil +} + +func (v *VMClaimController) findVirtualMachines(vmc *vmclaimpb.VMClaim) (err error) { + accessCode, ok := vmc.Labels[hflabels.AccessCodeLabel] + if !ok { + glog.Error("accessCode label not set on vmc, aborting") + return fmt.Errorf("accessCode label not set on vmc, aborting") + } + _, environments, err := v.findScheduledEvent(accessCode) + + if err != nil { + glog.Error("error finding scheduledevent during static bind") + return err + } + + vmMap := make(map[string]*vmclaimpb.VMClaimVM) + for name, vmStruct := range vmc.GetVms() { + if vmStruct.GetVmId() == "" { + glog.Info("assigning a vm") + vmID, err := v.assignNextFreeVM(vmc.GetId(), vmc.GetUserId(), environments, vmStruct.Template, vmc.RestrictedBind, vmc.RestrictedBindValue) + if err != nil { + // If we run into any issue assigning a VM we need to unassign the previously assigned VMs + for _, vm := range vmMap { + v.unassignVM(vm.GetVmId()) + } + return err + } + vmMap[name] = &vmclaimpb.VMClaimVM{ + Template: vmStruct.Template, + VmId: vmID, + } + } + } + _, err = v.internalVmClaimServer.UpdateVMClaim(v.Context, &vmclaimpb.UpdateVMClaimRequest{ + Id: vmc.GetId(), + Vmset: vmMap, + }) + if err != nil { + return err + } + + return nil +} + +func (v *VMClaimController) assignVM(vmClaimId string, user string, vmId string) error { + _, err := v.vmClient.UpdateVM(v.Context, &vmpb.UpdateVMRequest{ + Id: vmId, + Bound: "true", + VmClaimId: wrapperspb.String(vmClaimId), + User: wrapperspb.String(user), + }) + if err != nil { + return err + } + _, err = v.vmClient.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: vmId, + Allocated: wrapperspb.Bool(true), + }) + if err != nil { + return err + } + + glog.V(4).Infof("updated result for virtual machine") + return nil +} + +func (v *VMClaimController) unassignVM(vmId string) (string, error) { + _, err := v.vmClient.UpdateVM(v.Context, &vmpb.UpdateVMRequest{ + Id: vmId, + Bound: "false", + VmClaimId: wrapperspb.String(""), + User: wrapperspb.String(""), + }) + if err != nil { + return "", err + } + _, err = v.vmClient.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: vmId, + Allocated: wrapperspb.Bool(false), + }) + if err != nil { + return "", err + } + + return vmId, nil +} + +func (v *VMClaimController) assignNextFreeVM(vmClaimId string, user string, environments map[string]*scheduledeventpb.VMTemplateCountMap, template string, restrictedBind bool, restrictedBindValue string) (string, error) { + vmLabels := labels.Set{ + "bound": "false", + hflabels.VirtualMachineTemplate: template, + } + + if restrictedBind { + vmLabels["restrictedbind"] = "true" + vmLabels["restrictedbindvalue"] = restrictedBindValue + } else { + vmLabels["restrictedbind"] = "false" + } + + vmList, err := v.vmClient.ListVM(v.Context, &generalpb.ListOptions{LabelSelector: vmLabels.AsSelector().String(), LoadFromCache: true}) + vms := vmList.GetVms() + glog.V(4).Infof("found %d vm's matching this requirement", len(vms)) + if err != nil { + return "", fmt.Errorf("error while listing all vms %v", err) + } + + if len(vms) == 0 { + return "", fmt.Errorf("all static VMs are in use, no static VMs matching template: %s", template) + } + + assigned := false + vmId := "" + for _, vm := range vms { + // Check for Supported environment + if vmts, found := environments[vm.Labels[hflabels.EnvironmentLabel]]; found { + // This virtualmachine is one of the supported environments + if _, foundVMT := vmts.GetVmTemplateCounts()[vm.VmTemplateId]; !foundVMT { + // ... but this environment does not support this virtualmachinetemplate + continue + } + } else { + // This virtualmachine is in a non supported environment + continue + } + if !vm.Status.Allocated && !vm.Status.Tainted { + // we can assign this vm + assigned = true + vmId = vm.GetId() + + // Prefer running machines + if vm.Status.Status == string(hfv1.VmStatusRunning) { + break + } + } + } + + if assigned { + err = v.assignVM(vmClaimId, user, vmId) + + if err != nil { + return "", err + } + + return vmId, nil + } + + return vmId, fmt.Errorf("unknown error while assigning next free vm") + +} diff --git a/v3/services/vmclaimsvc/internal/crd.go b/v3/services/vmclaimsvc/internal/crd.go new file mode 100644 index 00000000..79b5db17 --- /dev/null +++ b/v3/services/vmclaimsvc/internal/crd.go @@ -0,0 +1,27 @@ +package vmclaimservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// VMClaimCRDInstaller is a struct that can generate CRDs for virtual machine claims. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type VMClaimCRDInstaller struct{} + +func (vmci VMClaimCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.VirtualMachineClaim{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.VirtualMachineClaim{}, func(cv *crder.Version) { + cv. + WithColumn("BindMode", ".status.bind_mode"). + WithColumn("Bound", ".status.bound"). + WithColumn("Ready", ".status.ready"). + WithStatus() + }) + }), + } +} diff --git a/v3/services/vmclaimsvc/internal/grpc.go b/v3/services/vmclaimsvc/internal/grpc.go new file mode 100644 index 00000000..e5edaa3e --- /dev/null +++ b/v3/services/vmclaimsvc/internal/grpc.go @@ -0,0 +1,326 @@ +package vmclaimservice + +import ( + "context" + "fmt" + + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/timestamppb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" + "k8s.io/client-go/util/workqueue" +) + +type GrpcVMClaimServer struct { + vmclaimpb.UnimplementedVMClaimSvcServer + vmClaimClient hfClientsetv1.VirtualMachineClaimInterface + vmClaimLister listersv1.VirtualMachineClaimLister + vmClaimSynced cache.InformerSynced + vmClaimWorkqueue workqueue.DelayingInterface +} + +func NewGrpcVMClaimServer( + hfClientSet hfClientset.Interface, + hfInformerFactory hfInformers.SharedInformerFactory, + workqueue workqueue.DelayingInterface, +) *GrpcVMClaimServer { + return &GrpcVMClaimServer{ + vmClaimClient: hfClientSet.HobbyfarmV1().VirtualMachineClaims(util.GetReleaseNamespace()), + vmClaimLister: hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Lister(), + vmClaimSynced: hfInformerFactory.Hobbyfarm().V1().VirtualMachineClaims().Informer().HasSynced, + vmClaimWorkqueue: workqueue, + } +} + +func (s *GrpcVMClaimServer) CreateVMClaim(ctx context.Context, req *vmclaimpb.CreateVMClaimRequest) (*emptypb.Empty, error) { + id := req.GetId() + userName := req.GetUserName() + vmset := req.GetVmset() + restrictedBind := req.GetRestrictedBind() + restrictedBindValue := req.GetRestrictedBindValue() + dynamicCapable := req.GetDynamicCapable() + labels := req.GetLabels() + vmClaim := &hfv1.VirtualMachineClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + Labels: labels, + }, + Spec: hfv1.VirtualMachineClaimSpec{ + UserId: userName, + RestrictedBind: restrictedBind, + BaseName: id, + VirtualMachines: make(map[string]hfv1.VirtualMachineClaimVM), + DynamicCapable: dynamicCapable, + }, + } + + if restrictedBind { + vmClaim.Spec.RestrictedBindValue = restrictedBindValue + } + + for vmName, vmTemplateName := range vmset { + vmClaim.Spec.VirtualMachines[vmName] = hfv1.VirtualMachineClaimVM{Template: vmTemplateName, VirtualMachineId: ""} + // also label this vmc so we can query against it later + vmClaim.ObjectMeta.Labels[fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s", vmTemplateName)] = "true" + } + + _, err := s.vmClaimClient.Create(ctx, vmClaim, metav1.CreateOptions{}) + if err != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMClaimServer) GetVMClaim(ctx context.Context, req *generalpb.GetRequest) (*vmclaimpb.VMClaim, error) { + vmc, err := util.GenericHfGetter(ctx, req, s.vmClaimClient, s.vmClaimLister.VirtualMachineClaims(util.GetReleaseNamespace()), "virtual machine claim", s.vmClaimSynced()) + if err != nil { + return &vmclaimpb.VMClaim{}, err + } + + vmClaimVMs := make(map[string]*vmclaimpb.VMClaimVM) + + for key, vm := range vmc.Spec.VirtualMachines { + vmClaimVM := &vmclaimpb.VMClaimVM{ + Template: vm.Template, + VmId: vm.VirtualMachineId, + } + vmClaimVMs[key] = vmClaimVM + } + + status := &vmclaimpb.VMClaimStatus{ + BindMode: vmc.Status.BindMode, + StaticBindAttempts: uint32(vmc.Status.StaticBindAttempts), + Bound: vmc.Status.Bound, + Ready: vmc.Status.Ready, + Tainted: vmc.Status.Tainted, + } + + var deletionTimeStamp *timestamppb.Timestamp + if !vmc.DeletionTimestamp.IsZero() { + deletionTimeStamp = timestamppb.New(vmc.DeletionTimestamp.Time) + } + + return &vmclaimpb.VMClaim{ + Id: vmc.Name, + Uid: string(vmc.UID), + UserId: vmc.Spec.UserId, + RestrictedBind: vmc.Spec.RestrictedBind, + RestrictedBindValue: vmc.Spec.RestrictedBindValue, + Vms: vmClaimVMs, + DynamicCapable: vmc.Spec.DynamicCapable, + BaseName: vmc.Spec.BaseName, + Labels: vmc.Labels, + Status: status, + DeletionTimestamp: deletionTimeStamp, + }, nil +} + +func (s *GrpcVMClaimServer) UpdateVMClaim(ctx context.Context, req *vmclaimpb.UpdateVMClaimRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + vmset := req.GetVmset() + restrictedBind := req.GetRestrictedBind() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vmc, err := s.vmClaimClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine claim %s", + req, + req.GetId(), + ) + } + + if restrictedBind != nil { + vmc.Spec.RestrictedBind = restrictedBind.Value + vmc.Spec.RestrictedBindValue = vmc.Labels[hflabels.ScheduledEventLabel] + } + // if restricted bind is disabled, make sure that restricted bind value is also empty + if !vmc.Spec.RestrictedBind { + vmc.Spec.RestrictedBindValue = "" + } + + if len(vmset) > 0 { + vmClaimVMs := make(map[string]hfv1.VirtualMachineClaimVM) + for key, vm := range vmset { + vmClaimVM := hfv1.VirtualMachineClaimVM{ + Template: vm.Template, + VirtualMachineId: vm.GetVmId(), + } + vmClaimVMs[key] = vmClaimVM + } + vmc.Spec.VirtualMachines = vmClaimVMs + } + + _, updateErr := s.vmClaimClient.Update(ctx, vmc, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMClaimServer) UpdateVMClaimStatus(ctx context.Context, req *vmclaimpb.UpdateVMClaimStatusRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + bindMode := req.GetBindMode() + staticBindAttempts := req.GetStaticBindAttempts() + bound := req.GetBound() + ready := req.GetReady() + tainted := req.GetTainted() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vmc, err := s.vmClaimClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine claim %s", + req, + req.GetId(), + ) + } + + if bindMode != "" { + vmc.Status.BindMode = bindMode + } + + if staticBindAttempts != nil { + vmc.Status.StaticBindAttempts = int(staticBindAttempts.Value) + } + + if bound != nil { + vmc.Status.Bound = bound.Value + } + + if ready != nil { + vmc.Status.Ready = ready.Value + } + + if tainted != nil { + vmc.Status.Tainted = tainted.Value + } + + _, updateErr := s.vmClaimClient.UpdateStatus(ctx, vmc, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + // @TODO: verify result like in util.go + glog.V(4).Infof("updated result for vmc") + return nil + }) + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update vmc status: %v", + req, + retryErr, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMClaimServer) DeleteVMClaim(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.vmClaimClient, "virtual machine claim") +} + +func (s *GrpcVMClaimServer) DeleteCollectionVMClaim(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.vmClaimClient, "virtual machine claims") +} + +func (s *GrpcVMClaimServer) ListVMClaim(ctx context.Context, listOptions *generalpb.ListOptions) (*vmclaimpb.ListVMClaimsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var vmClaims []hfv1.VirtualMachineClaim + var err error + if !doLoadFromCache { + var vmClaimList *hfv1.VirtualMachineClaimList + vmClaimList, err = util.ListByHfClient(ctx, listOptions, s.vmClaimClient, "virtual machine claims") + if err == nil { + vmClaims = vmClaimList.Items + } + } else { + vmClaims, err = util.ListByCache(listOptions, s.vmClaimLister, "virtual machine claims", s.vmClaimSynced()) + } + if err != nil { + glog.Error(err) + return &vmclaimpb.ListVMClaimsResponse{}, err + } + + preparedVmcs := []*vmclaimpb.VMClaim{} + + for _, vmc := range vmClaims { + vmClaimVMs := make(map[string]*vmclaimpb.VMClaimVM) + for key, vm := range vmc.Spec.VirtualMachines { + vmClaimVM := &vmclaimpb.VMClaimVM{ + Template: vm.Template, + VmId: vm.VirtualMachineId, + } + vmClaimVMs[key] = vmClaimVM + } + + status := &vmclaimpb.VMClaimStatus{ + BindMode: vmc.Status.BindMode, + StaticBindAttempts: uint32(vmc.Status.StaticBindAttempts), + Bound: vmc.Status.Bound, + Ready: vmc.Status.Ready, + Tainted: vmc.Status.Tainted, + } + + var deletionTimeStamp *timestamppb.Timestamp + if !vmc.DeletionTimestamp.IsZero() { + deletionTimeStamp = timestamppb.New(vmc.DeletionTimestamp.Time) + } + + preparedVmcs = append(preparedVmcs, &vmclaimpb.VMClaim{ + Id: vmc.Name, + Uid: string(vmc.UID), + UserId: vmc.Spec.UserId, + RestrictedBind: vmc.Spec.RestrictedBind, + RestrictedBindValue: vmc.Spec.RestrictedBindValue, + Vms: vmClaimVMs, + DynamicCapable: vmc.Spec.DynamicCapable, + BaseName: vmc.Spec.BaseName, + Labels: vmc.Labels, + Status: status, + DeletionTimestamp: deletionTimeStamp, + }) + } + + return &vmclaimpb.ListVMClaimsResponse{Vmclaims: preparedVmcs}, nil +} + +func (s *GrpcVMClaimServer) AddToWorkqueue(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.AddToWorkqueue(s.vmClaimWorkqueue, req) +} diff --git a/v3/services/vmclaimsvc/internal/server.go b/v3/services/vmclaimsvc/internal/server.go new file mode 100644 index 00000000..373745cc --- /dev/null +++ b/v3/services/vmclaimsvc/internal/server.go @@ -0,0 +1,38 @@ +package vmclaimservice + +import ( + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + + "github.com/golang/glog" + "github.com/gorilla/mux" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" +) + +const ( + idIndex = "vmcs.hobbyfarm.io/id-index" + resourcePlural = rbac.ResourcePluralVMClaim +) + +type VMClaimServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + internalVMClaimServer *GrpcVMClaimServer +} + +func NewVMClaimServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + internalVMClaimServer *GrpcVMClaimServer, +) VMClaimServer { + return VMClaimServer{ + authnClient: authnClient, + authrClient: authrClient, + internalVMClaimServer: internalVMClaimServer, + } +} + +func (vmcs VMClaimServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/vmclaim/{vm_claim_id}", vmcs.GetVMClaimFunc).Methods("GET") + glog.V(2).Infof("set up routes") +} diff --git a/v3/services/vmclaimsvc/internal/vmclaimservice.go b/v3/services/vmclaimsvc/internal/vmclaimservice.go new file mode 100644 index 00000000..20d78b15 --- /dev/null +++ b/v3/services/vmclaimsvc/internal/vmclaimservice.go @@ -0,0 +1,92 @@ +package vmclaimservice + +import ( + "encoding/json" + "fmt" + "net/http" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +type PreparedVirtualMachineClaim struct { + Id string `json:"id"` + UserId string `json:"user"` + RestrictedBind bool `json:"restricted_bind"` + RestrictedBindValue string `json:"restricted_bind_value"` + VirtualMachines map[string]*vmclaimpb.VMClaimVM `json:"vm"` + DynamicCapable bool `json:"dynamic_bind_capable"` + BaseName string `json:"base_name"` + BindMode string `json:"bind_mode"` + StaticBindAttempts uint32 `json:"static_bind_attempts"` + Bound bool `json:"bound"` + Ready bool `json:"ready"` + Tainted bool `json:"tainted"` +} + +func (vmcs VMClaimServer) GetVMClaimFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, vmcs.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vmc") + return + } + + vars := mux.Vars(r) + + vmcId := vars["vm_claim_id"] + + if len(vmcId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no vmc id passed in") + return + } + + vmc, err := vmcs.internalVMClaimServer.GetVMClaim(r.Context(), &generalpb.GetRequest{Id: vmcId, LoadFromCache: true}) + if err != nil { + glog.Error(hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + util.ReturnHTTPMessage(w, r, 404, "not found", fmt.Sprintf("vm claim %s not found", vmcId)) + return + } else { + util.ReturnHTTPMessage(w, r, 500, "internalerror", fmt.Sprintf("error retrieving vm claim %s", vmcId)) + return + } + } + + if vmc.GetUserId() != user.GetId() { + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, vmcs.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "access denied to get vmclaim") + return + } + } + + preparedVMC := PreparedVirtualMachineClaim{ + Id: vmcId, + UserId: vmc.GetUserId(), + RestrictedBind: vmc.GetRestrictedBind(), + RestrictedBindValue: vmc.GetRestrictedBindValue(), + VirtualMachines: vmc.GetVms(), + DynamicCapable: vmc.GetDynamicCapable(), + BaseName: vmc.GetBaseName(), + BindMode: vmc.GetStatus().GetBindMode(), + StaticBindAttempts: vmc.GetStatus().GetStaticBindAttempts(), + Bound: vmc.GetStatus().GetBound(), + Ready: vmc.GetStatus().GetReady(), + Tainted: vmc.GetStatus().GetTainted(), + } + + encodedVMC, err := json.Marshal(preparedVMC) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedVMC) + + glog.V(2).Infof("retrieved vmc %s", vmcId) +} diff --git a/v3/services/vmclaimsvc/main.go b/v3/services/vmclaimsvc/main.go new file mode 100644 index 00000000..e10bf128 --- /dev/null +++ b/v3/services/vmclaimsvc/main.go @@ -0,0 +1,129 @@ +package main + +import ( + "context" + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "k8s.io/client-go/util/workqueue" + + "github.com/golang/glog" + vmclaimservice "github.com/hobbyfarm/gargantua/services/vmclaimsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + accesscodepb "github.com/hobbyfarm/gargantua/v3/protos/accesscode" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + dbconfigpb "github.com/hobbyfarm/gargantua/v3/protos/dbconfig" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + progresspb "github.com/hobbyfarm/gargantua/v3/protos/progress" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + ctx := context.Background() + + cfg, hfClient, kubeClient := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(vmclaimservice.VMClaimCRDInstaller{}, cfg, "virtual machine claim") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.AccessCode, + microservices.DBConfig, + microservices.Environment, + microservices.Progress, + microservices.ScheduledEvent, + microservices.Session, + microservices.VM, + microservices.VMTemplate, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + acClient := accesscodepb.NewAccessCodeSvcClient(connections[microservices.AccessCode]) + dbcClient := dbconfigpb.NewDynamicBindConfigSvcClient(connections[microservices.DBConfig]) + envClient := environmentpb.NewEnvironmentSvcClient(connections[microservices.Environment]) + eventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + progressClient := progresspb.NewProgressSvcClient(connections[microservices.Progress]) + sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session]) + vmClient := vmpb.NewVMSvcClient(connections[microservices.VM]) + vmTemplateClient := vmtemplatepb.NewVMTemplateSvcClient(connections[microservices.VMTemplate]) + + vmClaimWorkqueue := workqueue.NewDelayingQueueWithConfig(workqueue.DelayingQueueConfig{Name: "vmclaim-controller"}) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + vs := vmclaimservice.NewGrpcVMClaimServer(hfClient, hfInformerFactory, vmClaimWorkqueue) + vmclaimpb.RegisterVMClaimSvcServer(gs, vs) + vmClaimController, err := vmclaimservice.NewVMClaimController( + kubeClient, + vs, + hfInformerFactory, + acClient, + dbcClient, + envClient, + eventClient, + progressClient, + sessionClient, + vmClient, + vmTemplateClient, + ctx, + ) + if err != nil { + glog.Fatalf("failed creating vm claim controller: %s", err.Error()) + } + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + vmClaimServer := vmclaimservice.NewVMClaimServer( + authnClient, + authrClient, + vs, + ) + microservices.StartAPIServer(vmClaimServer) + }() + + go func() { + defer wg.Done() + vmClaimController.RunSharded(stopCh, microservices.VMClaim) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/vmsetsvc/Dockerfile b/v3/services/vmsetsvc/Dockerfile new file mode 100644 index 00000000..6c4b2fa3 --- /dev/null +++ b/v3/services/vmsetsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/vmsetsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/vmsetsvc/go.mod b/v3/services/vmsetsvc/go.mod new file mode 100644 index 00000000..1d8f1c93 --- /dev/null +++ b/v3/services/vmsetsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/vmsetsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/vmsetsvc/go.sum b/v3/services/vmsetsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/vmsetsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/vmsetsvc/internal/controller.go b/v3/services/vmsetsvc/internal/controller.go new file mode 100644 index 00000000..228214d8 --- /dev/null +++ b/v3/services/vmsetsvc/internal/controller.go @@ -0,0 +1,282 @@ +package vmsetservice + +import ( + "context" + "fmt" + "math/rand" + "strings" + "time" + + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + "k8s.io/apimachinery/pkg/labels" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + controllers "github.com/hobbyfarm/gargantua/v3/pkg/microservices/controller" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + "k8s.io/client-go/kubernetes" +) + +const ( + vmSetFinalizer = "finalizer.hobbyfarm.io/vmset" +) + +type VMSetController struct { + controllers.DelayingWorkqueueController + controllers.Reconciler + internalVmSetServer *GrpcVMSetServer + environmentClient environmentpb.EnvironmentSvcClient + vmClient vmpb.VMSvcClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient +} + +func NewVMSetController( + kubeClient *kubernetes.Clientset, + internalVmSetServer *GrpcVMSetServer, + hfInformerFactory hfInformers.SharedInformerFactory, + environmentClient environmentpb.EnvironmentSvcClient, + vmClient vmpb.VMSvcClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + ctx context.Context, +) (*VMSetController, error) { + vmSetInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Informer() + delayingWorkqueueController := *controllers.NewDelayingWorkqueueController( + ctx, + vmSetInformer, + kubeClient, + "vmset-controller", + time.Minute*30, + internalVmSetServer.vmSetWorkqueue, + ) + + vmSetController := &VMSetController{ + DelayingWorkqueueController: delayingWorkqueueController, + internalVmSetServer: internalVmSetServer, + environmentClient: environmentClient, + vmClient: vmClient, + vmTemplateClient: vmTemplateClient, + } + vmSetController.SetReconciler(vmSetController) + vmSetController.SetWorkScheduler(vmSetController) + + return vmSetController, nil +} + +func (v *VMSetController) Reconcile(objName string) error { + glog.V(8).Infof("reconciling vmclaim %s inside vm claim controller", objName) + // fetch vmClaim + vmSet, err := v.internalVmSetServer.GetVMSet(v.Context, &generalpb.GetRequest{Id: objName}) + if err != nil { + if hferrors.IsGrpcNotFound(err) { + glog.Infof("vmset %s not found on queue.. ignoring", objName) + //v.vmSetWorkqueue.Forget(obj) + return nil + } else { + return fmt.Errorf("error while retrieving vmset %s from queue with err %v", objName, err) + } + } + + err = v.reconcileVirtualMachineSet(vmSet) + + //v.vmSetWorkqueue.Forget(obj) + glog.V(4).Infof("vm set processed by vm set controller %v", objName) + return err +} + +func (v *VMSetController) enqueueVMSet(vmSetId string) { + glog.V(8).Infof("Enqueueing vm set %s", vmSetId) + //v.vmSetWorkqueue.AddRateLimited(key) + v.GetWorkqueue().Add(vmSetId) +} + +func (v *VMSetController) reconcileVirtualMachineSet(vmset *vmsetpb.VMSet) error { + vmLabels := labels.Set{ + "vmset": vmset.GetId(), + } + currentVMList, err := v.vmClient.ListVM(v.Context, &generalpb.ListOptions{ + LabelSelector: vmLabels.AsSelector().String(), + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error listing vms in vmset controller") + return err + } + + currentVMs := currentVMList.GetVms() + + if len(currentVMs) < int(vmset.GetCount()) { // if desired count is greater than the current provisioned + // 1. let's check the environment to see if there is available capacity + // 2. if available capacity is available let's create new VM's + glog.V(4).Infof("vmset %s needs %d vm's but current vm count is %d", vmset.GetId(), vmset.GetCount(), len(currentVMs)) + env, err := v.environmentClient.GetEnvironment(v.Context, &generalpb.GetRequest{ + Id: vmset.GetEnvironment(), + LoadFromCache: true, + }) + var provision bool + provision = true + if provisionMethod, ok := env.GetAnnotations()["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { + provision = false + } + if err != nil { + if hferrors.IsGrpcNotFound(err) { + glog.Errorf("environment invalid") + } + return err + } + + vmt, err := v.vmTemplateClient.GetVMTemplate(v.Context, &generalpb.GetRequest{ + Id: vmset.GetVmTemplate(), + LoadFromCache: true, + }) + + if err != nil { + return fmt.Errorf("error while retrieving virtual machine template %s %v", vmset.GetVmTemplate(), err) + } + needed := int(vmset.GetCount()) - len(currentVMs) + + glog.V(5).Infof("provisioning %d vms", needed) + for i := 0; i < needed; i++ { + vmName := strings.Join([]string{vmset.GetBaseName(), fmt.Sprintf("%08x", rand.Uint32())}, "-") + config := util.GetVMConfig(env, vmt) + sshUser := config["ssh_username"] + protocol, exists := config["protocol"] + if !exists { + protocol = "ssh" + } + restrictedBind := vmset.GetRestrictedBind() + + vmLabels := map[string]string{ + "dynamic": "false", + "vmset": vmset.GetId(), + hflabels.VirtualMachineTemplate: vmt.GetId(), + hflabels.EnvironmentLabel: env.GetId(), + "bound": "false", + "ready": "false", + hflabels.ScheduledEventLabel: vmset.GetLabels()[hflabels.ScheduledEventLabel], + "restrictedbind": fmt.Sprintf("%t", restrictedBind), + } + if restrictedBind { + vmLabels["restrictedbindvalue"] = vmset.GetRestrictedBindValue() + } + if provisionMethod, ok := env.GetAnnotations()["hobbyfarm.io/provisioner"]; ok && provisionMethod != "" { + vmLabels["hobbyfarm.io/provisioner"] = provisionMethod + } + + _, err := v.vmClient.CreateVM(v.Context, &vmpb.CreateVMRequest{ + Id: vmName, + VmTemplateId: vmt.GetId(), + SshUsername: sshUser, + Protocol: protocol, + SecretName: "", + User: "", + Provision: provision, + VmSetId: vmset.GetId(), + VmSetUid: vmset.GetUid(), + Labels: vmLabels, + Finalizers: []string{vmSetFinalizer}, + }) + + if err != nil { + glog.Error(err) + } + + _, err = v.vmClient.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: vmName, + Status: string(hfv1.VmStatusRFP), + Allocated: wrapperspb.Bool(false), + Tainted: wrapperspb.Bool(false), + WsEndpoint: env.GetWsEndpoint(), + PublicIp: wrapperspb.String(""), + PrivateIp: wrapperspb.String(""), + EnvironmentId: env.GetId(), + Hostname: wrapperspb.String(""), + }) + + if err != nil { + glog.Error(err) + } + } + } + + // handle case of scaling down VMSets + if len(currentVMs) > int(vmset.GetCount()) { + // We first calculate how many VMs already have been deleted to avoid deleting more than we need + currentlyDeleting := 0 + for _, x := range currentVMs { + if x.GetDeletionTimestamp() != nil { + currentlyDeleting++ + } + } + + // We need to delete all over the spec.count minus the VMs that are already being deleted right now. + needed_delete := len(currentVMs) - int(vmset.GetCount()) - currentlyDeleting + glog.V(4).Infof("vmset %s needs to delete %d vm's and %d are already flagged as deleted", vmset.GetId(), needed_delete, currentlyDeleting) + for _, cur_vm := range currentVMs { + if needed_delete == 0 { + break + } + + if !cur_vm.GetStatus().GetAllocated() && cur_vm.GetDeletionTimestamp() == nil { + _, err = v.vmClient.DeleteVM(v.Context, &generalpb.ResourceId{Id: cur_vm.GetId()}) + if err != nil { + glog.Errorf("error deleting vm %s with error: %v", cur_vm.GetId(), err) + } else { + needed_delete-- + } + } + } + if needed_delete > 0 { + glog.V(4).Infof("vmset %d could not delete %d VMs due to some VMs being in use.", vmset.GetId(), needed_delete) + } + } + + vmList, err := v.vmClient.ListVM(v.Context, &generalpb.ListOptions{ + LabelSelector: vmLabels.AsSelector().String(), + LoadFromCache: true, + }) + + if err != nil { + glog.Errorf("error while retrieving vms owned by vmset %s", vmset.GetId()) + } + + vms := vmList.GetVms() + + provisionedCount := 0 + activeCount := 0 + for _, x := range vms { + if x.GetDeletionTimestamp() == nil && !x.GetStatus().GetTainted() { + activeCount++ + } + provisionedCount++ + } + + if activeCount < int(vmset.GetCount()) { + glog.V(4).Infof("requeing VMset as there are not enough VMs ready") + v.enqueueVMSet(vmset.GetId()) + } + + err = v.updateVMSetCount(vmset.GetId(), activeCount, provisionedCount) + + return err +} + +func (v *VMSetController) updateVMSetCount(vmSetName string, active int, prov int) error { + _, err := v.internalVmSetServer.UpdateVMSetStatus(v.Context, &vmsetpb.UpdateVMSetStatusRequest{ + Available: wrapperspb.UInt32(uint32(active)), + Provisioned: wrapperspb.UInt32(uint32(prov)), + }) + if err != nil { + return fmt.Errorf("error updating Virtual Machine Set Status: %s, %v", vmSetName, err) + } + return nil +} diff --git a/v3/services/vmsetsvc/internal/crd.go b/v3/services/vmsetsvc/internal/crd.go new file mode 100644 index 00000000..1325b01a --- /dev/null +++ b/v3/services/vmsetsvc/internal/crd.go @@ -0,0 +1,26 @@ +package vmsetservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// VMSetCRDInstaller is a struct that can generate CRDs for virtual machine sets. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type VMSetCRDInstaller struct{} + +func (vmsi VMSetCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.VirtualMachineSet{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.VirtualMachineSet{}, func(cv *crder.Version) { + cv. + WithColumn("Available", ".status.available"). + WithColumn("Provisioned", ".status.provisioned"). + WithStatus() + }) + }), + } +} diff --git a/v3/services/vmsetsvc/internal/grpc.go b/v3/services/vmsetsvc/internal/grpc.go new file mode 100644 index 00000000..a6290c21 --- /dev/null +++ b/v3/services/vmsetsvc/internal/grpc.go @@ -0,0 +1,321 @@ +package vmsetservice + +import ( + "context" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" + "k8s.io/client-go/util/workqueue" +) + +type GrpcVMSetServer struct { + vmsetpb.UnimplementedVMSetSvcServer + vmSetClient hfClientsetv1.VirtualMachineSetInterface + vmSetLister listersv1.VirtualMachineSetLister + vmSetSynced cache.InformerSynced + vmSetWorkqueue workqueue.DelayingInterface +} + +func NewGrpcVMSetServer( + hfClientSet hfClientset.Interface, + hfInformerFactory hfInformers.SharedInformerFactory, + workqueue workqueue.DelayingInterface, +) *GrpcVMSetServer { + return &GrpcVMSetServer{ + vmSetClient: hfClientSet.HobbyfarmV1().VirtualMachineSets(util.GetReleaseNamespace()), + vmSetLister: hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Lister(), + vmSetSynced: hfInformerFactory.Hobbyfarm().V1().VirtualMachineSets().Informer().HasSynced, + vmSetWorkqueue: workqueue, + } +} + +func (s *GrpcVMSetServer) CreateVMSet(ctx context.Context, req *vmsetpb.CreateVMSetRequest) (*emptypb.Empty, error) { + id := req.GetId() + count := req.GetCount() + environment := req.GetEnvironment() + vmTemplate := req.GetVmTemplate() + baseName := req.GetBaseName() + restrictedBind := req.GetRestrictedBind() + restrictedBindValue := req.GetRestrictedBindValue() + seName := req.GetSeName() + seUid := req.GetSeUid() + labels := req.GetLabels() + + vms := &hfv1.VirtualMachineSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: "ScheduledEvent", + Name: seName, + UID: types.UID(seUid), + }, + }, + Labels: labels, + }, + Spec: hfv1.VirtualMachineSetSpec{ + Count: int(count), + Environment: environment, + RestrictedBind: restrictedBind, + VMTemplate: vmTemplate, + BaseName: baseName, + }, + } + + if restrictedBind { + vms.Spec.RestrictedBindValue = restrictedBindValue + } + + _, err := s.vmSetClient.Create(ctx, vms, metav1.CreateOptions{}) + if err != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMSetServer) GetVMSet(ctx context.Context, req *generalpb.GetRequest) (*vmsetpb.VMSet, error) { + vms, err := util.GenericHfGetter(ctx, req, s.vmSetClient, s.vmSetLister.VirtualMachineSets(util.GetReleaseNamespace()), "virtual machine set", s.vmSetSynced()) + if err != nil { + return &vmsetpb.VMSet{}, err + } + + vmSetVMs := []*vmsetpb.VMProvision{} + + for _, vm := range vms.Status.Machines { + vmSetVM := &vmsetpb.VMProvision{ + VmName: vm.VirtualMachineName, + TfcState: vm.TFControllerState, + TfcCm: vm.TFControllerCM, + } + vmSetVMs = append(vmSetVMs, vmSetVM) + } + + status := &vmsetpb.VMSetStatus{ + Machines: vmSetVMs, + Available: uint32(vms.Status.AvailableCount), + Provisioned: uint32(vms.Status.ProvisionedCount), + } + + return &vmsetpb.VMSet{ + Id: vms.Name, + Uid: string(vms.UID), + Count: uint32(vms.Spec.Count), + Environment: vms.Spec.Environment, + VmTemplate: vms.Spec.VMTemplate, + BaseName: vms.Spec.BaseName, + RestrictedBind: vms.Spec.RestrictedBind, + RestrictedBindValue: vms.Spec.RestrictedBindValue, + Labels: vms.Labels, + Status: status, + }, nil +} + +func (s *GrpcVMSetServer) UpdateVMSet(ctx context.Context, req *vmsetpb.UpdateVMSetRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + count := req.GetCount() + environment := req.GetEnvironment() + vmTemplate := req.GetVmTemplate() + restrictedBind := req.GetRestrictedBind() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vms, err := s.vmSetClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine set %s", + req, + req.GetId(), + ) + } + + if count != nil { + vms.Spec.Count = int(count.Value) + } + + if environment != "" { + vms.Spec.Environment = environment + vms.Labels[hflabels.EnvironmentLabel] = environment + } + + if vmTemplate != "" { + vms.Spec.VMTemplate = vmTemplate + } + + if restrictedBind != nil { + vms.Spec.RestrictedBind = restrictedBind.Value + vms.Spec.RestrictedBindValue = vms.Labels[hflabels.ScheduledEventLabel] + } + // if restricted bind is disabled, make sure that restricted bind value is also empty + if !vms.Spec.RestrictedBind { + vms.Spec.RestrictedBindValue = "" + } + + _, updateErr := s.vmSetClient.Update(ctx, vms, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMSetServer) UpdateVMSetStatus(ctx context.Context, req *vmsetpb.UpdateVMSetStatusRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + machines := req.GetMachines() + available := req.GetAvailable() + provisioned := req.GetProvisioned() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vms, err := s.vmSetClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine set %s", + req, + req.GetId(), + ) + } + + if available != nil { + vms.Status.AvailableCount = int(available.Value) + } + + if provisioned != nil { + vms.Status.ProvisionedCount = int(provisioned.Value) + } + + if len(machines) > 0 { + vmSetVMs := []hfv1.VirtualMachineProvision{} + for key, vm := range machines { + vmSetVM := hfv1.VirtualMachineProvision{ + VirtualMachineName: vm.VmName, + TFControllerState: vm.TfcState, + TFControllerCM: vm.TfcCm, + } + vmSetVMs[key] = vmSetVM + vmSetVMs = append(vmSetVMs, vmSetVM) + } + vms.Status.Machines = vmSetVMs + } + + _, updateErr := s.vmSetClient.UpdateStatus(ctx, vms, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + // @TODO: verify result like in util.go + glog.V(4).Infof("updated result for vms") + return nil + }) + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update vms status: %v", + req, + retryErr, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMSetServer) DeleteVMSet(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.vmSetClient, "virtual machine set") +} + +func (s *GrpcVMSetServer) DeleteCollectionVMSet(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.vmSetClient, "virtual machine sets") +} + +func (s *GrpcVMSetServer) ListVMSet(ctx context.Context, listOptions *generalpb.ListOptions) (*vmsetpb.ListVMSetsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var vmSets []hfv1.VirtualMachineSet + var err error + if !doLoadFromCache { + var vmSetList *hfv1.VirtualMachineSetList + vmSetList, err = util.ListByHfClient(ctx, listOptions, s.vmSetClient, "virtual machine sets") + if err == nil { + vmSets = vmSetList.Items + } + } else { + vmSets, err = util.ListByCache(listOptions, s.vmSetLister, "virtual machine sets", s.vmSetSynced()) + } + if err != nil { + glog.Error(err) + return &vmsetpb.ListVMSetsResponse{}, err + } + + preparedVmSets := []*vmsetpb.VMSet{} + + for _, vms := range vmSets { + vmSetVMs := []*vmsetpb.VMProvision{} + for key, vm := range vms.Status.Machines { + vmSetVM := &vmsetpb.VMProvision{ + VmName: vm.VirtualMachineName, + TfcState: vm.TFControllerState, + TfcCm: vm.TFControllerCM, + } + vmSetVMs[key] = vmSetVM + vmSetVMs = append(vmSetVMs, vmSetVM) + } + + status := &vmsetpb.VMSetStatus{ + Machines: vmSetVMs, + Available: uint32(vms.Status.AvailableCount), + Provisioned: uint32(vms.Status.ProvisionedCount), + } + + preparedVmSets = append(preparedVmSets, &vmsetpb.VMSet{ + Id: vms.Name, + Uid: string(vms.UID), + Count: uint32(vms.Spec.Count), + Environment: vms.Spec.Environment, + VmTemplate: vms.Spec.VMTemplate, + BaseName: vms.Spec.BaseName, + RestrictedBind: vms.Spec.RestrictedBind, + RestrictedBindValue: vms.Spec.RestrictedBindValue, + Status: status, + Labels: vms.Labels, + }) + } + + return &vmsetpb.ListVMSetsResponse{Vmsets: preparedVmSets}, nil +} + +func (s *GrpcVMSetServer) AddToWorkqueue(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.AddToWorkqueue(s.vmSetWorkqueue, req) +} diff --git a/v3/services/vmsetsvc/internal/server.go b/v3/services/vmsetsvc/internal/server.go new file mode 100644 index 00000000..50a1bb2b --- /dev/null +++ b/v3/services/vmsetsvc/internal/server.go @@ -0,0 +1,32 @@ +package vmsetservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" +) + +type VMSetServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + internalVMSetServer *GrpcVMSetServer +} + +func NewVMSetServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + internalVMSetServer *GrpcVMSetServer, +) VMSetServer { + return VMSetServer{ + authnClient: authnClient, + authrClient: authrClient, + internalVMSetServer: internalVMSetServer, + } +} + +func (vms VMSetServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/a/vmset/{se_id}", vms.GetVMSetListByScheduledEventFunc).Methods("GET") + r.HandleFunc("/a/vmset", vms.GetAllVMSetListFunc).Methods("GET") + glog.V(2).Infof("set up routes") +} diff --git a/v3/services/vmsetsvc/internal/vmsetservice.go b/v3/services/vmsetsvc/internal/vmsetservice.go new file mode 100644 index 00000000..cdd76a00 --- /dev/null +++ b/v3/services/vmsetsvc/internal/vmsetservice.go @@ -0,0 +1,99 @@ +package vmsetservice + +import ( + "encoding/json" + "fmt" + "net/http" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + util2 "github.com/hobbyfarm/gargantua/v3/pkg/util" + + "github.com/golang/glog" + "github.com/gorilla/mux" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" +) + +const ( + resourcePlural = rbac.ResourcePluralVMSet +) + +type PreparedVirtualMachineSet struct { + Id string `json:"id"` + Count uint32 `json:"count"` + Environment string `json:"environment"` + VMTemplate string `json:"vm_template"` + BaseName string `json:"base_name"` + RestrictedBind bool `json:"restricted_bind"` + RestrictedBindValue string `json:"restricted_bind_value"` + Machines []*vmsetpb.VMProvision `json:"machines"` + AvailableCount uint32 `json:"available"` + ProvisionedCount uint32 `json:"provisioned"` +} + +func (vms VMSetServer) GetVMSetListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + id := vars["se_id"] + + if len(id) == 0 { + util2.ReturnHTTPMessage(w, r, 400, "bad request", "no scheduledEvent id passed in") + return + } + + lo := &generalpb.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id)} + + vms.GetVMSetListFunc(w, r, lo) +} + +func (vms VMSetServer) GetAllVMSetListFunc(w http.ResponseWriter, r *http.Request) { + vms.GetVMSetListFunc(w, r, &generalpb.ListOptions{}) +} + +func (vms VMSetServer) GetVMSetListFunc(w http.ResponseWriter, r *http.Request, listOptions *generalpb.ListOptions) { + user, err := rbac.AuthenticateRequest(r, vms.authnClient) + if err != nil { + util2.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util2.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list vmsets") + return + } + + vmSetList, err := vms.internalVMSetServer.ListVMSet(r.Context(), listOptions) + + if err != nil { + glog.Errorf("error while retrieving vmsets: %s", hferrors.GetErrorMessage(err)) + util2.ReturnHTTPMessage(w, r, 500, "error", "error retreiving vmsets") + return + } + + preparedVMSets := []PreparedVirtualMachineSet{} + for _, vmSet := range vmSetList.GetVmsets() { + pVMSet := PreparedVirtualMachineSet{ + Id: vmSet.GetId(), + Count: vmSet.GetCount(), + Environment: vmSet.GetEnvironment(), + VMTemplate: vmSet.GetVmTemplate(), + BaseName: vmSet.GetBaseName(), + RestrictedBind: vmSet.GetRestrictedBind(), + RestrictedBindValue: vmSet.GetRestrictedBindValue(), + Machines: vmSet.GetStatus().GetMachines(), + AvailableCount: vmSet.GetStatus().GetAvailable(), + ProvisionedCount: vmSet.GetStatus().GetProvisioned(), + } + preparedVMSets = append(preparedVMSets, pVMSet) + } + + encodedVMSets, err := json.Marshal(preparedVMSets) + if err != nil { + glog.Error(err) + } + util2.ReturnHTTPContent(w, r, 200, "success", encodedVMSets) +} diff --git a/v3/services/vmsetsvc/main.go b/v3/services/vmsetsvc/main.go new file mode 100644 index 00000000..a784780d --- /dev/null +++ b/v3/services/vmsetsvc/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "context" + "sync" + "time" + + "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "k8s.io/client-go/util/workqueue" + + vmsetservice "github.com/hobbyfarm/gargantua/services/vmsetsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + ctx := context.Background() + + cfg, hfClient, kubeClient := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(vmsetservice.VMSetCRDInstaller{}, cfg, "virtual machine set") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.Environment, + microservices.VM, + microservices.VMTemplate, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + envClient := environmentpb.NewEnvironmentSvcClient(connections[microservices.Environment]) + vmClient := vmpb.NewVMSvcClient(connections[microservices.VM]) + vmTemplateClient := vmtemplatepb.NewVMTemplateSvcClient(connections[microservices.VMTemplate]) + + vmSetWorkqueue := workqueue.NewDelayingQueueWithConfig(workqueue.DelayingQueueConfig{Name: "vmclaim-controller"}) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + vs := vmsetservice.NewGrpcVMSetServer(hfClient, hfInformerFactory, vmSetWorkqueue) + vmsetpb.RegisterVMSetSvcServer(gs, vs) + vmSetController, err := vmsetservice.NewVMSetController( + kubeClient, + vs, + hfInformerFactory, + envClient, + vmClient, + vmTemplateClient, + ctx, + ) + if err != nil { + glog.Fatalf("failed creating vm set controller: %s", err.Error()) + } + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + vmSetServer := vmsetservice.NewVMSetServer( + authnClient, + authrClient, + vs, + ) + microservices.StartAPIServer(vmSetServer) + }() + + go func() { + defer wg.Done() + vmSetController.RunSharded(stopCh, microservices.VMSet) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/vmsvc/Dockerfile b/v3/services/vmsvc/Dockerfile new file mode 100644 index 00000000..4dc6e7b8 --- /dev/null +++ b/v3/services/vmsvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/vmsvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/vmsvc/go.mod b/v3/services/vmsvc/go.mod new file mode 100644 index 00000000..f725c216 --- /dev/null +++ b/v3/services/vmsvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/vmsvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/api v0.28.2 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/vmsvc/go.sum b/v3/services/vmsvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/vmsvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/vmsvc/internal/controller.go b/v3/services/vmsvc/internal/controller.go new file mode 100644 index 00000000..0c18507c --- /dev/null +++ b/v3/services/vmsvc/internal/controller.go @@ -0,0 +1,468 @@ +package vmservice + +import ( + "context" + "fmt" + "math/rand" + "strings" + "time" + + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + controllers "github.com/hobbyfarm/gargantua/v3/pkg/microservices/controller" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + terraformpb "github.com/hobbyfarm/gargantua/v3/protos/terraform" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/golang/glog" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + k8sv1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +const ( + vmSetFinalizer = "finalizer.hobbyfarm.io/vmset" +) + +type VMController struct { + controllers.DelayingWorkqueueController + controllers.Reconciler + internalVmServer *GrpcVMServer + configMapClient corev1.ConfigMapInterface + environmentClient environmentpb.EnvironmentSvcClient + secretClient corev1.SecretInterface + terraformClient terraformpb.TerraformSvcClient + vmClaimClient vmclaimpb.VMClaimSvcClient + vmSetClient vmsetpb.VMSetSvcClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient +} + +func NewVMController( + kubeClient *kubernetes.Clientset, + internalVmServer *GrpcVMServer, + hfInformerFactory hfInformers.SharedInformerFactory, + environmentClient environmentpb.EnvironmentSvcClient, + terraformClient terraformpb.TerraformSvcClient, + vmClaimClient vmclaimpb.VMClaimSvcClient, + vmSetClient vmsetpb.VMSetSvcClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + ctx context.Context, +) (*VMController, error) { + kubeClient.CoreV1().ConfigMaps("") + vmInformer := hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer() + delayingWorkqueueController := *controllers.NewDelayingWorkqueueController( + ctx, + vmInformer, + kubeClient, + "vm-controller", + time.Minute*30, + nil, + ) + + vmController := &VMController{ + DelayingWorkqueueController: delayingWorkqueueController, + internalVmServer: internalVmServer, + configMapClient: kubeClient.CoreV1().ConfigMaps(util.GetReleaseNamespace()), + environmentClient: environmentClient, + secretClient: kubeClient.CoreV1().Secrets(util.GetReleaseNamespace()), + terraformClient: terraformClient, + vmClaimClient: vmClaimClient, + vmSetClient: vmSetClient, + vmTemplateClient: vmTemplateClient, + } + vmController.SetReconciler(vmController) + vmController.SetWorkScheduler(vmController) + + return vmController, nil +} + +func (v *VMController) Reconcile(objName string) error { + glog.V(8).Infof("reconciling vm %s inside vm controller", objName) + // fetch vm + vm, err := v.internalVmServer.GetVM(v.Context, &generalpb.GetRequest{Id: objName}) + if err != nil { + if hferrors.IsGrpcNotFound(err) { + glog.Infof("vm %s not found on queue.. ignoring", objName) + return nil + } else { + glog.Errorf("error while retrieving vm %s from queue with err %v", objName, err) + return err + } + } + + // trigger reconcile on vmClaims only when associated VM is running + // this should avoid triggering unwanted reconciles of VMClaims until the VM's are running + if vm.GetVmClaimId() != "" && vm.GetStatus().GetStatus() == string(hfv1.VmStatusRunning) { + v.vmClaimClient.AddToWorkqueue(v.Context, &generalpb.ResourceId{Id: vm.GetVmClaimId()}) + } + if vm.GetStatus().GetTainted() && vm.GetDeletionTimestamp() == nil { + err, requeue := v.deleteVM(vm) + v.handleRequeue(err, requeue, vm.GetId()) + } else if vm.GetDeletionTimestamp() != nil { + err, requeue := v.handleDeletion(vm) + v.handleRequeue(err, requeue, vm.GetId()) + } else { + err, requeue := v.handleProvision(vm) + v.handleRequeue(err, requeue, vm.GetId()) + } + return nil +} + +func (v *VMController) handleRequeue(err error, requeue bool, vmId string) { + if err != nil { + glog.Error(err) + } + if requeue { + v.GetWorkqueue().Add(vmId) + } +} + +// returns an error and a boolean of requeue +func (v *VMController) deleteVM(vm *vmpb.VM) (error, bool) { + _, deleteVMErr := v.internalVmServer.DeleteVM(v.Context, &generalpb.ResourceId{Id: vm.GetId()}) + if deleteVMErr != nil { + return fmt.Errorf("there was an error while deleting the virtual machine %s", vm.GetId()), true + } + // We do not need to manually requeue this vm if it is deleted successfully. The controller picks up deletion events by design. + return nil, false +} + +// returns an error and a boolean of requeue +func (v *VMController) handleDeletion(vm *vmpb.VM) (error, bool) { + if vm.GetVmSetId() != "" && util.ContainsFinalizer(vm.GetFinalizers(), vmSetFinalizer) { + glog.V(4).Infof("requeuing vmset %s to account for tainted vm %s", vm.GetVmSetId(), vm.GetId()) + updatedVmFinalizers := util.RemoveFinalizer(vm.GetFinalizers(), vmSetFinalizer) + _, err := v.internalVmServer.UpdateVM(v.Context, &vmpb.UpdateVMRequest{Id: vm.GetId(), Finalizers: &generalpb.StringArray{ + Values: updatedVmFinalizers, + }}) + if err != nil { + glog.Errorf("error removing vm finalizer on vm %s", vm.GetId()) + return err, true + } + v.vmSetClient.AddToWorkqueue(v.Context, &generalpb.ResourceId{Id: vm.GetVmSetId()}) + // We do not need to manually requeue this vm if it is updated successfully. The controller picks up update events by design. + return nil, false + } + + if vm.GetStatus().GetTfstate() == "" { + return v.updateAndVerifyVMDeletion(vm) + } + + _, err := v.terraformClient.DeleteState(v.Context, &generalpb.ResourceId{Id: vm.GetStatus().GetTfstate()}) + if hferrors.IsGrpcNotFound(err) { + // Our vm has no associated terraform state (anymore). Let's remove its remaining finalizers! + return v.updateAndVerifyVMDeletion(vm) + } else if err != nil { + // Something went wrong during the terraform state deletion process. Let's requeue and try again! + return err, true + } else { + // The terraform state was deleted successfully. + // We still need to requeue, remove the finalizers and confirm that the vm was deleted successfully + return nil, false + } +} + +// returns an error and a boolean of requeue +func (v *VMController) updateAndVerifyVMDeletion(vm *vmpb.VM) (error, bool) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + resultCh := make(chan error, 1) + + // start verification of deletion in a separate goroutine + go func() { + resultCh <- util.VerifyDeletion(ctx, v.internalVmServer.vmClient, vm.GetId()) + }() + _, err := v.internalVmServer.UpdateVM(v.Context, &vmpb.UpdateVMRequest{ + Id: vm.GetId(), + Finalizers: &generalpb.StringArray{Values: []string{}}, + }) + if err != nil { + // Something went wrong while removing the remaining finalizers. Let's requeue and try again. + return err, true + } + + // At this point the remaining finalizers were removed successfully. + // But the verification of the vm deletion might fail, e. g. if the context deadline is exceeded. + // We have chosen not to requeue in this scenario to ensure that the controller remains responsive for other tasks. + err = <-resultCh + if err != nil { + glog.Warningf("VM deletion verification failed: %v", err) + } else { + glog.Infof("VM %s deleted successfully", vm.GetId()) + } + return nil, false +} + +// returns an error and a boolean of requeue +func (v *VMController) handleProvision(vm *vmpb.VM) (error, bool) { + // VM shall not be provisioned by internal terraform controller + if !vm.GetProvision() { + if prov, ok := vm.GetLabels()["hobbyfarm.io/provisioner"]; ok && prov != "" { + glog.V(8).Infof("vm %s ignored by internal provisioner due to 3rd party provisioning label", vm.GetId()) + v.GetWorkqueue().Done(vm.GetId()) + } + glog.V(8).Infof("vm %s was not a provisioned vm", vm.GetId()) + return nil, false + } + //Status is ReadyForProvisioning AND No Secret provided (Do not provision VM twice, happens due to vm.status being updated after vm.status) + if vm.Status.Status == string(hfv1.VmStatusRFP) { + vmt, err := v.vmTemplateClient.GetVMTemplate(v.Context, &generalpb.GetRequest{Id: vm.GetVmTemplateId(), LoadFromCache: true}) + if err != nil { + glog.Errorf("error getting vmt %v", err) + return err, true + } + env, err := v.environmentClient.GetEnvironment(v.Context, &generalpb.GetRequest{Id: vm.GetStatus().GetEnvironmentId(), LoadFromCache: true}) + if err != nil { + glog.Errorf("error getting env %v", err) + return err, true + } + + _, exists := env.GetTemplateMapping()[vmt.GetId()] + if !exists { + glog.Errorf("error pulling environment template info %v", err) + // @TODO: Why do we requeue here??? This will fail for each iteration as long as the environment is not updated... + return fmt.Errorf("Error during RFP: environment %s does not support vmt %s.", env.GetId(), vmt.GetId()), true + } + + // let's provision the vm + pubKey, privKey, err := util.GenKeyPair() + if err != nil { + glog.Errorf("error generating keypair %v", err) + return err, true + } + config := util.GetVMConfig(env, vmt) + + config["name"] = vm.GetId() + config["public_key"] = pubKey + + image, exists := config["image"] + if !exists || image == "" { + return fmt.Errorf("image does not exist or is empty in vm config for vmt %s", vmt.GetId()), true + } + + moduleName, exists := config["module"] + if !exists || moduleName == "" { + return fmt.Errorf("module name does not exist or is empty in vm config for vmt %s", vmt.GetId()), true + } + + executorImage, exists := config["executor_image"] + if !exists || executorImage == "" { + return fmt.Errorf("executorimage does not exist or is empty in vm config for vmt %s", vmt.GetId()), true + } + + password, exists := config["password"] + if !exists { + password = "" + } + + vmOwnerReference := []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: "VirtualMachine", + Name: vm.GetId(), + UID: types.UID(vm.GetUid()), + }, + } + + r := fmt.Sprintf("%08x", rand.Uint32()) + cm := &k8sv1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.Join([]string{vm.GetId() + "-cm", r}, "-"), + OwnerReferences: vmOwnerReference, + }, + Data: config, + } + + cm, err = v.configMapClient.Create(v.Context, cm, metav1.CreateOptions{}) + + if err != nil { + glog.Errorf("error creating configmap %s: %v", cm.Name, err) + } + + keypair := &k8sv1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.Join([]string{vm.GetId() + "-secret", r}, "-"), + OwnerReferences: vmOwnerReference, + }, + Data: map[string][]byte{ + "private_key": []byte(privKey), + "public_key": []byte(pubKey), + "password": []byte(password), + }, + } + + keypair, err = v.secretClient.Create(v.Context, keypair, metav1.CreateOptions{}) + + if err != nil { + glog.Errorf("error creating secret %s: %v", keypair.Name, err) + } + + credentialSecrets := []string{} + credentialsSecret, exists := config["cred_secret"] + if !exists { + glog.Errorf("cred secret does not exist in env template") + } + if credentialsSecret != "" { + credentialSecrets = append(credentialSecrets, credentialsSecret) + } + + tfsId, err := v.terraformClient.CreateState(v.Context, &terraformpb.CreateStateRequest{ + VmId: vm.GetId(), + Image: executorImage, + Variables: &terraformpb.Variables{ + ConfigNames: []string{cm.Name}, + SecretNames: credentialSecrets, + }, + ModuleName: moduleName, + AutoConfirm: true, + DestroyOnDelete: true, + }) + + if err != nil { + glog.Errorf("error creating tfs %v", err) + } + + _, err = v.internalVmServer.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: vm.GetId(), + Status: string(hfv1.VmStatusProvisioned), + Tfstate: tfsId.GetId(), + }) + if err != nil { + return err, true + } + + var updatedFinalizers []string + if vm.GetFinalizers() != nil { + updatedFinalizers = append(vm.GetFinalizers(), "vm.controllers.hobbyfarm.io") + } else { + updatedFinalizers = []string{"vm.controllers.hobbyfarm.io"} + } + _, err = v.internalVmServer.UpdateVM(v.Context, &vmpb.UpdateVMRequest{ + Id: vm.GetId(), + SecretName: keypair.Name, + Finalizers: &generalpb.StringArray{Values: updatedFinalizers}, + }) + if err != nil { + return err, true + } + + glog.V(6).Infof("provisioned vm %s", vm.GetId()) + return nil, false + + } else if vm.Status.Status == string(hfv1.VmStatusProvisioned) { + // let's check the status of our tf provision + /*tfState, err := t.tfsLister.States(util.GetReleaseNamespace()).Get(vm.Status.TFState) + if err != nil { + if apierrors.IsNotFound(err) { + return fmt.Errorf("execution not found") + } + return nil + } */ + // TEMPORARY WORKAROUND UNTIL WE FIGURE OUT A BETTER WAY TO DO THIS + + if vm.GetStatus().GetTfstate() == "" { + return fmt.Errorf("tf state was blank in object"), true + } + + labelSelectorString := labels.Set{"state": string(vm.GetStatus().GetTfstate())}.AsSelector().String() + tfExecsList, err := v.terraformClient.ListExecution(v.Context, &generalpb.ListOptions{ + LabelSelector: labelSelectorString, + }) + + if err != nil { + return err, true + } + + tfExecs := tfExecsList.GetExecutions() + + var newestTimestamp int32 + var tfExec *terraformpb.Execution + if len(tfExecs) == 0 { + return fmt.Errorf("no executions found for terraform state"), true + } + + newestTimestamp = tfExecs[0].GetCreationTimestamp().GetNanos() + tfExec = tfExecs[0] + for _, e := range tfExecs { + if newestTimestamp < e.GetCreationTimestamp().GetNanos() { + newestTimestamp = e.GetCreationTimestamp().GetNanos() + tfExec = e + } + } + // END TEMPORARY WORKAROUND + + //executionName := tfState.Status.ExecutionName + /* + tfExec, err := t.tfeLister.Executions(util.GetReleaseNamespace()).Get(executionName) + if err != nil { + //glog.Error(err) + if apierrors.IsNotFound(err) { + return fmt.Errorf("execution not found") + } + return nil + } + */ + if tfExec.GetStatus().GetOutputs() == "" { + return nil, true + } + + tfOutput, err := util.GenericUnmarshal[map[string]map[string]string](tfExec.GetStatus().GetOutputs(), "terraform execution output") + if err != nil { + glog.Error(err) + } + env, err := v.environmentClient.GetEnvironment(v.Context, &generalpb.GetRequest{ + Id: vm.GetStatus().GetEnvironmentId(), + LoadFromCache: true, + }) + if err != nil { + glog.Error(err) + return fmt.Errorf("error getting environment"), true + } + glog.V(8).Infof("private ip is: %s", tfOutput["private_ip"]["value"]) + + var publicIP string + if _, exists := tfOutput["public_ip"]; exists { + publicIP = tfOutput["public_ip"]["value"] + } else { + publicIP = translatePrivToPub(env.GetIpTranslationMap(), tfOutput["private_ip"]["value"]) + } + + _, err = v.internalVmServer.UpdateVMStatus(v.Context, &vmpb.UpdateVMStatusRequest{ + Id: vm.GetId(), + Status: string(hfv1.VmStatusRunning), + PublicIp: wrapperspb.String(publicIP), + PrivateIp: wrapperspb.String(tfOutput["private_ip"]["value"]), + Hostname: wrapperspb.String(tfOutput["hostname"]["value"]), + }) + + if err != nil { + return err, true + } + } + return nil, false +} + +func translatePrivToPub(translationMap map[string]string, priv string) string { + splitIp := strings.Split(priv, ".") + + origPrefix := splitIp[0] + "." + splitIp[1] + "." + splitIp[2] + + translation, ok := translationMap[origPrefix] + + if ok { + return translation + "." + splitIp[3] + } + return "" + +} diff --git a/v3/services/vmsvc/internal/crd.go b/v3/services/vmsvc/internal/crd.go new file mode 100644 index 00000000..624a9a50 --- /dev/null +++ b/v3/services/vmsvc/internal/crd.go @@ -0,0 +1,28 @@ +package vmservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// VmCRDInstaller is a struct that can generate CRDs for virtual machines. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type VmCRDInstaller struct{} + +func (vmi VmCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.VirtualMachine{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.VirtualMachine{}, func(cv *crder.Version) { + cv. + WithColumn("Status", ".status.status"). + WithColumn("Allocated", ".status.allocated"). + WithColumn("PublicIP", ".status.public_ip"). + WithColumn("PrivateIP", ".status.private_ip"). + WithStatus() + }) + }), + } +} diff --git a/v3/services/vmsvc/internal/grpc.go b/v3/services/vmsvc/internal/grpc.go new file mode 100644 index 00000000..ef82fde8 --- /dev/null +++ b/v3/services/vmsvc/internal/grpc.go @@ -0,0 +1,380 @@ +package vmservice + +import ( + "context" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/timestamppb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcVMServer struct { + vmpb.UnimplementedVMSvcServer + vmClient hfClientsetv1.VirtualMachineInterface + vmLister listersv1.VirtualMachineLister + vmSynced cache.InformerSynced +} + +func NewGrpcVMServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcVMServer { + return &GrpcVMServer{ + vmClient: hfClientSet.HobbyfarmV1().VirtualMachines(util.GetReleaseNamespace()), + vmLister: hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Lister(), + vmSynced: hfInformerFactory.Hobbyfarm().V1().VirtualMachines().Informer().HasSynced, + } +} + +func (s *GrpcVMServer) CreateVM(ctx context.Context, req *vmpb.CreateVMRequest) (*emptypb.Empty, error) { + var ownerReferenceId string + var ownerReferenceUid types.UID + var ownerReferenceKind string + + id := req.GetId() + vmTemplateId := req.GetVmTemplateId() + sshUserName := req.GetSshUsername() + protocol := req.GetProtocol() + secretName := req.GetSecretName() + vmClaimId := req.GetVmClaimId() + vmClaimUid := req.GetVmClaimUid() + user := req.GetUser() + provision := req.GetProvision() + vmSetId := req.GetVmSetId() + vmSetUid := req.GetVmSetUid() + labels := req.GetLabels() + finalizers := req.GetFinalizers() + + vmSetOwner := vmSetId != "" && vmSetUid != "" + vmClaimOwner := vmClaimId != "" && vmClaimUid != "" + // either vmClaimId AND vmClaimUid or vmSetId AND vmSetUid need to be provided for the owner reference + // if that's not the case, return an error + if !vmSetOwner && !vmClaimOwner { + return &emptypb.Empty{}, hferrors.GrpcError(codes.InvalidArgument, "no ID and UID for owner reference provided", req) + } + + // vm set takes precedence over vm claim + if vmSetOwner { + ownerReferenceId = vmSetId + ownerReferenceUid = types.UID(vmSetUid) + ownerReferenceKind = "VirtualMachineSet" + } else { + ownerReferenceId = vmClaimId + ownerReferenceUid = types.UID(vmClaimUid) + ownerReferenceKind = "VirtualMachineClaim" + } + + requiredStringParams := map[string]string{ + "id": id, + "vmTemplateId": vmTemplateId, + "protocol": protocol, + } + for param, value := range requiredStringParams { + if value == "" { + return &emptypb.Empty{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + vm := &hfv1.VirtualMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: id, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "hobbyfarm.io/v1", + Kind: ownerReferenceKind, + Name: ownerReferenceId, + UID: ownerReferenceUid, + }, + }, + Labels: labels, + Finalizers: finalizers, + }, + Spec: hfv1.VirtualMachineSpec{ + VirtualMachineTemplateId: vmTemplateId, + SecretName: secretName, + Protocol: protocol, + VirtualMachineClaimId: vmClaimId, + UserId: user, + Provision: provision, + VirtualMachineSetId: vmSetId, + }, + } + + if sshUserName != "" { + vm.Spec.SshUsername = sshUserName + } + + _, err := s.vmClient.Create(ctx, vm, metav1.CreateOptions{}) + if err != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMServer) GetVM(ctx context.Context, req *generalpb.GetRequest) (*vmpb.VM, error) { + vm, err := util.GenericHfGetter(ctx, req, s.vmClient, s.vmLister.VirtualMachines(util.GetReleaseNamespace()), "virtual machine", s.vmSynced()) + if err != nil { + return &vmpb.VM{}, err + } + + status := &vmpb.VMStatus{ + Status: string(vm.Status.Status), + Allocated: vm.Status.Allocated, + Tainted: vm.Status.Tainted, + PublicIp: vm.Status.PublicIP, + PrivateIp: vm.Status.PrivateIP, + EnvironmentId: vm.Status.EnvironmentId, + Hostname: vm.Status.Hostname, + Tfstate: vm.Status.TFState, + WsEndpoint: vm.Status.WsEndpoint, + } + + var deletionTimeStamp *timestamppb.Timestamp + if !vm.DeletionTimestamp.IsZero() { + deletionTimeStamp = timestamppb.New(vm.DeletionTimestamp.Time) + } + + return &vmpb.VM{ + Id: vm.Name, + Uid: string(vm.UID), + VmTemplateId: vm.Spec.VirtualMachineTemplateId, + SshUsername: vm.Spec.SshUsername, + Protocol: vm.Spec.Protocol, + SecretName: vm.Spec.SecretName, + VmClaimId: vm.Spec.VirtualMachineClaimId, + User: vm.Spec.UserId, + Provision: vm.Spec.Provision, + VmSetId: vm.Spec.VirtualMachineSetId, + Labels: vm.Labels, + Finalizers: vm.Finalizers, + Status: status, + Annotations: vm.Annotations, + DeletionTimestamp: deletionTimeStamp, + }, nil +} + +func (s *GrpcVMServer) UpdateVM(ctx context.Context, req *vmpb.UpdateVMRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + bound := req.GetBound() + vmClaimId := req.GetVmClaimId() + user := req.GetUser() + secretName := req.GetSecretName() + finalizers := req.GetFinalizers() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vm, err := s.vmClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine %s", + req, + req.GetId(), + ) + } + + if bound != "" { + vm.Labels["bound"] = bound + } + + if vmClaimId != nil { + vm.Spec.VirtualMachineClaimId = vmClaimId.GetValue() + } + + if user != nil { + vm.Spec.UserId = user.GetValue() + } + + if secretName != "" { + vm.Spec.SecretName = secretName + } + + if finalizers != nil { + vm.SetFinalizers(finalizers.GetValues()) + } + + _, updateErr := s.vmClient.Update(ctx, vm, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMServer) UpdateVMStatus(ctx context.Context, req *vmpb.UpdateVMStatusRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + status := req.GetStatus() + allocated := req.GetAllocated() + tainted := req.GetTainted() + publicIp := req.GetPublicIp() + privateIp := req.GetPrivateIp() + hostname := req.GetHostname() + environmentId := req.GetEnvironmentId() + tfState := req.GetTfstate() + wsEndpoint := req.GetWsEndpoint() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vm, err := s.vmClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine %s", + req, + req.GetId(), + ) + } + + if status != "" { + vm.Status.Status = hfv1.VmStatus(status) + } + + if allocated != nil { + vm.Status.Allocated = allocated.GetValue() + } + + if tainted != nil { + vm.Status.Tainted = tainted.GetValue() + } + + if publicIp != nil { + vm.Status.PublicIP = publicIp.GetValue() + } + + if privateIp != nil { + vm.Status.PrivateIP = privateIp.GetValue() + } + + if hostname != nil { + vm.Status.Hostname = hostname.GetValue() + } + + if environmentId != "" { + vm.Status.EnvironmentId = environmentId + } + + if tfState != "" { + vm.Status.TFState = tfState + } + + if wsEndpoint != "" { + vm.Status.WsEndpoint = wsEndpoint + } + + _, updateErr := s.vmClient.UpdateStatus(ctx, vm, metav1.UpdateOptions{}) + if updateErr != nil { + return updateErr + } + // @TODO: verify result like in util.go + glog.V(4).Infof("updated result for vm") + return nil + }) + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update vm status: %v", + req, + retryErr, + ) + } + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMServer) DeleteVM(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.vmClient, "virtual machine") +} + +func (s *GrpcVMServer) DeleteCollectionVM(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.vmClient, "virtual machines") +} + +func (s *GrpcVMServer) ListVM(ctx context.Context, listOptions *generalpb.ListOptions) (*vmpb.ListVMsResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var vms []hfv1.VirtualMachine + var err error + if !doLoadFromCache { + var vmList *hfv1.VirtualMachineList + vmList, err = util.ListByHfClient(ctx, listOptions, s.vmClient, "virtual machines") + if err == nil { + vms = vmList.Items + } + } else { + vms, err = util.ListByCache(listOptions, s.vmLister, "virtual machines", s.vmSynced()) + } + if err != nil { + glog.Error(err) + return &vmpb.ListVMsResponse{}, err + } + + preparedVms := []*vmpb.VM{} + + for _, vm := range vms { + status := &vmpb.VMStatus{ + Status: string(vm.Status.Status), + Allocated: vm.Status.Allocated, + Tainted: vm.Status.Tainted, + PublicIp: vm.Status.PublicIP, + PrivateIp: vm.Status.PrivateIP, + Hostname: vm.Status.Hostname, + EnvironmentId: vm.Status.EnvironmentId, + Tfstate: vm.Status.TFState, + WsEndpoint: vm.Status.WsEndpoint, + } + + var deletionTimeStamp *timestamppb.Timestamp + if !vm.DeletionTimestamp.IsZero() { + deletionTimeStamp = timestamppb.New(vm.DeletionTimestamp.Time) + } + + preparedVms = append(preparedVms, &vmpb.VM{ + Id: vm.Name, + Uid: string(vm.UID), + VmTemplateId: vm.Spec.VirtualMachineTemplateId, + SshUsername: vm.Spec.SshUsername, + Protocol: vm.Spec.Protocol, + SecretName: vm.Spec.SecretName, + VmClaimId: vm.Spec.VirtualMachineClaimId, + User: vm.Spec.UserId, + Provision: vm.Spec.Provision, + VmSetId: vm.Spec.VirtualMachineSetId, + Labels: vm.Labels, + Finalizers: vm.Finalizers, + Status: status, + Annotations: vm.Annotations, + DeletionTimestamp: deletionTimeStamp, + }) + } + + return &vmpb.ListVMsResponse{Vms: preparedVms}, nil +} diff --git a/v3/services/vmsvc/internal/server.go b/v3/services/vmsvc/internal/server.go new file mode 100644 index 00000000..6ad88bd9 --- /dev/null +++ b/v3/services/vmsvc/internal/server.go @@ -0,0 +1,39 @@ +package vmservice + +import ( + "github.com/golang/glog" + "github.com/gorilla/mux" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +type VMServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + vmTemplateClient vmtemplatepb.VMTemplateSvcClient + internalVMServer *GrpcVMServer +} + +func NewVMServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + vmTemplateClient vmtemplatepb.VMTemplateSvcClient, + internalVMServer *GrpcVMServer, +) VMServer { + return VMServer{ + authnClient: authnClient, + authrClient: authrClient, + vmTemplateClient: vmTemplateClient, + internalVMServer: internalVMServer, + } +} + +func (vms VMServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/vm/{vm_id}", vms.GetVMFunc).Methods("GET") + r.HandleFunc("/vm/getwebinterfaces/{vm_id}", vms.getWebinterfaces).Methods("GET") + r.HandleFunc("/a/vm/list", vms.GetAllVMListFunc).Methods("GET") + r.HandleFunc("/a/vm/scheduledevent/{se_id}", vms.GetVMListByScheduledEventFunc).Methods("GET") + r.HandleFunc("/a/vm/count", vms.CountByScheduledEvent).Methods("GET") + glog.V(2).Infof("set up routes") +} diff --git a/v3/services/vmsvc/internal/vmservice.go b/v3/services/vmsvc/internal/vmservice.go new file mode 100644 index 00000000..88337393 --- /dev/null +++ b/v3/services/vmsvc/internal/vmservice.go @@ -0,0 +1,278 @@ +package vmservice + +import ( + "encoding/json" + "fmt" + "net/http" + + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +const ( + idIndex = "vms.hobbyfarm.io/id-index" + resourcePlural = rbac.ResourcePluralVM +) + +type PreparedVirtualMachine struct { + Id string `json:"id"` + VirtualMachineTemplateId string `json:"vm_template_id"` + SshUsername string `json:"ssh_username"` + Protocol string `json:"protocol"` + SecretName string `json:"secret_name"` // this refers to the secret name for the keypair + VirtualMachineClaimId string `json:"vm_claim_id"` + UserId string `json:"user"` + Provision bool `json:"provision"` + VirtualMachineSetId string `json:"vm_set_id"` + Status string `json:"status"` // default is nothing, but could be one of the following: readyforprovisioning, provisioning, running, terminating + Allocated bool `json:"allocated"` + Tainted bool `json:"tainted"` + PublicIP string `json:"public_ip"` + PrivateIP string `json:"private_ip"` + EnvironmentId string `json:"environment_id"` + Hostname string `json:"hostname"` // ideally . should be the FQDN to this machine + TFState string `json:"tfstate,omitempty"` // Terraform state name + WsEndpoint string `json:"ws_endpoint"` +} + +/* +* Checks if VMTemplate used to create VM has "webinterfaces" in ConfigMap. +* Returns those webinterface definitions or http Error Codes. + */ +func (vms VMServer) getWebinterfaces(w http.ResponseWriter, r *http.Request) { + // Check if User has access to VMs + user, err := rbac.AuthenticateRequest(r, vms.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") + return + } + impersonatedUserId := user.GetId() + + vars := mux.Vars(r) + // Check if id for the VM was provided + vmId := vars["vm_id"] + if len(vmId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no vm id passed in") + return + } + // Get the VM, Error if none is found for the given id + vm, err := vms.internalVMServer.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) + if err != nil { + glog.Errorf("error retrieving virtual machine %s from cache: %s", vmId, hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("vm %s not found", vmId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving vm %s", vmId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) + return + } + + // Check if the VM belongs to the User or User has RBAC-Rights to access VMs + if vm.GetUser() != impersonatedUserId { + authrResponse, err := rbac.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + glog.Errorf("user forbidden from accessing vm id %s", vm.GetId()) + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") + return + } + } + + // Get the corresponding VMTemplate for the VM and Check for "ide" + vmtId := vm.GetVmTemplateId() + vmt, err := vms.vmTemplateClient.GetVMTemplate(r.Context(), &generalpb.GetRequest{Id: vmtId}) + if err != nil { + glog.Errorf("error retrieving vm's vm template %s: %s", vmtId, hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("vm template %s of vm %s not found", vmtId, vmId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving vm template %s of vm %s", vmtId, vmId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) + return + } + + services, found := vmt.GetConfigMap()["webinterfaces"] + if !found { + util.ReturnHTTPMessage(w, r, 404, "error", "No Webinterfaces found for this VM") + return + } + + encodedWebinterfaceDefinitions, err := json.Marshal(services) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedWebinterfaceDefinitions) +} + +func (vms VMServer) GetVMFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, vms.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") + return + } + impersonatedUserId := user.GetId() + + vars := mux.Vars(r) + + vmId := vars["vm_id"] + + if len(vmId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no vm id passed in") + return + } + + vm, err := vms.internalVMServer.GetVM(r.Context(), &generalpb.GetRequest{Id: vmId, LoadFromCache: true}) + if err != nil { + glog.Errorf("error retrieving virtual machine %s from cache: %s", vmId, hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("vm %s not found", vmId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving vm %s", vmId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) + return + } + + if vm.GetUser() != impersonatedUserId { + authrResponse, err := rbac.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + glog.Errorf("user forbidden from accessing vm id %s", vm.GetId()) + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm") + return + } + } + + preparedVM := getPreparedVM(vm) + encodedVM, err := json.Marshal(preparedVM) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedVM) + + glog.V(2).Infof("retrieved vm %s", vm.GetId()) +} + +func (vms VMServer) GetVMListFunc(w http.ResponseWriter, r *http.Request, listOptions *generalpb.ListOptions) { + user, err := rbac.AuthenticateRequest(r, vms.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list virtualmachines") + return + } + + vmList, err := vms.internalVMServer.ListVM(r.Context(), listOptions) + if err != nil { + glog.Errorf("error while retrieving vms %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error retreiving vms") + return + } + + preparedVMs := []PreparedVirtualMachine{} + for _, vm := range vmList.GetVms() { + pVM := getPreparedVM(vm) + preparedVMs = append(preparedVMs, pVM) + } + + encodedVMs, err := json.Marshal(preparedVMs) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedVMs) +} + +func (vms VMServer) GetVMListByScheduledEventFunc(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + id := vars["se_id"] + + if len(id) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no scheduledEvent id passed in") + return + } + + lo := &generalpb.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", hflabels.ScheduledEventLabel, id)} + + vms.GetVMListFunc(w, r, lo) +} + +func (vms VMServer) CountByScheduledEvent(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, vms.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, vms.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list virtualmachines") + return + } + + vmList, err := vms.internalVMServer.ListVM(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error while retrieving virtualmachine %v", err) + util.ReturnHTTPMessage(w, r, 500, "error", "no virtualmachine found") + return + } + + countMap := map[string]int{} + for _, vm := range vmList.GetVms() { + se := vm.GetLabels()[hflabels.ScheduledEventLabel] + if _, ok := countMap[se]; ok { + countMap[se] = countMap[se] + 1 + } else { + countMap[se] = 1 + } + } + + encodedMap, err := json.Marshal(countMap) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedMap) +} + +func (vms VMServer) GetAllVMListFunc(w http.ResponseWriter, r *http.Request) { + vms.GetVMListFunc(w, r, &generalpb.ListOptions{}) +} + +func getPreparedVM(vm *vmpb.VM) PreparedVirtualMachine { + return PreparedVirtualMachine{ + Id: vm.GetId(), + VirtualMachineTemplateId: vm.GetVmTemplateId(), + SshUsername: vm.GetSshUsername(), + Protocol: vm.GetProtocol(), + SecretName: vm.GetSecretName(), + VirtualMachineClaimId: vm.GetVmClaimId(), + UserId: vm.GetUser(), + Provision: vm.GetProvision(), + VirtualMachineSetId: vm.GetVmSetId(), + Status: vm.GetStatus().GetStatus(), + Allocated: vm.GetStatus().GetAllocated(), + Tainted: vm.GetStatus().GetTainted(), + PublicIP: vm.GetStatus().GetPublicIp(), + PrivateIP: vm.GetStatus().GetPrivateIp(), + EnvironmentId: vm.GetStatus().GetEnvironmentId(), + Hostname: vm.GetStatus().GetHostname(), + TFState: vm.GetStatus().GetTfstate(), + WsEndpoint: vm.GetStatus().GetWsEndpoint(), + } +} diff --git a/v3/services/vmsvc/main.go b/v3/services/vmsvc/main.go new file mode 100644 index 00000000..d4960662 --- /dev/null +++ b/v3/services/vmsvc/main.go @@ -0,0 +1,114 @@ +package main + +import ( + "context" + "sync" + "time" + + "github.com/golang/glog" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + vmservice "github.com/hobbyfarm/gargantua/services/vmsvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + environmentpb "github.com/hobbyfarm/gargantua/v3/protos/environment" + terraformpb "github.com/hobbyfarm/gargantua/v3/protos/terraform" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + ctx := context.Background() + + cfg, hfClient, kubeClient := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(vmservice.VmCRDInstaller{}, cfg, "virtual machine") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.Environment, + microservices.Terraform, + microservices.VMClaim, + microservices.VMSet, + microservices.VMTemplate, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + environmentClient := environmentpb.NewEnvironmentSvcClient(connections[microservices.Environment]) + terraformClient := terraformpb.NewTerraformSvcClient(connections[microservices.Terraform]) + vmClaimClient := vmclaimpb.NewVMClaimSvcClient(connections[microservices.VMClaim]) + vmSetClient := vmsetpb.NewVMSetSvcClient(connections[microservices.VMSet]) + vmTemplateClient := vmtemplatepb.NewVMTemplateSvcClient(connections[microservices.VMTemplate]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + vs := vmservice.NewGrpcVMServer(hfClient, hfInformerFactory) + vmpb.RegisterVMSvcServer(gs, vs) + vmController, err := vmservice.NewVMController( + kubeClient, + vs, + hfInformerFactory, + environmentClient, + terraformClient, + vmClaimClient, + vmSetClient, + vmTemplateClient, + ctx, + ) + if err != nil { + glog.Fatalf("failed creating vm controller: %s", err.Error()) + } + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + vmServer := vmservice.NewVMServer( + authnClient, + authrClient, + vmTemplateClient, + vs, + ) + microservices.StartAPIServer(vmServer) + }() + + go func() { + defer wg.Done() + vmController.RunSharded(stopCh, microservices.VM) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +} diff --git a/v3/services/vmtemplatesvc/Dockerfile b/v3/services/vmtemplatesvc/Dockerfile new file mode 100644 index 00000000..9e43da1e --- /dev/null +++ b/v3/services/vmtemplatesvc/Dockerfile @@ -0,0 +1,22 @@ +##### sdk image ##### +FROM golang:1.21.1 AS sdk + +WORKDIR /app + +# Copy everything, respecting .dockerignore. +COPY . . + +# Change to the directory of the service. +WORKDIR /app/v3/services/vmtemplatesvc +RUN go mod download + +# Build the service. The output binary is named "app". +RUN CGO_ENABLED=0 GOOS=linux go build -o /tmp/app + +###### release image ##### +FROM alpine:latest + +COPY --from=sdk /tmp/app /usr/local/bin/ + +ENTRYPOINT ["app"] +CMD ["-v=9", "-logtostderr"] \ No newline at end of file diff --git a/v3/services/vmtemplatesvc/go.mod b/v3/services/vmtemplatesvc/go.mod new file mode 100644 index 00000000..4da3f935 --- /dev/null +++ b/v3/services/vmtemplatesvc/go.mod @@ -0,0 +1,75 @@ +module github.com/hobbyfarm/gargantua/services/vmtemplatesvc/v3 + +replace github.com/hobbyfarm/gargantua/v3 => ../../ + +replace k8s.io/client-go => k8s.io/client-go v0.28.2 + +go 1.21.1 + +require ( + github.com/ebauman/crder v0.1.0 + github.com/golang/glog v1.1.2 + github.com/gorilla/mux v1.8.0 + github.com/hobbyfarm/gargantua/v3 v3.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.58.3 + google.golang.org/protobuf v1.31.0 + k8s.io/apimachinery v0.28.2 + k8s.io/client-go v12.0.0+incompatible +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/logr v1.2.4 // 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/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/handlers v1.4.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterhellberg/duration v0.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 // indirect + github.com/rancher/terraform-controller v0.0.10-alpha1 // indirect + github.com/rancher/wrangler v1.0.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.28.2 // indirect + k8s.io/apiextensions-apiserver v0.28.2 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/controller-runtime v0.13.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/v3/services/vmtemplatesvc/go.sum b/v3/services/vmtemplatesvc/go.sum new file mode 100644 index 00000000..c7c0897b --- /dev/null +++ b/v3/services/vmtemplatesvc/go.sum @@ -0,0 +1,518 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/ebauman/crder v0.1.0 h1:NNeE9mXV86b355eW/7GuZ+kUmS/jC3VbVO/ASB90guQ= +github.com/ebauman/crder v0.1.0/go.mod h1:QJ0asWI2wg4FpyguZ+7SID6Wi9utqq/83xDXVHVdc9E= +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/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +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/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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +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.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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 v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA= +github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +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 v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jetstack/cert-manager v0.7.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY= +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 v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/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/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/knative/build v0.6.0/go.mod h1:/sU74ZQkwlYA5FwYDJhYTy61i/Kn+5eWfln2jDbw3Qo= +github.com/knative/pkg v0.0.0-20190514205332-5e4512dcb2ca/go.mod h1:7Ijfhw7rfB+H9VtosIsDYvZQ+qYTz7auK3fHW/5z4ww= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +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/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/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.7.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.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterhellberg/duration v0.0.2 h1:J/ELSSpXCuHInfYJ/hGVYe0enoGsD8buoRzbsdQJW5o= +github.com/peterhellberg/duration v0.0.2/go.mod h1:n3Pkw/vId7ZwR2ITRQlLeIjETlGEtUa7zQw49dED6ew= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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_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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +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/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= +github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= +github.com/rancher/terraform-controller v0.0.10-alpha1 h1:3xcpF5bw3nR6H5K7dDLUGehnYn2NlB3Y6XuBNWKeRhw= +github.com/rancher/terraform-controller v0.0.10-alpha1/go.mod h1:0gpTA55mRx87CjOu0gIae0fAOPWn1pFLvEGxBktVv6A= +github.com/rancher/wrangler v0.0.0-20190516181950-a7cf48fa83ef/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.1.0/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v1.0.1 h1:toavOGC1+eaZufcOJD6UyIf+aGM4rlJjPqm511Ls4sI= +github.com/rancher/wrangler v1.0.1/go.mod h1:Blhan9LdaIJjC9w+xGteSrHHEiIFIdPEHEMrtx82dPk= +github.com/rancher/wrangler-api v0.1.1/go.mod h1:vholckBg588JqP3M3vyEDUz/ERaB1M3ilnCuV5XxPHM= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +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/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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-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-20190502183928-7f726cade0ab/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.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.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-20210107192922-496545a6307b/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= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= +k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= +k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= +k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= +k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= +k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= +k8s.io/code-generator v0.0.0-20190311093542-50b561225d70/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +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.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= +sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +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/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +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= diff --git a/v3/services/vmtemplatesvc/internal/crd.go b/v3/services/vmtemplatesvc/internal/crd.go new file mode 100644 index 00000000..1b295abe --- /dev/null +++ b/v3/services/vmtemplatesvc/internal/crd.go @@ -0,0 +1,21 @@ +package vmtemplateservice + +import ( + "github.com/ebauman/crder" + v1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + "github.com/hobbyfarm/gargantua/v3/pkg/crd" +) + +// VMTemplateCRDInstaller is a struct that can generate CRDs for virtual machine templates. +// It implements the CrdInstaller interface defined in "github.com/hobbyfarm/gargantua/v3/pkg/microservices" +type VMTemplateCRDInstaller struct{} + +func (vmti VMTemplateCRDInstaller) GenerateCRDs() []crder.CRD { + return []crder.CRD{ + crd.HobbyfarmCRD(&v1.VirtualMachineTemplate{}, func(c *crder.CRD) { + c. + IsNamespaced(true). + AddVersion("v1", &v1.VirtualMachineTemplate{}, nil) + }), + } +} diff --git a/v3/services/vmtemplatesvc/internal/grpc.go b/v3/services/vmtemplatesvc/internal/grpc.go new file mode 100644 index 00000000..2354331b --- /dev/null +++ b/v3/services/vmtemplatesvc/internal/grpc.go @@ -0,0 +1,197 @@ +package vmtemplateservice + +import ( + "context" + "crypto/sha256" + "encoding/base32" + "strings" + + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + + "github.com/golang/glog" + hfv1 "github.com/hobbyfarm/gargantua/v3/pkg/apis/hobbyfarm.io/v1" + hfClientset "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned" + hfClientsetv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/clientset/versioned/typed/hobbyfarm.io/v1" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + listersv1 "github.com/hobbyfarm/gargantua/v3/pkg/client/listers/hobbyfarm.io/v1" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +type GrpcVMTemplateServer struct { + vmtemplatepb.UnimplementedVMTemplateSvcServer + vmTemplateClient hfClientsetv1.VirtualMachineTemplateInterface + vmTemplateLister listersv1.VirtualMachineTemplateLister + vmTemplateSynced cache.InformerSynced +} + +func NewGrpcVMTemplateServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory) *GrpcVMTemplateServer { + return &GrpcVMTemplateServer{ + vmTemplateClient: hfClientSet.HobbyfarmV1().VirtualMachineTemplates(util.GetReleaseNamespace()), + vmTemplateLister: hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Lister(), + vmTemplateSynced: hfInformerFactory.Hobbyfarm().V1().VirtualMachineTemplates().Informer().HasSynced, + } +} + +func (s *GrpcVMTemplateServer) CreateVMTemplate(ctx context.Context, req *vmtemplatepb.CreateVMTemplateRequest) (*generalpb.ResourceId, error) { + name := req.GetName() + image := req.GetImage() + configMapRaw := req.GetConfigMapRaw() + + requiredStringParams := map[string]string{ + "name": name, + "image": image, + } + for param, value := range requiredStringParams { + if value == "" { + return &generalpb.ResourceId{}, hferrors.GrpcNotSpecifiedError(req, param) + } + } + + hasher := sha256.New() + hasher.Write([]byte(name)) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + + vmTemplate := &hfv1.VirtualMachineTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vmt-" + strings.ToLower(sha), + }, + Spec: hfv1.VirtualMachineTemplateSpec{ + Name: name, + Image: image, + }, + } + + if configMapRaw != "" { + configMap, err := util.GenericUnmarshal[map[string]string](configMapRaw, "config_map") + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcParsingError(req, "config_map") + } + vmTemplate.Spec.ConfigMap = configMap + } + + _, err := s.vmTemplateClient.Create(ctx, vmTemplate, metav1.CreateOptions{}) + if err != nil { + return &generalpb.ResourceId{}, hferrors.GrpcError( + codes.Internal, + err.Error(), + req, + ) + } + return &generalpb.ResourceId{Id: vmTemplate.Name}, nil +} + +func (s *GrpcVMTemplateServer) GetVMTemplate(ctx context.Context, req *generalpb.GetRequest) (*vmtemplatepb.VMTemplate, error) { + vmTemplate, err := util.GenericHfGetter(ctx, req, s.vmTemplateClient, s.vmTemplateLister.VirtualMachineTemplates(util.GetReleaseNamespace()), "virtual machine template", s.vmTemplateSynced()) + if err != nil { + return &vmtemplatepb.VMTemplate{}, err + } + + return &vmtemplatepb.VMTemplate{ + Id: vmTemplate.Name, + Uid: string(vmTemplate.UID), + Name: vmTemplate.Spec.Name, + Image: vmTemplate.Spec.Image, + ConfigMap: vmTemplate.Spec.ConfigMap, + }, nil +} + +func (s *GrpcVMTemplateServer) UpdateVMTemplate(ctx context.Context, req *vmtemplatepb.UpdateVMTemplateRequest) (*emptypb.Empty, error) { + id := req.GetId() + if len(id) == 0 { + return &emptypb.Empty{}, hferrors.GrpcIdNotSpecifiedError(req) + } + + name := req.GetName() + image := req.GetImage() + configMapRaw := req.GetConfigMapRaw() + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + vmTemplate, err := s.vmTemplateClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + glog.Error(err) + return hferrors.GrpcError( + codes.Internal, + "error while retrieving virtual machine template %s", + req, + req.GetId(), + ) + } + + if name != "" { + vmTemplate.Spec.Name = name + } + + if image != "" { + vmTemplate.Spec.Image = image + } + + if configMapRaw != "" { + configMap, err := util.GenericUnmarshal[map[string]string](configMapRaw, "config_map") + if err != nil { + return err + } + vmTemplate.Spec.ConfigMap = configMap + } + + _, updateErr := s.vmTemplateClient.Update(ctx, vmTemplate, metav1.UpdateOptions{}) + return updateErr + }) + + if retryErr != nil { + return &emptypb.Empty{}, hferrors.GrpcError( + codes.Internal, + "error attempting to update", + req, + ) + } + + return &emptypb.Empty{}, nil +} + +func (s *GrpcVMTemplateServer) DeleteVMTemplate(ctx context.Context, req *generalpb.ResourceId) (*emptypb.Empty, error) { + return util.DeleteHfResource(ctx, req, s.vmTemplateClient, "virtual machine template") +} + +func (s *GrpcVMTemplateServer) DeleteCollectionVMTemplate(ctx context.Context, listOptions *generalpb.ListOptions) (*emptypb.Empty, error) { + return util.DeleteHfCollection(ctx, listOptions, s.vmTemplateClient, "virtual machine templates") +} + +func (s *GrpcVMTemplateServer) ListVMTemplate(ctx context.Context, listOptions *generalpb.ListOptions) (*vmtemplatepb.ListVMTemplatesResponse, error) { + doLoadFromCache := listOptions.GetLoadFromCache() + var vmTemplates []hfv1.VirtualMachineTemplate + var err error + if !doLoadFromCache { + var vmTemplateList *hfv1.VirtualMachineTemplateList + vmTemplateList, err = util.ListByHfClient(ctx, listOptions, s.vmTemplateClient, "virtual machine templates") + if err == nil { + vmTemplates = vmTemplateList.Items + } + } else { + vmTemplates, err = util.ListByCache(listOptions, s.vmTemplateLister, "virtual machine templates", s.vmTemplateSynced()) + } + if err != nil { + glog.Error(err) + return &vmtemplatepb.ListVMTemplatesResponse{}, err + } + + preparedVmTemplates := []*vmtemplatepb.VMTemplate{} + + for _, vmTemplate := range vmTemplates { + preparedVmTemplates = append(preparedVmTemplates, &vmtemplatepb.VMTemplate{ + Id: vmTemplate.Name, + Uid: string(vmTemplate.UID), + Name: vmTemplate.Spec.Name, + Image: vmTemplate.Spec.Image, + ConfigMap: vmTemplate.Spec.ConfigMap, + }) + } + + return &vmtemplatepb.ListVMTemplatesResponse{Vmtemplates: preparedVmTemplates}, nil +} diff --git a/v3/services/vmtemplatesvc/internal/server.go b/v3/services/vmtemplatesvc/internal/server.go new file mode 100644 index 00000000..b9d9ef01 --- /dev/null +++ b/v3/services/vmtemplatesvc/internal/server.go @@ -0,0 +1,52 @@ +package vmtemplateservice + +import ( + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + + "github.com/golang/glog" + "github.com/gorilla/mux" +) + +type VirtualMachineTemplateServer struct { + authnClient authnpb.AuthNClient + authrClient authrpb.AuthRClient + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient + vmClient vmpb.VMSvcClient + vmClaimClient vmclaimpb.VMClaimSvcClient + vmSetClient vmsetpb.VMSetSvcClient + internalVMTemplateServer *GrpcVMTemplateServer +} + +func NewVirtualMachineTemplateServer( + authnClient authnpb.AuthNClient, + authrClient authrpb.AuthRClient, + scheduledEventClient scheduledeventpb.ScheduledEventSvcClient, + vmClient vmpb.VMSvcClient, + vmClaimClient vmclaimpb.VMClaimSvcClient, + vmSetClient vmsetpb.VMSetSvcClient, + internalVMTemplateServer *GrpcVMTemplateServer, +) VirtualMachineTemplateServer { + return VirtualMachineTemplateServer{ + authnClient: authnClient, + authrClient: authrClient, + scheduledEventClient: scheduledEventClient, + vmClient: vmClient, + vmClaimClient: vmClaimClient, + vmSetClient: vmSetClient, + internalVMTemplateServer: internalVMTemplateServer, + } +} + +func (v VirtualMachineTemplateServer) SetupRoutes(r *mux.Router) { + r.HandleFunc("/a/vmtemplate/list", v.ListFunc).Methods("GET") + r.HandleFunc("/a/vmtemplate/{id}", v.GetFunc).Methods("GET") + r.HandleFunc("/a/vmtemplate/create", v.CreateFunc).Methods("POST") + r.HandleFunc("/a/vmtemplate/{id}/update", v.UpdateFunc).Methods("PUT") + r.HandleFunc("/a/vmtemplate/{id}/delete", v.DeleteFunc).Methods("DELETE") + glog.V(2).Infof("set up routes for admin vmtemplate server") +} diff --git a/v3/services/vmtemplatesvc/internal/vmtemplateservice.go b/v3/services/vmtemplatesvc/internal/vmtemplateservice.go new file mode 100644 index 00000000..971ac692 --- /dev/null +++ b/v3/services/vmtemplatesvc/internal/vmtemplateservice.go @@ -0,0 +1,371 @@ +package vmtemplateservice + +import ( + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/rbac" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + generalpb "github.com/hobbyfarm/gargantua/v3/protos/general" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" + + "github.com/golang/glog" + "github.com/gorilla/mux" + hferrors "github.com/hobbyfarm/gargantua/v3/pkg/errors" + hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels" +) + +const ( + resourcePlural = rbac.ResourcePluralVMTemplate +) + +// Prepared struct for API endpoints which only need to provide vmt id, name and image +type PreparedVMTemplate struct { + Id string `json:"id"` + Name string `json:"name"` + Image string `json:"image"` +} + +// Prepared struct for API endpoints which additionally to the PreparedVMTemplate struct also need to provide config details +type PreparedVMTemplateWithConfig struct { + PreparedVMTemplate + ConfigMap map[string]string `json:"config_map"` +} + +func (v VirtualMachineTemplateServer) GetFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, v.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbGet)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to get vm template") + return + } + + vars := mux.Vars(r) + + vmtId := vars["id"] + + if len(vmtId) == 0 { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no vm template id passed in") + return + } + + vmt, err := v.internalVMTemplateServer.GetVMTemplate(r.Context(), &generalpb.GetRequest{Id: vmtId}) + if err != nil { + glog.Errorf("error while retrieving virtual machine template: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("virtual machine template %s not found", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving virtual machine template %s", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) + return + } + + preparedVmt := PreparedVMTemplateWithConfig{ + PreparedVMTemplate: PreparedVMTemplate{ + Id: vmtId, + Name: vmt.GetName(), + Image: vmt.GetImage(), + }, + ConfigMap: vmt.GetConfigMap(), + } + + encodedVmt, err := json.Marshal(preparedVmt) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedVmt) + + glog.V(2).Infof("retrieved vmt %s", vmtId) +} + +func (v VirtualMachineTemplateServer) ListFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, v.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbList)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to list vmts") + return + } + + vmtList, err := v.internalVMTemplateServer.ListVMTemplate(r.Context(), &generalpb.ListOptions{}) + if err != nil { + glog.Errorf("error while listing all vmts: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "error", "error listing all vmts") + return + } + + preparedVirtualMachineTemplates := []PreparedVMTemplate{} + + for _, vmt := range vmtList.GetVmtemplates() { + preparedVirtualMachineTemplates = append(preparedVirtualMachineTemplates, PreparedVMTemplate{ + Id: vmt.GetId(), + Name: vmt.GetName(), + Image: vmt.GetImage(), + }) + } + + encodedVirtualMachineTemplates, err := json.Marshal(preparedVirtualMachineTemplates) + if err != nil { + glog.Error(err) + } + util.ReturnHTTPContent(w, r, 200, "success", encodedVirtualMachineTemplates) + + glog.V(2).Infof("retrieved list of all environments") +} + +func (v VirtualMachineTemplateServer) CreateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, v.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbCreate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to create vmt") + return + } + + name := r.PostFormValue("name") + if name == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "missing name") + return + } + + image := r.PostFormValue("image") + if image == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "missing image") + return + } + + configMapRaw := r.PostFormValue("config_map") // no validation, config_map not required + + glog.V(2).Infof("user %s is creating vmtemplate", user.GetId()) + + vmTemplateId, err := v.internalVMTemplateServer.CreateVMTemplate(r.Context(), &vmtemplatepb.CreateVMTemplateRequest{ + Name: name, + Image: image, + ConfigMapRaw: configMapRaw, + }) + if err != nil { + glog.Errorf("error creating vmtemplate: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error creating vmtemplate") + return + } + + util.ReturnHTTPMessage(w, r, 201, "created", vmTemplateId.GetId()) +} + +func (v VirtualMachineTemplateServer) UpdateFunc(w http.ResponseWriter, r *http.Request) { + user, err := rbac.AuthenticateRequest(r, v.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbUpdate)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to update vmt") + return + } + + vars := mux.Vars(r) + + id := vars["id"] + if id == "" { + util.ReturnHTTPMessage(w, r, 400, "bad request", "no id passed in") + return + } + + glog.V(2).Infof("user %s updating vmtemplate %s", impersonatedUserId, id) + + name := r.PostFormValue("name") + image := r.PostFormValue("image") + configMapRaw := r.PostFormValue("config_map") + + _, err = v.internalVMTemplateServer.UpdateVMTemplate(r.Context(), &vmtemplatepb.UpdateVMTemplateRequest{ + Id: id, + Name: name, + Image: image, + ConfigMapRaw: configMapRaw, + }) + + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "error", "error attempting to update vmtemplate") + return + } + + util.ReturnHTTPMessage(w, r, 200, "updated", "") +} + +func (v VirtualMachineTemplateServer) DeleteFunc(w http.ResponseWriter, r *http.Request) { + // deleting a vmtemplate requires none of the following objects having reference to it + // - future scheduled events + // - virtualmachines + // - virtualmachineclaims + // - virtualmachinesets + user, err := rbac.AuthenticateRequest(r, v.authnClient) + if err != nil { + util.ReturnHTTPMessage(w, r, 401, "unauthorized", "authentication failed") + return + } + + impersonatedUserId := user.GetId() + authrResponse, err := rbac.AuthorizeSimple(r, v.authrClient, impersonatedUserId, rbac.HobbyfarmPermission(resourcePlural, rbac.VerbDelete)) + if err != nil || !authrResponse.Success { + util.ReturnHTTPMessage(w, r, 403, "forbidden", "no access to delete vmt") + return + } + + // first, check if the vmt exists + vars := mux.Vars(r) + vmtId := vars["id"] + if vmtId == "" { + util.ReturnHTTPMessage(w, r, 400, "badrequest", "no id passed in") + return + } + + glog.V(2).Infof("user %s deleting vmtemplate %s", user.GetId(), vmtId) + + // first check if the vmt actually exists + _, err = v.internalVMTemplateServer.GetVMTemplate(r.Context(), &generalpb.GetRequest{Id: vmtId}) + if err != nil { + glog.Errorf("error while retrieving virtual machine template: %s", hferrors.GetErrorMessage(err)) + if hferrors.IsGrpcNotFound(err) { + errMsg := fmt.Sprintf("error retrieving vmt while attempting vmt deletion: vmt %s not found", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusNotFound, "not found", errMsg) + return + } + errMsg := fmt.Sprintf("error retrieving vmt %s while attempting vmt deletion", vmtId) + util.ReturnHTTPMessage(w, r, http.StatusInternalServerError, "error", errMsg) + return + } + + // vmt exists, now we need to check all other objects for references + // start with vmList + vmList, err := v.vmClient.ListVM(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", hflabels.VirtualMachineTemplate, vmtId), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error listing virtual machines while attempting vmt deletion") + return + } + + if len(vmList.GetVms()) > 0 { + util.ReturnHTTPMessage(w, r, 409, "conflict", "existing virtual machines reference this vmtemplate") + return + } + + // now check scheduledevents + scheduledEventList, err := v.scheduledEventClient.ListScheduledEvent(r.Context(), &generalpb.ListOptions{}) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", + "error listing scheduled events while attempting vmt deletion") + return + } + + scheduledEvents := scheduledEventList.GetScheduledevents() + if len(scheduledEvents) > 0 { + for _, se := range scheduledEvents { + if !se.GetStatus().GetFinished() { + // unfinished SE. Is it going on now or in the future? + startTime, err := time.Parse(time.UnixDate, se.GetStartTime()) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", + "error parsing time while checking scheduledevent for conflict") + return + } + endTime, err := time.Parse(time.UnixDate, se.GetEndTime()) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", + "error parsing time while checking scheduledevent for conflict") + return + } + + // if this starts in the future, or hasn't ended + if startTime.After(time.Now()) || endTime.After(time.Now()) { + // check for template existence + if exists := searchForTemplateInRequiredVMs(se.GetRequiredVms(), vmtId); exists { + // if template exists in this to-be-happening SE, we can't delete it + util.ReturnHTTPMessage(w, r, 409, "conflict", + "existing or future scheduled event references this vmtemplate") + } + } + } + } + } + + // now check virtual machine claims + vmcList, err := v.vmClaimClient.ListVMClaim(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s=%s", vmtId, "true"), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", + "error listing virtual machine claims while attempting vmt deletion") + return + } + + if len(vmcList.GetVmclaims()) > 0 { + util.ReturnHTTPMessage(w, r, 409, "conflict", + "existing virtual machine claims reference this vmtemplate") + return + } + + // now check virtualmachinesets (theoretically the VM checks above should catch this, but let's be safe) + vmsetList, err := v.vmSetClient.ListVMSet(r.Context(), &generalpb.ListOptions{ + LabelSelector: fmt.Sprintf("virtualmachinetemplate.hobbyfarm.io/%s=%s", vmtId, "true"), + }) + if err != nil { + util.ReturnHTTPMessage(w, r, 500, "internalerror", + "error listing virtual machine sets while attempting vmt deletion") + return + } + + if len(vmsetList.GetVmsets()) > 0 { + util.ReturnHTTPMessage(w, r, 409, "conflict", + "existing virtual machine sets reference this vmtemplate") + return + } + + // if we get here, shouldn't be anything in our path stopping us from deleting the vmtemplate + // so do it! + _, err = v.internalVMTemplateServer.DeleteVMTemplate(r.Context(), &generalpb.ResourceId{Id: vmtId}) + if err != nil { + glog.Errorf("error deleting vmtemplate: %s", hferrors.GetErrorMessage(err)) + util.ReturnHTTPMessage(w, r, 500, "internalerror", "error deleting vmtemplate") + return + } + + util.ReturnHTTPMessage(w, r, 200, "deleted", "vmtemplate deleted") +} + +func searchForTemplateInRequiredVMs(req map[string]*scheduledeventpb.VMTemplateCountMap, template string) bool { + for _, v := range req { + // k is environment, v is map[string]string + for kk := range v.GetVmTemplateCounts() { + // kk is vmtemplate, vv is count + if kk == template { + return true + } + } + } + return false +} diff --git a/v3/services/vmtemplatesvc/main.go b/v3/services/vmtemplatesvc/main.go new file mode 100644 index 00000000..3bfc4c9c --- /dev/null +++ b/v3/services/vmtemplatesvc/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "sync" + "time" + + "github.com/hobbyfarm/gargantua/v3/pkg/crd" + "github.com/hobbyfarm/gargantua/v3/pkg/microservices" + "github.com/hobbyfarm/gargantua/v3/pkg/signals" + "github.com/hobbyfarm/gargantua/v3/pkg/util" + + vmtemplateservice "github.com/hobbyfarm/gargantua/services/vmtemplatesvc/v3/internal" + hfInformers "github.com/hobbyfarm/gargantua/v3/pkg/client/informers/externalversions" + authnpb "github.com/hobbyfarm/gargantua/v3/protos/authn" + authrpb "github.com/hobbyfarm/gargantua/v3/protos/authr" + scheduledeventpb "github.com/hobbyfarm/gargantua/v3/protos/scheduledevent" + vmpb "github.com/hobbyfarm/gargantua/v3/protos/vm" + vmclaimpb "github.com/hobbyfarm/gargantua/v3/protos/vmclaim" + vmsetpb "github.com/hobbyfarm/gargantua/v3/protos/vmset" + vmtemplatepb "github.com/hobbyfarm/gargantua/v3/protos/vmtemplate" +) + +var ( + serviceConfig *microservices.ServiceConfig +) + +func init() { + serviceConfig = microservices.BuildServiceConfig() +} + +func main() { + stopCh := signals.SetupSignalHandler() + + cfg, hfClient, _ := microservices.BuildClusterConfig(serviceConfig) + + namespace := util.GetReleaseNamespace() + hfInformerFactory := hfInformers.NewSharedInformerFactoryWithOptions(hfClient, time.Second*30, hfInformers.WithNamespace(namespace)) + + crd.InstallCrds(vmtemplateservice.VMTemplateCRDInstaller{}, cfg, "virtual machine template") + + services := []microservices.MicroService{ + microservices.AuthN, + microservices.AuthR, + microservices.ScheduledEvent, + microservices.VM, + microservices.VMClaim, + microservices.VMSet, + } + connections := microservices.EstablishConnections(services, serviceConfig.ClientCert) + for _, conn := range connections { + defer conn.Close() + } + + authnClient := authnpb.NewAuthNClient(connections[microservices.AuthN]) + authrClient := authrpb.NewAuthRClient(connections[microservices.AuthR]) + scheduledEventClient := scheduledeventpb.NewScheduledEventSvcClient(connections[microservices.ScheduledEvent]) + vmClient := vmpb.NewVMSvcClient(connections[microservices.VM]) + vmClaimClient := vmclaimpb.NewVMClaimSvcClient(connections[microservices.VMClaim]) + vmSetClient := vmsetpb.NewVMSetSvcClient(connections[microservices.VMSet]) + + gs := microservices.CreateGRPCServer(serviceConfig.ServerCert.Clone()) + + vs := vmtemplateservice.NewGrpcVMTemplateServer(hfClient, hfInformerFactory) + + vmtemplatepb.RegisterVMTemplateSvcServer(gs, vs) + + var wg sync.WaitGroup + // only add 1 to our wait group since our service should stop (and restart) as soon as one of the go routines terminates + wg.Add(1) + + go func() { + defer wg.Done() + microservices.StartGRPCServer(gs, serviceConfig.EnableReflection) + }() + + go func() { + defer wg.Done() + + vmTemplateServer := vmtemplateservice.NewVirtualMachineTemplateServer( + authnClient, + authrClient, + scheduledEventClient, + vmClient, + vmClaimClient, + vmSetClient, + vs, + ) + microservices.StartAPIServer(vmTemplateServer) + }() + + hfInformerFactory.Start(stopCh) + + wg.Wait() +}