From c50d1dfe880c8a68f06b399e1591fb7c66e1da1d Mon Sep 17 00:00:00 2001 From: Philip Aguilar Bremer Date: Fri, 21 Jun 2024 11:44:29 +0200 Subject: [PATCH 1/2] Change architecture to microservices (#194) * Implement missing OTAC RPCs * Remove TODO Command * Add labels field for otacs. We need this property in the future * Implement missing ac service functions * Refactor gRPC errors * Introduce general proto message definitions * Change proto package name * Add dbconfig proto type definitions * Refactoring * Expose HobbyfarmCRD function * Add crd config for dbconfig service * Add Dockerfile for dbconfig service * Refactoring crd generation * Fix mistake * Remove update of labels and restricted bind value. Since resources contain an owner reference, labels and restricted bind values should not be updated but rather inferred from the resource object's owner reference. * Implement dbconfig service * Minor changes * Add vm claim service * Add vmset service * Add progress service * Remove CRD installation of migrated services * Remove unused function * Add new grpc error helper functions * Fix error and add progress svc go module * Improve error handling for not found errors * Introduce caching for get/list and improve error handling * Implement caching for get/list * Add generic functions for Get and OwnerReferences * log error for unspecified IDs * Use generic getter function Improving code quality... * implement and use util function to delete hf resources further improving code quality ... * Implement generic unmarshall function * Fix integer typing * Add generic function to convert maps of type map[string] int/uint32 * Apply map conversion * Remove redundant imports * Add docker files * Implement internal part of vm template service * Rm CRDs, add generic func for CRD installation The CRDs removed here are migrated towards their respective microservice * Use generic function to generate CRDs * Implement vm service * move labels from util to labels package * Add GrpcBadRequestError * Add .proto definitions for vm service * Implement internal scheduled event service * Update proto definitions, use scheduled event service * Update proto go gen version * Add internal course and scenario service * Update proto definitions * Add internal environment service * Use correct label package and generic func to install CRDs * Use correct labels and generic func to install CRDs * Use correct label package * Use generic function to install CRDs * Add internal session service * Use session client, correct labels and generic CRD installer * Use generic CRD installer * Use correct labels package * Use generic CRD installer * Update to latest proto gen go version * Fix retrieval of setting values * Add new services to go.work * Update proto gen go version * Add missing microservices to MicroService type * Minor fix * Add deletion time stamp * Add deletion time stamp * Update function signatures * Add uid in proto definitions * Add uid to PreparedListSetting * Add uid * Return (list/get) annotations for environments and vms * provide ID to vm service * Add vmclaim controller * Simplify code * remove todo comment * Update proto-gen version * Implement vm controller * Add parameter to optionally pass workqueue directly to controller * Add deletion timestamp for vms * Fix typo * Add util function to add items to workqueue * Add util function to remove finalizers * Add wrapper type for string slices * Add parameter to enable the option updating finalizers on vms * Update error message * Add controller logic for vm sets * Remove old controller logic * Add controller logic to scheduledevent service * Rename scheduled event controller * Use new scheduled event controller logic * Remove old scheduled event controller logic * Add session controller logic to session service * Remove old session controller logic * Implement terraform service * Make GrpcNotFoundError function a generic function * Return NotFoundError if to be deleted item is not found * Add terraform service * Add terraform client to vm svc and its controller * Readd ContainsFinalizer utility function * Add option to update secret name for vm * Update tf service to return resource id after state creation * Fix typo * Add utility function to watch/verify object deletion * Add proto file change to allow vm updates for secret name * Move terraform controller logic into vm controller * Remove old controller logic * Add vm tasks to protobuf specification * change property types * Add vm tasks to scenario service * Add missing route to authn service * Remove old authserver logic * Update package names for protobuf modules * Simplify api server creation for user service * Add function to safely extract grpc error details * Add function to convert []*generalpb.StringMap to []map[string]string * Simplify and improve grpc error handling * Migrate course api server logic * Start api server via course service * Minor fix * Rename rbac import name * Rename function name. Add conversion functions. * Migrate environment api server logic * Start environment api logic in environment service * Migrate progress api server logic * Run go mod tidy * Add comment explaining why progress api server is using progress k8s client directly * Rename imports * move course utility func to util module This is needed because the AppendDynamicScenariosByCategories function is also used inside the scenario service * Improve error handling * Remove redundant return statements * Simplify if expression * Add utility functions to filter for sessions/scheduled events * Change VMTask property name * Add copy function to grpc server * Migrate scenario API server logic * Make struct map conversion generic * Rename function * Add max duration param for grpc OTAC creation func * Migrate and apply scheduled event api server logic * minor refactoring * Rename field name * Change return type * Change return type * Implement the option to update a collection of progress data * Add comment * Migrate session api server logic * Change proto message field name * Run go.mod tidy * Migrate vm claim server logic * Implement vmset api server logic * Refactor wait group logic * Run go.mod tidy * Migrate vm api server logic * Migrate vm template api logic * Refactor shell service * Refactor gargantua main.go and remove legacy code * Add jobs for new services * Run go.mod tidy * Fix index out of bounds error * Bug fixes * Set WorkScheduler in controllers * Fix typos/bugs * Minor refactoring * Minor bug fix * Use fixed version for protoc-gen-go-grpc module * Fix deletion of vm sets for finished scheduled events --- .github/workflows/main.yaml | 72 + generate-protos.sh | 2 +- go.work | 12 + main.go | 269 +--- v3/go.mod | 6 +- v3/go.sum | 518 ++++++ v3/pkg/accesscode/accesscode.go | 185 --- v3/pkg/authserver/authserver.go | 114 -- .../scheduledeventcontroller.go | 658 -------- .../controllers/session/sessioncontroller.go | 332 ---- .../tfpcontroller/tfpcontroller.go | 537 ------- .../vmclaimcontroller/vmclaimcontroller.go | 850 ---------- .../vmsetcontroller/vmsetcontroller.go | 478 ------ v3/pkg/courseclient/courseclient.go | 33 - v3/pkg/courseserver/courseserver.go | 671 -------- v3/pkg/crd/crd.go | 168 +- v3/pkg/environmentserver/environmentserver.go | 451 ------ v3/pkg/errors/errors.go | 109 ++ v3/pkg/labels/labels.go | 28 +- v3/pkg/microservices/controller/controller.go | 2 +- .../controller/delayingWorkqueueController.go | 11 +- .../rateLimitingWorkqueueController.go | 4 +- .../controller/shardedController.go | 20 +- v3/pkg/microservices/microservices.go | 26 +- .../predefinedserviceserver.go | 13 +- v3/pkg/progressserver/progressserver.go | 382 ----- v3/pkg/rbac/auth.go | 36 +- v3/pkg/scenarioclient/scenarioclient.go | 28 - v3/pkg/scenarioserver/scenarioserver.go | 1107 ------------- v3/pkg/scheduledeventserver/scheduledevent.go | 842 ---------- v3/pkg/sessionserver/sessionserver.go | 824 ---------- v3/pkg/setting/util.go | 70 +- v3/pkg/shell/shell.go | 125 +- v3/pkg/util/conversion.go | 57 + v3/pkg/util/delete.go | 67 + v3/pkg/util/filter.go | 80 + v3/pkg/util/finalizer.go | 38 + v3/pkg/util/getter.go | 92 ++ v3/pkg/util/labels.go | 12 - v3/pkg/util/lister.go | 56 + v3/pkg/util/unmarshal.go | 18 + v3/pkg/util/util.go | 162 +- v3/pkg/util/verify.go | 84 + v3/pkg/util/watch.go | 41 + v3/pkg/util/workqueue.go | 21 + v3/pkg/vmclaimserver/vmclaimserver.go | 136 -- v3/pkg/vmclient/vmclient.go | 30 - v3/pkg/vmserver/vmserver.go | 294 ---- v3/pkg/vmsetserver/vmsetserver.go | 123 -- v3/pkg/vmtemplateserver/vmtemplateserver.go | 436 ----- v3/protos/accesscode/accesscode.pb.go | 991 +++++++++++- v3/protos/accesscode/accesscode.proto | 109 +- v3/protos/accesscode/accesscode_grpc.pb.go | 524 +++++- v3/protos/authn/authn.pb.go | 9 +- v3/protos/authn/authn.proto | 2 +- v3/protos/authn/authn_grpc.pb.go | 2 +- v3/protos/authr/authr.pb.go | 9 +- v3/protos/authr/authr.proto | 2 +- v3/protos/authr/authr_grpc.pb.go | 2 +- v3/protos/course/course.pb.go | 670 ++++++++ v3/protos/course/course.proto | 61 + v3/protos/course/course_grpc.pb.go | 296 ++++ v3/protos/dbconfig/dbconfig.pb.go | 585 +++++++ v3/protos/dbconfig/dbconfig.proto | 48 + v3/protos/dbconfig/dbconfig_grpc.pb.go | 296 ++++ v3/protos/environment/environment.pb.go | 705 ++++++++ v3/protos/environment/environment.proto | 59 + v3/protos/environment/environment_grpc.pb.go | 296 ++++ v3/protos/general/general.pb.go | 614 +++++++ v3/protos/general/general.proto | 47 + v3/protos/progress/progress.pb.go | 884 ++++++++++ v3/protos/progress/progress.proto | 76 + v3/protos/progress/progress_grpc.pb.go | 333 ++++ v3/protos/rbac/rbac.pb.go | 341 ++-- v3/protos/rbac/rbac.proto | 24 +- v3/protos/rbac/rbac_grpc.pb.go | 100 +- v3/protos/scenario/scenario.pb.go | 988 ++++++++++++ v3/protos/scenario/scenario.proto | 86 + v3/protos/scenario/scenario_grpc.pb.go | 337 ++++ v3/protos/scheduledevent/scheduledevent.pb.go | 1204 ++++++++++++++ v3/protos/scheduledevent/scheduledevent.proto | 102 ++ .../scheduledevent/scheduledevent_grpc.pb.go | 333 ++++ v3/protos/session/session.pb.go | 816 ++++++++++ v3/protos/session/session.proto | 72 + v3/protos/session/session_grpc.pb.go | 333 ++++ v3/protos/setting/setting.pb.go | 630 ++++---- v3/protos/setting/setting.proto | 44 +- v3/protos/setting/setting_grpc.pb.go | 67 +- v3/protos/terraform/terraform.pb.go | 1426 +++++++++++++++++ v3/protos/terraform/terraform.proto | 116 ++ v3/protos/terraform/terraform_grpc.pb.go | 333 ++++ v3/protos/user/user.pb.go | 297 ++-- v3/protos/user/user.proto | 30 +- v3/protos/user/user_grpc.pb.go | 61 +- v3/protos/vm/vm.pb.go | 1038 ++++++++++++ v3/protos/vm/vm.proto | 92 ++ v3/protos/vm/vm_grpc.pb.go | 333 ++++ v3/protos/vmclaim/virtualmachineclaim.pb.go | 936 +++++++++++ v3/protos/vmclaim/virtualmachineclaim.proto | 77 + .../vmclaim/virtualmachineclaim_grpc.pb.go | 370 +++++ v3/protos/vmset/virtualmachineset.pb.go | 907 +++++++++++ v3/protos/vmset/virtualmachineset.proto | 77 + v3/protos/vmset/virtualmachineset_grpc.pb.go | 370 +++++ v3/protos/vmtemplate/vmtemplate.pb.go | 482 ++++++ v3/protos/vmtemplate/vmtemplate.proto | 42 + v3/protos/vmtemplate/vmtemplate_grpc.pb.go | 296 ++++ v3/services/accesscodesvc/internal/crd.go | 15 +- v3/services/accesscodesvc/internal/grpc.go | 582 ++++++- v3/services/accesscodesvc/main.go | 38 +- v3/services/authnsvc/go.mod | 4 +- v3/services/authnsvc/go.sum | 3 +- v3/services/authnsvc/internal/authnservice.go | 198 ++- v3/services/authnsvc/internal/grpc.go | 56 +- v3/services/authnsvc/internal/server.go | 35 +- v3/services/authnsvc/main.go | 34 +- v3/services/authrsvc/internal/grpc.go | 48 +- v3/services/authrsvc/main.go | 8 +- v3/services/coursesvc/Dockerfile | 22 + v3/services/coursesvc/go.mod | 75 + v3/services/coursesvc/go.sum | 518 ++++++ .../coursesvc/internal/courseservice.go | 486 ++++++ v3/services/coursesvc/internal/crd.go | 21 + v3/services/coursesvc/internal/grpc.go | 267 +++ v3/services/coursesvc/internal/server.go | 52 + v3/services/coursesvc/main.go | 93 ++ v3/services/dbconfigsvc/Dockerfile | 22 + v3/services/dbconfigsvc/go.mod | 75 + v3/services/dbconfigsvc/go.sum | 518 ++++++ v3/services/dbconfigsvc/internal/crd.go | 21 + v3/services/dbconfigsvc/internal/grpc.go | 220 +++ v3/services/dbconfigsvc/main.go | 50 + v3/services/environmentsvc/Dockerfile | 22 + v3/services/environmentsvc/go.mod | 75 + v3/services/environmentsvc/go.sum | 518 ++++++ v3/services/environmentsvc/internal/crd.go | 21 + .../internal/environmentservice.go | 372 +++++ v3/services/environmentsvc/internal/grpc.go | 275 ++++ v3/services/environmentsvc/internal/server.go | 39 + v3/services/environmentsvc/main.go | 81 + v3/services/progresssvc/Dockerfile | 22 + v3/services/progresssvc/go.mod | 75 + v3/services/progresssvc/go.sum | 518 ++++++ v3/services/progresssvc/internal/crd.go | 30 + v3/services/progresssvc/internal/grpc.go | 324 ++++ .../progresssvc/internal/progressservice.go | 398 +++++ v3/services/progresssvc/internal/server.go | 36 + v3/services/progresssvc/main.go | 76 + v3/services/rbacsvc/internal/grpc.go | 36 +- v3/services/rbacsvc/internal/grpc_access.go | 28 +- v3/services/rbacsvc/internal/grpc_rbac.go | 37 +- .../rbacsvc/internal/grpc_rolebindings.go | 189 +-- v3/services/rbacsvc/internal/grpc_roles.go | 181 +-- .../rbacsvc/internal/rbac/rbac_roles.go | 3 +- v3/services/rbacsvc/internal/rolebindings.go | 76 +- v3/services/rbacsvc/internal/roles.go | 76 +- v3/services/rbacsvc/internal/server.go | 10 +- v3/services/rbacsvc/main.go | 16 +- v3/services/scenariosvc/Dockerfile | 22 + v3/services/scenariosvc/go.mod | 75 + v3/services/scenariosvc/go.sum | 518 ++++++ v3/services/scenariosvc/internal/crd.go | 21 + v3/services/scenariosvc/internal/grpc.go | 410 +++++ .../scenariosvc/internal/scenarioservice.go | 810 ++++++++++ v3/services/scenariosvc/internal/server.go | 60 + v3/services/scenariosvc/main.go | 93 ++ v3/services/scheduledeventsvc/Dockerfile | 22 + v3/services/scheduledeventsvc/go.mod | 75 + v3/services/scheduledeventsvc/go.sum | 518 ++++++ .../scheduledeventsvc/internal/controller.go | 508 ++++++ v3/services/scheduledeventsvc/internal/crd.go | 27 + .../scheduledeventsvc/internal/grpc.go | 469 ++++++ .../internal/scheduledeventservice.go | 651 ++++++++ .../scheduledeventsvc/internal/server.go | 61 + v3/services/scheduledeventsvc/main.go | 131 ++ v3/services/sessionsvc/Dockerfile | 22 + v3/services/sessionsvc/go.mod | 75 + v3/services/sessionsvc/go.sum | 518 ++++++ v3/services/sessionsvc/internal/controller.go | 227 +++ v3/services/sessionsvc/internal/crd.go | 29 + v3/services/sessionsvc/internal/grpc.go | 280 ++++ v3/services/sessionsvc/internal/server.go | 60 + .../sessionsvc/internal/sessionservice.go | 700 ++++++++ v3/services/sessionsvc/main.go | 124 ++ v3/services/settingsvc/go.mod | 2 +- v3/services/settingsvc/internal/crd.go | 14 +- v3/services/settingsvc/internal/grpc.go | 313 ++-- v3/services/settingsvc/internal/preinstall.go | 94 +- v3/services/settingsvc/internal/server.go | 10 +- .../settingsvc/internal/settingservice.go | 36 +- v3/services/settingsvc/main.go | 39 +- v3/services/terraformsvc/Dockerfile | 22 + v3/services/terraformsvc/go.mod | 75 + v3/services/terraformsvc/go.sum | 518 ++++++ v3/services/terraformsvc/internal/crd.go | 46 + v3/services/terraformsvc/internal/grpc.go | 376 +++++ v3/services/terraformsvc/main.go | 51 + v3/services/usersvc/internal/crd.go | 12 +- v3/services/usersvc/internal/grpc.go | 392 ++--- v3/services/usersvc/internal/server.go | 26 +- v3/services/usersvc/internal/userservice.go | 64 +- v3/services/usersvc/main.go | 51 +- v3/services/vmclaimsvc/Dockerfile | 22 + v3/services/vmclaimsvc/go.mod | 75 + v3/services/vmclaimsvc/go.sum | 518 ++++++ v3/services/vmclaimsvc/internal/controller.go | 652 ++++++++ v3/services/vmclaimsvc/internal/crd.go | 27 + v3/services/vmclaimsvc/internal/grpc.go | 326 ++++ v3/services/vmclaimsvc/internal/server.go | 38 + .../vmclaimsvc/internal/vmclaimservice.go | 92 ++ v3/services/vmclaimsvc/main.go | 129 ++ v3/services/vmsetsvc/Dockerfile | 22 + v3/services/vmsetsvc/go.mod | 75 + v3/services/vmsetsvc/go.sum | 518 ++++++ v3/services/vmsetsvc/internal/controller.go | 282 ++++ v3/services/vmsetsvc/internal/crd.go | 26 + v3/services/vmsetsvc/internal/grpc.go | 321 ++++ v3/services/vmsetsvc/internal/server.go | 32 + v3/services/vmsetsvc/internal/vmsetservice.go | 99 ++ v3/services/vmsetsvc/main.go | 109 ++ v3/services/vmsvc/Dockerfile | 22 + v3/services/vmsvc/go.mod | 75 + v3/services/vmsvc/go.sum | 518 ++++++ v3/services/vmsvc/internal/controller.go | 468 ++++++ v3/services/vmsvc/internal/crd.go | 28 + v3/services/vmsvc/internal/grpc.go | 380 +++++ v3/services/vmsvc/internal/server.go | 39 + v3/services/vmsvc/internal/vmservice.go | 278 ++++ v3/services/vmsvc/main.go | 114 ++ v3/services/vmtemplatesvc/Dockerfile | 22 + v3/services/vmtemplatesvc/go.mod | 75 + v3/services/vmtemplatesvc/go.sum | 518 ++++++ v3/services/vmtemplatesvc/internal/crd.go | 21 + v3/services/vmtemplatesvc/internal/grpc.go | 197 +++ v3/services/vmtemplatesvc/internal/server.go | 52 + .../internal/vmtemplateservice.go | 371 +++++ v3/services/vmtemplatesvc/main.go | 94 ++ 236 files changed, 40955 insertions(+), 11432 deletions(-) create mode 100644 v3/go.sum delete mode 100644 v3/pkg/accesscode/accesscode.go delete mode 100644 v3/pkg/authserver/authserver.go delete mode 100644 v3/pkg/controllers/scheduledevent/scheduledeventcontroller.go delete mode 100644 v3/pkg/controllers/session/sessioncontroller.go delete mode 100644 v3/pkg/controllers/tfpcontroller/tfpcontroller.go delete mode 100644 v3/pkg/controllers/vmclaimcontroller/vmclaimcontroller.go delete mode 100644 v3/pkg/controllers/vmsetcontroller/vmsetcontroller.go delete mode 100644 v3/pkg/courseclient/courseclient.go delete mode 100644 v3/pkg/courseserver/courseserver.go delete mode 100644 v3/pkg/environmentserver/environmentserver.go delete mode 100644 v3/pkg/progressserver/progressserver.go delete mode 100644 v3/pkg/scenarioclient/scenarioclient.go delete mode 100644 v3/pkg/scenarioserver/scenarioserver.go delete mode 100644 v3/pkg/scheduledeventserver/scheduledevent.go delete mode 100644 v3/pkg/sessionserver/sessionserver.go create mode 100644 v3/pkg/util/conversion.go create mode 100644 v3/pkg/util/delete.go create mode 100644 v3/pkg/util/filter.go create mode 100644 v3/pkg/util/finalizer.go create mode 100644 v3/pkg/util/getter.go delete mode 100644 v3/pkg/util/labels.go create mode 100644 v3/pkg/util/lister.go create mode 100644 v3/pkg/util/unmarshal.go create mode 100644 v3/pkg/util/verify.go create mode 100644 v3/pkg/util/watch.go create mode 100644 v3/pkg/util/workqueue.go delete mode 100644 v3/pkg/vmclaimserver/vmclaimserver.go delete mode 100644 v3/pkg/vmclient/vmclient.go delete mode 100644 v3/pkg/vmserver/vmserver.go delete mode 100644 v3/pkg/vmsetserver/vmsetserver.go delete mode 100644 v3/pkg/vmtemplateserver/vmtemplateserver.go create mode 100644 v3/protos/course/course.pb.go create mode 100644 v3/protos/course/course.proto create mode 100644 v3/protos/course/course_grpc.pb.go create mode 100644 v3/protos/dbconfig/dbconfig.pb.go create mode 100644 v3/protos/dbconfig/dbconfig.proto create mode 100644 v3/protos/dbconfig/dbconfig_grpc.pb.go create mode 100644 v3/protos/environment/environment.pb.go create mode 100644 v3/protos/environment/environment.proto create mode 100644 v3/protos/environment/environment_grpc.pb.go create mode 100644 v3/protos/general/general.pb.go create mode 100644 v3/protos/general/general.proto create mode 100644 v3/protos/progress/progress.pb.go create mode 100644 v3/protos/progress/progress.proto create mode 100644 v3/protos/progress/progress_grpc.pb.go create mode 100644 v3/protos/scenario/scenario.pb.go create mode 100644 v3/protos/scenario/scenario.proto create mode 100644 v3/protos/scenario/scenario_grpc.pb.go create mode 100644 v3/protos/scheduledevent/scheduledevent.pb.go create mode 100644 v3/protos/scheduledevent/scheduledevent.proto create mode 100644 v3/protos/scheduledevent/scheduledevent_grpc.pb.go create mode 100644 v3/protos/session/session.pb.go create mode 100644 v3/protos/session/session.proto create mode 100644 v3/protos/session/session_grpc.pb.go create mode 100644 v3/protos/terraform/terraform.pb.go create mode 100644 v3/protos/terraform/terraform.proto create mode 100644 v3/protos/terraform/terraform_grpc.pb.go create mode 100644 v3/protos/vm/vm.pb.go create mode 100644 v3/protos/vm/vm.proto create mode 100644 v3/protos/vm/vm_grpc.pb.go create mode 100644 v3/protos/vmclaim/virtualmachineclaim.pb.go create mode 100644 v3/protos/vmclaim/virtualmachineclaim.proto create mode 100644 v3/protos/vmclaim/virtualmachineclaim_grpc.pb.go create mode 100644 v3/protos/vmset/virtualmachineset.pb.go create mode 100644 v3/protos/vmset/virtualmachineset.proto create mode 100644 v3/protos/vmset/virtualmachineset_grpc.pb.go create mode 100644 v3/protos/vmtemplate/vmtemplate.pb.go create mode 100644 v3/protos/vmtemplate/vmtemplate.proto create mode 100644 v3/protos/vmtemplate/vmtemplate_grpc.pb.go create mode 100644 v3/services/coursesvc/Dockerfile create mode 100644 v3/services/coursesvc/go.mod create mode 100644 v3/services/coursesvc/go.sum create mode 100644 v3/services/coursesvc/internal/courseservice.go create mode 100644 v3/services/coursesvc/internal/crd.go create mode 100644 v3/services/coursesvc/internal/grpc.go create mode 100644 v3/services/coursesvc/internal/server.go create mode 100644 v3/services/coursesvc/main.go create mode 100644 v3/services/dbconfigsvc/Dockerfile create mode 100644 v3/services/dbconfigsvc/go.mod create mode 100644 v3/services/dbconfigsvc/go.sum create mode 100644 v3/services/dbconfigsvc/internal/crd.go create mode 100644 v3/services/dbconfigsvc/internal/grpc.go create mode 100644 v3/services/dbconfigsvc/main.go create mode 100644 v3/services/environmentsvc/Dockerfile create mode 100644 v3/services/environmentsvc/go.mod create mode 100644 v3/services/environmentsvc/go.sum create mode 100644 v3/services/environmentsvc/internal/crd.go create mode 100644 v3/services/environmentsvc/internal/environmentservice.go create mode 100644 v3/services/environmentsvc/internal/grpc.go create mode 100644 v3/services/environmentsvc/internal/server.go create mode 100644 v3/services/environmentsvc/main.go create mode 100644 v3/services/progresssvc/Dockerfile create mode 100644 v3/services/progresssvc/go.mod create mode 100644 v3/services/progresssvc/go.sum create mode 100644 v3/services/progresssvc/internal/crd.go create mode 100644 v3/services/progresssvc/internal/grpc.go create mode 100644 v3/services/progresssvc/internal/progressservice.go create mode 100644 v3/services/progresssvc/internal/server.go create mode 100644 v3/services/progresssvc/main.go create mode 100644 v3/services/scenariosvc/Dockerfile create mode 100644 v3/services/scenariosvc/go.mod create mode 100644 v3/services/scenariosvc/go.sum create mode 100644 v3/services/scenariosvc/internal/crd.go create mode 100644 v3/services/scenariosvc/internal/grpc.go create mode 100644 v3/services/scenariosvc/internal/scenarioservice.go create mode 100644 v3/services/scenariosvc/internal/server.go create mode 100644 v3/services/scenariosvc/main.go create mode 100644 v3/services/scheduledeventsvc/Dockerfile create mode 100644 v3/services/scheduledeventsvc/go.mod create mode 100644 v3/services/scheduledeventsvc/go.sum create mode 100644 v3/services/scheduledeventsvc/internal/controller.go create mode 100644 v3/services/scheduledeventsvc/internal/crd.go create mode 100644 v3/services/scheduledeventsvc/internal/grpc.go create mode 100644 v3/services/scheduledeventsvc/internal/scheduledeventservice.go create mode 100644 v3/services/scheduledeventsvc/internal/server.go create mode 100644 v3/services/scheduledeventsvc/main.go create mode 100644 v3/services/sessionsvc/Dockerfile create mode 100644 v3/services/sessionsvc/go.mod create mode 100644 v3/services/sessionsvc/go.sum create mode 100644 v3/services/sessionsvc/internal/controller.go create mode 100644 v3/services/sessionsvc/internal/crd.go create mode 100644 v3/services/sessionsvc/internal/grpc.go create mode 100644 v3/services/sessionsvc/internal/server.go create mode 100644 v3/services/sessionsvc/internal/sessionservice.go create mode 100644 v3/services/sessionsvc/main.go create mode 100644 v3/services/terraformsvc/Dockerfile create mode 100644 v3/services/terraformsvc/go.mod create mode 100644 v3/services/terraformsvc/go.sum create mode 100644 v3/services/terraformsvc/internal/crd.go create mode 100644 v3/services/terraformsvc/internal/grpc.go create mode 100644 v3/services/terraformsvc/main.go create mode 100644 v3/services/vmclaimsvc/Dockerfile create mode 100644 v3/services/vmclaimsvc/go.mod create mode 100644 v3/services/vmclaimsvc/go.sum create mode 100644 v3/services/vmclaimsvc/internal/controller.go create mode 100644 v3/services/vmclaimsvc/internal/crd.go create mode 100644 v3/services/vmclaimsvc/internal/grpc.go create mode 100644 v3/services/vmclaimsvc/internal/server.go create mode 100644 v3/services/vmclaimsvc/internal/vmclaimservice.go create mode 100644 v3/services/vmclaimsvc/main.go create mode 100644 v3/services/vmsetsvc/Dockerfile create mode 100644 v3/services/vmsetsvc/go.mod create mode 100644 v3/services/vmsetsvc/go.sum create mode 100644 v3/services/vmsetsvc/internal/controller.go create mode 100644 v3/services/vmsetsvc/internal/crd.go create mode 100644 v3/services/vmsetsvc/internal/grpc.go create mode 100644 v3/services/vmsetsvc/internal/server.go create mode 100644 v3/services/vmsetsvc/internal/vmsetservice.go create mode 100644 v3/services/vmsetsvc/main.go create mode 100644 v3/services/vmsvc/Dockerfile create mode 100644 v3/services/vmsvc/go.mod create mode 100644 v3/services/vmsvc/go.sum create mode 100644 v3/services/vmsvc/internal/controller.go create mode 100644 v3/services/vmsvc/internal/crd.go create mode 100644 v3/services/vmsvc/internal/grpc.go create mode 100644 v3/services/vmsvc/internal/server.go create mode 100644 v3/services/vmsvc/internal/vmservice.go create mode 100644 v3/services/vmsvc/main.go create mode 100644 v3/services/vmtemplatesvc/Dockerfile create mode 100644 v3/services/vmtemplatesvc/go.mod create mode 100644 v3/services/vmtemplatesvc/go.sum create mode 100644 v3/services/vmtemplatesvc/internal/crd.go create mode 100644 v3/services/vmtemplatesvc/internal/grpc.go create mode 100644 v3/services/vmtemplatesvc/internal/server.go create mode 100644 v3/services/vmtemplatesvc/internal/vmtemplateservice.go create mode 100644 v3/services/vmtemplatesvc/main.go 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 d9847ab5..d548b852 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 } @@ -62,33 +67,25 @@ func emailIndexer(obj interface{}) ([]string, error) { return []string{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{} @@ -107,149 +104,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() != "" { @@ -271,53 +226,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 { @@ -326,38 +269,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 { @@ -378,7 +309,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 }) @@ -389,71 +320,55 @@ 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() } obj, err := u.userIndexer.ByIndex(emailIndex, gur.GetEmail()) if err != nil { - newErr := status.Newf( + return &userpb.User{}, hferrors.GrpcError( codes.Internal, "error while retrieving user by e-mail: %s with error: %v", + 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", + 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", + 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, @@ -462,111 +377,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() +} From beac8f721a7b70f9c4bae3a5124f9cee18b5f57c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Gerrit=20G=C3=B6bel?= <86782124+jggoebel@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:13:30 +0200 Subject: [PATCH 2/2] Index users by lowercase email instead of case-senstive (#193) --- v3/services/usersvc/internal/grpc.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/v3/services/usersvc/internal/grpc.go b/v3/services/usersvc/internal/grpc.go index d548b852..c24b6c01 100644 --- a/v3/services/usersvc/internal/grpc.go +++ b/v3/services/usersvc/internal/grpc.go @@ -59,12 +59,13 @@ func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfIn }, nil } +// Index user by lowercase Email func emailIndexer(obj interface{}) ([]string, error) { user, ok := obj.(*hfv2.User) if !ok { return []string{}, nil } - return []string{user.Spec.Email}, nil + return []string{strings.ToLower(user.Spec.Email)}, nil } func (u *GrpcUserServer) CreateUser(ctx context.Context, cur *userpb.CreateUserRequest) (*generalpb.ResourceId, error) { @@ -337,7 +338,9 @@ func (u *GrpcUserServer) GetUserByEmail(ctx context.Context, gur *userpb.GetUser ) } - obj, err := u.userIndexer.ByIndex(emailIndex, gur.GetEmail()) + userMail := strings.ToLower(gur.GetEmail()) + + obj, err := u.userIndexer.ByIndex(emailIndex, userMail) if err != nil { return &userpb.User{}, hferrors.GrpcError( codes.Internal,