From 37b6191b94e5bccd510f02086fee199ff83fa460 Mon Sep 17 00:00:00 2001 From: Kim Jun Young Date: Tue, 31 Mar 2026 13:40:46 +0900 Subject: [PATCH 1/3] feat: add container provisioner grpc client --- .env.example | 2 + Makefile | 33 + README.md | 25 + buf.gen.yaml | 8 + buf.lock | 2 + cmd/server/main.go | 15 +- codecov.yaml | 3 +- go.mod | 6 +- go.sum | 6 + internal/config/config.go | 69 +- internal/gen/stack/v1/stack.pb.go | 1761 +++++++++++++++++++++ internal/gen/stack/v1/stack_grpc.pb.go | 425 +++++ internal/http/handlers/testenv_test.go | 2 +- internal/http/integration/admin_test.go | 4 +- internal/http/integration/testenv_test.go | 2 +- internal/stack/grpc_client.go | 236 +++ 16 files changed, 2565 insertions(+), 34 deletions(-) create mode 100644 Makefile create mode 100644 buf.gen.yaml create mode 100644 buf.lock create mode 100644 internal/gen/stack/v1/stack.pb.go create mode 100644 internal/gen/stack/v1/stack_grpc.pb.go create mode 100644 internal/stack/grpc_client.go diff --git a/.env.example b/.env.example index 00b9ac8..5323b78 100644 --- a/.env.example +++ b/.env.example @@ -45,6 +45,8 @@ STACKS_ENABLED=true STACKS_MAX_SCOPE=team STACKS_MAX_PER=3 STACKS_PROVISIONER_BASE_URL=http://localhost:8081 +STACKS_PROVISIONER_USE_GRPC=false +STACKS_PROVISIONER_GRPC_ADDR=localhost:9090 STACKS_PROVISIONER_API_KEY=change-me STACKS_PROVISIONER_TIMEOUT=5s STACKS_CREATE_WINDOW=1m diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eea0ec7 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +SHELL := /bin/bash + +GO ?= go +BUF ?= buf +BUF_VERSION ?= v1.66.1 +BUF_MODULE ?= buf.build/smctf/container-provisioner + +.PHONY: all fmt vet lint buf-install buf-lint buf-generate test build + +all: buf-lint buf-generate test build + +fmt: + $(GO) fmt ./... + +vet: + $(GO) vet ./... + +lint: buf-lint vet + +buf-install: + $(GO) install github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION) + +buf-lint: + $(BUF) lint $(BUF_MODULE) + +buf-generate: + $(BUF) generate $(BUF_MODULE) --template buf.gen.yaml + +test: + $(GO) test ./... + +build: + $(GO) build ./cmd/server diff --git a/README.md b/README.md index 9246d67..29db515 100644 --- a/README.md +++ b/README.md @@ -173,8 +173,33 @@ STACKS_ENABLED=true STACKS_MAX_SCOPE=team STACKS_MAX_PER=3 STACKS_PROVISIONER_BASE_URL=http://localhost:8081 +STACKS_PROVISIONER_USE_GRPC=false +STACKS_PROVISIONER_GRPC_ADDR=localhost:9090 STACKS_PROVISIONER_API_KEY=change-me STACKS_PROVISIONER_TIMEOUT=5s + +## Buf / BSR (container-provisioner proto) + +This repo consumes the container-provisioner proto via Buf Schema Registry (BSR). + +Setup: + +```bash +make buf-install +buf registry login +``` + +Generate code: + +```bash +make buf-generate +``` + +Module reference is in `buf.gen.yaml`. You can also override via: + +```bash +make buf-generate BUF_MODULE=buf.build//container-provisioner +``` STACKS_CREATE_WINDOW=1m STACKS_CREATE_MAX=1 diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..3ae24ae --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,8 @@ +version: v1 +plugins: + - plugin: buf.build/protocolbuffers/go + out: internal/gen + opt: paths=source_relative + - plugin: buf.build/grpc/go + out: internal/gen + opt: paths=source_relative diff --git a/buf.lock b/buf.lock new file mode 100644 index 0000000..4f98143 --- /dev/null +++ b/buf.lock @@ -0,0 +1,2 @@ +# Generated by buf. DO NOT EDIT. +version: v2 diff --git a/cmd/server/main.go b/cmd/server/main.go index 0278403..e2a03bc 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -103,7 +103,20 @@ func main() { teamSvc := service.NewTeamService(teamRepo, divisionRepo) ctfSvc := service.NewCTFService(cfg, challengeRepo, submissionRepo, redisClient, fileStore) appConfigSvc := service.NewAppConfigService(appConfigRepo, redisClient, cfg.Cache.AppConfigTTL) - stackClient := stack.NewClient(cfg.Stack.ProvisionerBaseURL, cfg.Stack.ProvisionerAPIKey, cfg.Stack.ProvisionerTimeout) + + var stackClient stack.API + if cfg.Stack.ProvisionerUseGRPC { + client, err := stack.NewGRPCClient(cfg.Stack.ProvisionerGRPCAddr, cfg.Stack.ProvisionerAPIKey, cfg.Stack.ProvisionerTimeout) + if err != nil { + logger.Error("grpc stack client init error", slog.Any("error", err)) + os.Exit(1) + } + + stackClient = client + } else { + stackClient = stack.NewClient(cfg.Stack.ProvisionerBaseURL, cfg.Stack.ProvisionerAPIKey, cfg.Stack.ProvisionerTimeout) + } + stackSvc := service.NewStackService(cfg.Stack, stackRepo, challengeRepo, submissionRepo, stackClient, redisClient) bootstrap.BootstrapAdmin(ctx, cfg, database, userRepo, teamRepo, divisionRepo, logger) diff --git a/codecov.yaml b/codecov.yaml index e38a660..3baafd8 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -23,5 +23,6 @@ ignore: - "migrations/**" - "**/*.sql" - "internal/storage/s3.go" # S3 storage is production only code. instead, we test mock storage. - - "internal/stack/client.go" # Container Provisioner client is production only code. instead, we test mock client. + - "internal/stack/client.go" # Container Provisioner HTTP client is production only code. instead, we test mock client. + - "internal/stack/grpc_client.go" # Container Provisioner gRPC client is production only code. instead, we test mock client. - "internal/http/handlers/types.go" # only type definitions and constructors. diff --git a/go.mod b/go.mod index a8dd4e2..abaa174 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,8 @@ require ( github.com/uptrace/bun/driver/pgdriver v1.2.16 github.com/uptrace/bun/extra/bundebug v1.2.16 golang.org/x/crypto v0.47.0 + google.golang.org/grpc v1.75.1 + google.golang.org/protobuf v1.36.10 ) require ( @@ -119,7 +121,7 @@ require ( go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -127,7 +129,7 @@ require ( golang.org/x/net v0.48.0 // indirect golang.org/x/sys v0.40.0 // indirect golang.org/x/text v0.33.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index bdedad2..8da0e66 100644 --- a/go.sum +++ b/go.sum @@ -118,6 +118,8 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -265,6 +267,8 @@ go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= @@ -297,6 +301,8 @@ golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= diff --git a/internal/config/config.go b/internal/config/config.go index efb2f7a..b7e888f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -90,14 +90,16 @@ type S3Config struct { } type StackConfig struct { - Enabled bool - MaxScope string - MaxPer int - ProvisionerBaseURL string - ProvisionerAPIKey string - ProvisionerTimeout time.Duration - CreateWindow time.Duration - CreateMax int + Enabled bool + MaxScope string + MaxPer int + ProvisionerBaseURL string + ProvisionerGRPCAddr string + ProvisionerUseGRPC bool + ProvisionerAPIKey string + ProvisionerTimeout time.Duration + CreateWindow time.Duration + CreateMax int } type BootstrapConfig struct { @@ -240,6 +242,13 @@ func Load() (Config, error) { errs = append(errs, err) } + stackUseGRPC, err := getEnvBool("STACKS_PROVISIONER_USE_GRPC", false) + if err != nil { + errs = append(errs, err) + } + + stackGRPCAddr := getEnv("STACKS_PROVISIONER_GRPC_ADDR", "localhost:9090") + stackCreateWindow, err := getDuration("STACKS_CREATE_WINDOW", time.Minute) if err != nil { errs = append(errs, err) @@ -317,14 +326,16 @@ func Load() (Config, error) { PresignTTL: s3PresignTTL, }, Stack: StackConfig{ - Enabled: stackEnabled, - MaxScope: stackMaxScope, - MaxPer: stackMaxPer, - ProvisionerBaseURL: getEnv("STACKS_PROVISIONER_BASE_URL", "http://localhost:8081"), - ProvisionerAPIKey: getEnv("STACKS_PROVISIONER_API_KEY", ""), - ProvisionerTimeout: stackTimeout, - CreateWindow: stackCreateWindow, - CreateMax: stackCreateMax, + Enabled: stackEnabled, + MaxScope: stackMaxScope, + MaxPer: stackMaxPer, + ProvisionerBaseURL: getEnv("STACKS_PROVISIONER_BASE_URL", "http://localhost:8081"), + ProvisionerGRPCAddr: stackGRPCAddr, + ProvisionerUseGRPC: stackUseGRPC, + ProvisionerAPIKey: getEnv("STACKS_PROVISIONER_API_KEY", ""), + ProvisionerTimeout: stackTimeout, + CreateWindow: stackCreateWindow, + CreateMax: stackCreateMax, }, Bootstrap: BootstrapConfig{ AdminTeamEnabled: bootstrapAdminTeamEnabled, @@ -486,8 +497,12 @@ func validateConfig(cfg Config) error { if cfg.Stack.MaxScope != "user" && cfg.Stack.MaxScope != "team" { errs = append(errs, errors.New("STACKS_MAX_SCOPE must be user or team")) } - if cfg.Stack.ProvisionerBaseURL == "" { - errs = append(errs, errors.New("STACKS_PROVISIONER_BASE_URL must not be empty")) + if cfg.Stack.ProvisionerUseGRPC { + if cfg.Stack.ProvisionerGRPCAddr == "" { + errs = append(errs, errors.New("STACKS_PROVISIONER_GRPC_ADDR must not be empty when STACKS_PROVISIONER_USE_GRPC=true")) + } + } else if cfg.Stack.ProvisionerBaseURL == "" { + errs = append(errs, errors.New("STACKS_PROVISIONER_BASE_URL must not be empty when STACKS_PROVISIONER_USE_GRPC=false")) } if cfg.Stack.ProvisionerTimeout <= 0 { errs = append(errs, errors.New("STACKS_PROVISIONER_TIMEOUT must be positive")) @@ -614,14 +629,16 @@ func FormatForLog(cfg Config) map[string]any { "presign_ttl": seconds(cfg.S3.PresignTTL), }, "stack": map[string]any{ - "enabled": cfg.Stack.Enabled, - "max_scope": cfg.Stack.MaxScope, - "max_per": cfg.Stack.MaxPer, - "provisioner_base_url": cfg.Stack.ProvisionerBaseURL, - "provisioner_api_key": cfg.Stack.ProvisionerAPIKey, - "provisioner_timeout": seconds(cfg.Stack.ProvisionerTimeout), - "create_window": seconds(cfg.Stack.CreateWindow), - "create_max": cfg.Stack.CreateMax, + "enabled": cfg.Stack.Enabled, + "max_scope": cfg.Stack.MaxScope, + "max_per": cfg.Stack.MaxPer, + "provisioner_base_url": cfg.Stack.ProvisionerBaseURL, + "provisioner_grpc_addr": cfg.Stack.ProvisionerGRPCAddr, + "provisioner_use_grpc": cfg.Stack.ProvisionerUseGRPC, + "provisioner_api_key": cfg.Stack.ProvisionerAPIKey, + "provisioner_timeout": seconds(cfg.Stack.ProvisionerTimeout), + "create_window": seconds(cfg.Stack.CreateWindow), + "create_max": cfg.Stack.CreateMax, }, "bootstrap": map[string]any{ "admin_team_enabled": cfg.Bootstrap.AdminTeamEnabled, diff --git a/internal/gen/stack/v1/stack.pb.go b/internal/gen/stack/v1/stack.pb.go new file mode 100644 index 0000000..63f8f3b --- /dev/null +++ b/internal/gen/stack/v1/stack.pb.go @@ -0,0 +1,1761 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: stack/v1/stack.proto + +package stackv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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 Status int32 + +const ( + Status_STATUS_UNSPECIFIED Status = 0 + Status_STATUS_CREATING Status = 1 + Status_STATUS_RUNNING Status = 2 + Status_STATUS_STOPPED Status = 3 + Status_STATUS_FAILED Status = 4 + Status_STATUS_NODE_DELETED Status = 5 +) + +// Enum value maps for Status. +var ( + Status_name = map[int32]string{ + 0: "STATUS_UNSPECIFIED", + 1: "STATUS_CREATING", + 2: "STATUS_RUNNING", + 3: "STATUS_STOPPED", + 4: "STATUS_FAILED", + 5: "STATUS_NODE_DELETED", + } + Status_value = map[string]int32{ + "STATUS_UNSPECIFIED": 0, + "STATUS_CREATING": 1, + "STATUS_RUNNING": 2, + "STATUS_STOPPED": 3, + "STATUS_FAILED": 4, + "STATUS_NODE_DELETED": 5, + } +) + +func (x Status) Enum() *Status { + p := new(Status) + *p = x + return p +} + +func (x Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Status) Descriptor() protoreflect.EnumDescriptor { + return file_stack_v1_stack_proto_enumTypes[0].Descriptor() +} + +func (Status) Type() protoreflect.EnumType { + return &file_stack_v1_stack_proto_enumTypes[0] +} + +func (x Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Status.Descriptor instead. +func (Status) EnumDescriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{0} +} + +type JobStatus int32 + +const ( + JobStatus_JOB_STATUS_UNSPECIFIED JobStatus = 0 + JobStatus_JOB_STATUS_QUEUED JobStatus = 1 + JobStatus_JOB_STATUS_RUNNING JobStatus = 2 + JobStatus_JOB_STATUS_COMPLETED JobStatus = 3 + JobStatus_JOB_STATUS_FAILED JobStatus = 4 +) + +// Enum value maps for JobStatus. +var ( + JobStatus_name = map[int32]string{ + 0: "JOB_STATUS_UNSPECIFIED", + 1: "JOB_STATUS_QUEUED", + 2: "JOB_STATUS_RUNNING", + 3: "JOB_STATUS_COMPLETED", + 4: "JOB_STATUS_FAILED", + } + JobStatus_value = map[string]int32{ + "JOB_STATUS_UNSPECIFIED": 0, + "JOB_STATUS_QUEUED": 1, + "JOB_STATUS_RUNNING": 2, + "JOB_STATUS_COMPLETED": 3, + "JOB_STATUS_FAILED": 4, + } +) + +func (x JobStatus) Enum() *JobStatus { + p := new(JobStatus) + *p = x + return p +} + +func (x JobStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (JobStatus) Descriptor() protoreflect.EnumDescriptor { + return file_stack_v1_stack_proto_enumTypes[1].Descriptor() +} + +func (JobStatus) Type() protoreflect.EnumType { + return &file_stack_v1_stack_proto_enumTypes[1] +} + +func (x JobStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use JobStatus.Descriptor instead. +func (JobStatus) EnumDescriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{1} +} + +type HealthzRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HealthzRequest) Reset() { + *x = HealthzRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HealthzRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthzRequest) ProtoMessage() {} + +func (x *HealthzRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthzRequest.ProtoReflect.Descriptor instead. +func (*HealthzRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{0} +} + +type HealthzResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HealthzResponse) Reset() { + *x = HealthzResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HealthzResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthzResponse) ProtoMessage() {} + +func (x *HealthzResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthzResponse.ProtoReflect.Descriptor instead. +func (*HealthzResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{1} +} + +func (x *HealthzResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type CreateStackRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PodSpec string `protobuf:"bytes,1,opt,name=pod_spec,json=podSpec,proto3" json:"pod_spec,omitempty"` + TargetPorts []*PortSpec `protobuf:"bytes,2,rep,name=target_ports,json=targetPorts,proto3" json:"target_ports,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateStackRequest) Reset() { + *x = CreateStackRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateStackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateStackRequest) ProtoMessage() {} + +func (x *CreateStackRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateStackRequest.ProtoReflect.Descriptor instead. +func (*CreateStackRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateStackRequest) GetPodSpec() string { + if x != nil { + return x.PodSpec + } + return "" +} + +func (x *CreateStackRequest) GetTargetPorts() []*PortSpec { + if x != nil { + return x.TargetPorts + } + return nil +} + +type CreateStackResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stack *Stack `protobuf:"bytes,1,opt,name=stack,proto3" json:"stack,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateStackResponse) Reset() { + *x = CreateStackResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateStackResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateStackResponse) ProtoMessage() {} + +func (x *CreateStackResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateStackResponse.ProtoReflect.Descriptor instead. +func (*CreateStackResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateStackResponse) GetStack() *Stack { + if x != nil { + return x.Stack + } + return nil +} + +type GetStackRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStackRequest) Reset() { + *x = GetStackRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStackRequest) ProtoMessage() {} + +func (x *GetStackRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStackRequest.ProtoReflect.Descriptor instead. +func (*GetStackRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{4} +} + +func (x *GetStackRequest) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +type GetStackResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stack *Stack `protobuf:"bytes,1,opt,name=stack,proto3" json:"stack,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStackResponse) Reset() { + *x = GetStackResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStackResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStackResponse) ProtoMessage() {} + +func (x *GetStackResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStackResponse.ProtoReflect.Descriptor instead. +func (*GetStackResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{5} +} + +func (x *GetStackResponse) GetStack() *Stack { + if x != nil { + return x.Stack + } + return nil +} + +type GetStackStatusSummaryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStackStatusSummaryRequest) Reset() { + *x = GetStackStatusSummaryRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStackStatusSummaryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStackStatusSummaryRequest) ProtoMessage() {} + +func (x *GetStackStatusSummaryRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStackStatusSummaryRequest.ProtoReflect.Descriptor instead. +func (*GetStackStatusSummaryRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{6} +} + +func (x *GetStackStatusSummaryRequest) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +type GetStackStatusSummaryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Summary *StackStatusSummary `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStackStatusSummaryResponse) Reset() { + *x = GetStackStatusSummaryResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStackStatusSummaryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStackStatusSummaryResponse) ProtoMessage() {} + +func (x *GetStackStatusSummaryResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStackStatusSummaryResponse.ProtoReflect.Descriptor instead. +func (*GetStackStatusSummaryResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{7} +} + +func (x *GetStackStatusSummaryResponse) GetSummary() *StackStatusSummary { + if x != nil { + return x.Summary + } + return nil +} + +type DeleteStackRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteStackRequest) Reset() { + *x = DeleteStackRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteStackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteStackRequest) ProtoMessage() {} + +func (x *DeleteStackRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteStackRequest.ProtoReflect.Descriptor instead. +func (*DeleteStackRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteStackRequest) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +type DeleteStackResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"` + StackId string `protobuf:"bytes,2,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteStackResponse) Reset() { + *x = DeleteStackResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteStackResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteStackResponse) ProtoMessage() {} + +func (x *DeleteStackResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteStackResponse.ProtoReflect.Descriptor instead. +func (*DeleteStackResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteStackResponse) GetDeleted() bool { + if x != nil { + return x.Deleted + } + return false +} + +func (x *DeleteStackResponse) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +type ListStacksRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListStacksRequest) Reset() { + *x = ListStacksRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListStacksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListStacksRequest) ProtoMessage() {} + +func (x *ListStacksRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListStacksRequest.ProtoReflect.Descriptor instead. +func (*ListStacksRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{10} +} + +type ListStacksResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stacks []*Stack `protobuf:"bytes,1,rep,name=stacks,proto3" json:"stacks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListStacksResponse) Reset() { + *x = ListStacksResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListStacksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListStacksResponse) ProtoMessage() {} + +func (x *ListStacksResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListStacksResponse.ProtoReflect.Descriptor instead. +func (*ListStacksResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{11} +} + +func (x *ListStacksResponse) GetStacks() []*Stack { + if x != nil { + return x.Stacks + } + return nil +} + +type CreateBatchDeleteJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackIds []string `protobuf:"bytes,1,rep,name=stack_ids,json=stackIds,proto3" json:"stack_ids,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateBatchDeleteJobRequest) Reset() { + *x = CreateBatchDeleteJobRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateBatchDeleteJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateBatchDeleteJobRequest) ProtoMessage() {} + +func (x *CreateBatchDeleteJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateBatchDeleteJobRequest.ProtoReflect.Descriptor instead. +func (*CreateBatchDeleteJobRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{12} +} + +func (x *CreateBatchDeleteJobRequest) GetStackIds() []string { + if x != nil { + return x.StackIds + } + return nil +} + +type CreateBatchDeleteJobResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateBatchDeleteJobResponse) Reset() { + *x = CreateBatchDeleteJobResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateBatchDeleteJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateBatchDeleteJobResponse) ProtoMessage() {} + +func (x *CreateBatchDeleteJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateBatchDeleteJobResponse.ProtoReflect.Descriptor instead. +func (*CreateBatchDeleteJobResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{13} +} + +func (x *CreateBatchDeleteJobResponse) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +type GetBatchDeleteJobRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetBatchDeleteJobRequest) Reset() { + *x = GetBatchDeleteJobRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetBatchDeleteJobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBatchDeleteJobRequest) ProtoMessage() {} + +func (x *GetBatchDeleteJobRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBatchDeleteJobRequest.ProtoReflect.Descriptor instead. +func (*GetBatchDeleteJobRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{14} +} + +func (x *GetBatchDeleteJobRequest) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +type GetBatchDeleteJobResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Job *BatchDeleteJob `protobuf:"bytes,1,opt,name=job,proto3" json:"job,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetBatchDeleteJobResponse) Reset() { + *x = GetBatchDeleteJobResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetBatchDeleteJobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBatchDeleteJobResponse) ProtoMessage() {} + +func (x *GetBatchDeleteJobResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBatchDeleteJobResponse.ProtoReflect.Descriptor instead. +func (*GetBatchDeleteJobResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBatchDeleteJobResponse) GetJob() *BatchDeleteJob { + if x != nil { + return x.Job + } + return nil +} + +type GetStatsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStatsRequest) Reset() { + *x = GetStatsRequest{} + mi := &file_stack_v1_stack_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStatsRequest) ProtoMessage() {} + +func (x *GetStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStatsRequest.ProtoReflect.Descriptor instead. +func (*GetStatsRequest) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{16} +} + +type GetStatsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stats *Stats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStatsResponse) Reset() { + *x = GetStatsResponse{} + mi := &file_stack_v1_stack_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStatsResponse) ProtoMessage() {} + +func (x *GetStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStatsResponse.ProtoReflect.Descriptor instead. +func (*GetStatsResponse) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{17} +} + +func (x *GetStatsResponse) GetStats() *Stats { + if x != nil { + return x.Stats + } + return nil +} + +type Stats struct { + state protoimpl.MessageState `protogen:"open.v1"` + TotalStacks int32 `protobuf:"varint,1,opt,name=total_stacks,json=totalStacks,proto3" json:"total_stacks,omitempty"` + ActiveStacks int32 `protobuf:"varint,2,opt,name=active_stacks,json=activeStacks,proto3" json:"active_stacks,omitempty"` + NodeDistribution map[string]int32 `protobuf:"bytes,3,rep,name=node_distribution,json=nodeDistribution,proto3" json:"node_distribution,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + UsedNodePorts int32 `protobuf:"varint,4,opt,name=used_node_ports,json=usedNodePorts,proto3" json:"used_node_ports,omitempty"` + ReservedCpuMilli int64 `protobuf:"varint,5,opt,name=reserved_cpu_milli,json=reservedCpuMilli,proto3" json:"reserved_cpu_milli,omitempty"` + ReservedMemoryBytes int64 `protobuf:"varint,6,opt,name=reserved_memory_bytes,json=reservedMemoryBytes,proto3" json:"reserved_memory_bytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Stats) Reset() { + *x = Stats{} + mi := &file_stack_v1_stack_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Stats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Stats) ProtoMessage() {} + +func (x *Stats) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Stats.ProtoReflect.Descriptor instead. +func (*Stats) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{18} +} + +func (x *Stats) GetTotalStacks() int32 { + if x != nil { + return x.TotalStacks + } + return 0 +} + +func (x *Stats) GetActiveStacks() int32 { + if x != nil { + return x.ActiveStacks + } + return 0 +} + +func (x *Stats) GetNodeDistribution() map[string]int32 { + if x != nil { + return x.NodeDistribution + } + return nil +} + +func (x *Stats) GetUsedNodePorts() int32 { + if x != nil { + return x.UsedNodePorts + } + return 0 +} + +func (x *Stats) GetReservedCpuMilli() int64 { + if x != nil { + return x.ReservedCpuMilli + } + return 0 +} + +func (x *Stats) GetReservedMemoryBytes() int64 { + if x != nil { + return x.ReservedMemoryBytes + } + return 0 +} + +type Stack struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + PodId string `protobuf:"bytes,2,opt,name=pod_id,json=podId,proto3" json:"pod_id,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + NodeId string `protobuf:"bytes,4,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + NodePublicIp *string `protobuf:"bytes,5,opt,name=node_public_ip,json=nodePublicIp,proto3,oneof" json:"node_public_ip,omitempty"` + PodSpec string `protobuf:"bytes,6,opt,name=pod_spec,json=podSpec,proto3" json:"pod_spec,omitempty"` + Ports []*PortMapping `protobuf:"bytes,7,rep,name=ports,proto3" json:"ports,omitempty"` + ServiceName string `protobuf:"bytes,8,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + Status Status `protobuf:"varint,9,opt,name=status,proto3,enum=stack.v1.Status" json:"status,omitempty"` + TtlExpiresAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=ttl_expires_at,json=ttlExpiresAt,proto3" json:"ttl_expires_at,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + RequestedCpuMilli int64 `protobuf:"varint,13,opt,name=requested_cpu_milli,json=requestedCpuMilli,proto3" json:"requested_cpu_milli,omitempty"` + RequestedMemoryBytes int64 `protobuf:"varint,14,opt,name=requested_memory_bytes,json=requestedMemoryBytes,proto3" json:"requested_memory_bytes,omitempty"` + TargetPorts []*PortSpec `protobuf:"bytes,15,rep,name=target_ports,json=targetPorts,proto3" json:"target_ports,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Stack) Reset() { + *x = Stack{} + mi := &file_stack_v1_stack_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Stack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Stack) ProtoMessage() {} + +func (x *Stack) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Stack.ProtoReflect.Descriptor instead. +func (*Stack) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{19} +} + +func (x *Stack) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +func (x *Stack) GetPodId() string { + if x != nil { + return x.PodId + } + return "" +} + +func (x *Stack) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *Stack) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *Stack) GetNodePublicIp() string { + if x != nil && x.NodePublicIp != nil { + return *x.NodePublicIp + } + return "" +} + +func (x *Stack) GetPodSpec() string { + if x != nil { + return x.PodSpec + } + return "" +} + +func (x *Stack) GetPorts() []*PortMapping { + if x != nil { + return x.Ports + } + return nil +} + +func (x *Stack) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *Stack) GetStatus() Status { + if x != nil { + return x.Status + } + return Status_STATUS_UNSPECIFIED +} + +func (x *Stack) GetTtlExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.TtlExpiresAt + } + return nil +} + +func (x *Stack) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Stack) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Stack) GetRequestedCpuMilli() int64 { + if x != nil { + return x.RequestedCpuMilli + } + return 0 +} + +func (x *Stack) GetRequestedMemoryBytes() int64 { + if x != nil { + return x.RequestedMemoryBytes + } + return 0 +} + +func (x *Stack) GetTargetPorts() []*PortSpec { + if x != nil { + return x.TargetPorts + } + return nil +} + +type StackStatusSummary struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + Status Status `protobuf:"varint,2,opt,name=status,proto3,enum=stack.v1.Status" json:"status,omitempty"` + Ttl *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=ttl,proto3" json:"ttl,omitempty"` + Ports []*PortMapping `protobuf:"bytes,4,rep,name=ports,proto3" json:"ports,omitempty"` + NodePublicIp *string `protobuf:"bytes,5,opt,name=node_public_ip,json=nodePublicIp,proto3,oneof" json:"node_public_ip,omitempty"` + TargetPorts []*PortSpec `protobuf:"bytes,6,rep,name=target_ports,json=targetPorts,proto3" json:"target_ports,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackStatusSummary) Reset() { + *x = StackStatusSummary{} + mi := &file_stack_v1_stack_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackStatusSummary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackStatusSummary) ProtoMessage() {} + +func (x *StackStatusSummary) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackStatusSummary.ProtoReflect.Descriptor instead. +func (*StackStatusSummary) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{20} +} + +func (x *StackStatusSummary) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +func (x *StackStatusSummary) GetStatus() Status { + if x != nil { + return x.Status + } + return Status_STATUS_UNSPECIFIED +} + +func (x *StackStatusSummary) GetTtl() *timestamppb.Timestamp { + if x != nil { + return x.Ttl + } + return nil +} + +func (x *StackStatusSummary) GetPorts() []*PortMapping { + if x != nil { + return x.Ports + } + return nil +} + +func (x *StackStatusSummary) GetNodePublicIp() string { + if x != nil && x.NodePublicIp != nil { + return *x.NodePublicIp + } + return "" +} + +func (x *StackStatusSummary) GetTargetPorts() []*PortSpec { + if x != nil { + return x.TargetPorts + } + return nil +} + +type PortSpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + ContainerPort int32 `protobuf:"varint,1,opt,name=container_port,json=containerPort,proto3" json:"container_port,omitempty"` + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PortSpec) Reset() { + *x = PortSpec{} + mi := &file_stack_v1_stack_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PortSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PortSpec) ProtoMessage() {} + +func (x *PortSpec) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PortSpec.ProtoReflect.Descriptor instead. +func (*PortSpec) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{21} +} + +func (x *PortSpec) GetContainerPort() int32 { + if x != nil { + return x.ContainerPort + } + return 0 +} + +func (x *PortSpec) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +type PortMapping struct { + state protoimpl.MessageState `protogen:"open.v1"` + ContainerPort int32 `protobuf:"varint,1,opt,name=container_port,json=containerPort,proto3" json:"container_port,omitempty"` + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + NodePort int32 `protobuf:"varint,3,opt,name=node_port,json=nodePort,proto3" json:"node_port,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PortMapping) Reset() { + *x = PortMapping{} + mi := &file_stack_v1_stack_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PortMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PortMapping) ProtoMessage() {} + +func (x *PortMapping) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PortMapping.ProtoReflect.Descriptor instead. +func (*PortMapping) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{22} +} + +func (x *PortMapping) GetContainerPort() int32 { + if x != nil { + return x.ContainerPort + } + return 0 +} + +func (x *PortMapping) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *PortMapping) GetNodePort() int32 { + if x != nil { + return x.NodePort + } + return 0 +} + +type BatchDeleteJob struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` + Status JobStatus `protobuf:"varint,2,opt,name=status,proto3,enum=stack.v1.JobStatus" json:"status,omitempty"` + Total int32 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"` + Deleted int32 `protobuf:"varint,4,opt,name=deleted,proto3" json:"deleted,omitempty"` + NotFound int32 `protobuf:"varint,5,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + Failed int32 `protobuf:"varint,6,opt,name=failed,proto3" json:"failed,omitempty"` + Errors []*JobError `protobuf:"bytes,7,rep,name=errors,proto3" json:"errors,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BatchDeleteJob) Reset() { + *x = BatchDeleteJob{} + mi := &file_stack_v1_stack_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BatchDeleteJob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchDeleteJob) ProtoMessage() {} + +func (x *BatchDeleteJob) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchDeleteJob.ProtoReflect.Descriptor instead. +func (*BatchDeleteJob) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{23} +} + +func (x *BatchDeleteJob) GetJobId() string { + if x != nil { + return x.JobId + } + return "" +} + +func (x *BatchDeleteJob) GetStatus() JobStatus { + if x != nil { + return x.Status + } + return JobStatus_JOB_STATUS_UNSPECIFIED +} + +func (x *BatchDeleteJob) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *BatchDeleteJob) GetDeleted() int32 { + if x != nil { + return x.Deleted + } + return 0 +} + +func (x *BatchDeleteJob) GetNotFound() int32 { + if x != nil { + return x.NotFound + } + return 0 +} + +func (x *BatchDeleteJob) GetFailed() int32 { + if x != nil { + return x.Failed + } + return 0 +} + +func (x *BatchDeleteJob) GetErrors() []*JobError { + if x != nil { + return x.Errors + } + return nil +} + +func (x *BatchDeleteJob) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *BatchDeleteJob) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +type JobError struct { + state protoimpl.MessageState `protogen:"open.v1"` + StackId string `protobuf:"bytes,1,opt,name=stack_id,json=stackId,proto3" json:"stack_id,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobError) Reset() { + *x = JobError{} + mi := &file_stack_v1_stack_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobError) ProtoMessage() {} + +func (x *JobError) ProtoReflect() protoreflect.Message { + mi := &file_stack_v1_stack_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobError.ProtoReflect.Descriptor instead. +func (*JobError) Descriptor() ([]byte, []int) { + return file_stack_v1_stack_proto_rawDescGZIP(), []int{24} +} + +func (x *JobError) GetStackId() string { + if x != nil { + return x.StackId + } + return "" +} + +func (x *JobError) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +var File_stack_v1_stack_proto protoreflect.FileDescriptor + +const file_stack_v1_stack_proto_rawDesc = "" + + "\n" + + "\x14stack/v1/stack.proto\x12\bstack.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\x10\n" + + "\x0eHealthzRequest\")\n" + + "\x0fHealthzResponse\x12\x16\n" + + "\x06status\x18\x01 \x01(\tR\x06status\"f\n" + + "\x12CreateStackRequest\x12\x19\n" + + "\bpod_spec\x18\x01 \x01(\tR\apodSpec\x125\n" + + "\ftarget_ports\x18\x02 \x03(\v2\x12.stack.v1.PortSpecR\vtargetPorts\"<\n" + + "\x13CreateStackResponse\x12%\n" + + "\x05stack\x18\x01 \x01(\v2\x0f.stack.v1.StackR\x05stack\",\n" + + "\x0fGetStackRequest\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\"9\n" + + "\x10GetStackResponse\x12%\n" + + "\x05stack\x18\x01 \x01(\v2\x0f.stack.v1.StackR\x05stack\"9\n" + + "\x1cGetStackStatusSummaryRequest\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\"W\n" + + "\x1dGetStackStatusSummaryResponse\x126\n" + + "\asummary\x18\x01 \x01(\v2\x1c.stack.v1.StackStatusSummaryR\asummary\"/\n" + + "\x12DeleteStackRequest\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\"J\n" + + "\x13DeleteStackResponse\x12\x18\n" + + "\adeleted\x18\x01 \x01(\bR\adeleted\x12\x19\n" + + "\bstack_id\x18\x02 \x01(\tR\astackId\"\x13\n" + + "\x11ListStacksRequest\"=\n" + + "\x12ListStacksResponse\x12'\n" + + "\x06stacks\x18\x01 \x03(\v2\x0f.stack.v1.StackR\x06stacks\":\n" + + "\x1bCreateBatchDeleteJobRequest\x12\x1b\n" + + "\tstack_ids\x18\x01 \x03(\tR\bstackIds\"5\n" + + "\x1cCreateBatchDeleteJobResponse\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\"1\n" + + "\x18GetBatchDeleteJobRequest\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\"G\n" + + "\x19GetBatchDeleteJobResponse\x12*\n" + + "\x03job\x18\x01 \x01(\v2\x18.stack.v1.BatchDeleteJobR\x03job\"\x11\n" + + "\x0fGetStatsRequest\"9\n" + + "\x10GetStatsResponse\x12%\n" + + "\x05stats\x18\x01 \x01(\v2\x0f.stack.v1.StatsR\x05stats\"\xf2\x02\n" + + "\x05Stats\x12!\n" + + "\ftotal_stacks\x18\x01 \x01(\x05R\vtotalStacks\x12#\n" + + "\ractive_stacks\x18\x02 \x01(\x05R\factiveStacks\x12R\n" + + "\x11node_distribution\x18\x03 \x03(\v2%.stack.v1.Stats.NodeDistributionEntryR\x10nodeDistribution\x12&\n" + + "\x0fused_node_ports\x18\x04 \x01(\x05R\rusedNodePorts\x12,\n" + + "\x12reserved_cpu_milli\x18\x05 \x01(\x03R\x10reservedCpuMilli\x122\n" + + "\x15reserved_memory_bytes\x18\x06 \x01(\x03R\x13reservedMemoryBytes\x1aC\n" + + "\x15NodeDistributionEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\"\x98\x05\n" + + "\x05Stack\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\x12\x15\n" + + "\x06pod_id\x18\x02 \x01(\tR\x05podId\x12\x1c\n" + + "\tnamespace\x18\x03 \x01(\tR\tnamespace\x12\x17\n" + + "\anode_id\x18\x04 \x01(\tR\x06nodeId\x12)\n" + + "\x0enode_public_ip\x18\x05 \x01(\tH\x00R\fnodePublicIp\x88\x01\x01\x12\x19\n" + + "\bpod_spec\x18\x06 \x01(\tR\apodSpec\x12+\n" + + "\x05ports\x18\a \x03(\v2\x15.stack.v1.PortMappingR\x05ports\x12!\n" + + "\fservice_name\x18\b \x01(\tR\vserviceName\x12(\n" + + "\x06status\x18\t \x01(\x0e2\x10.stack.v1.StatusR\x06status\x12@\n" + + "\x0ettl_expires_at\x18\n" + + " \x01(\v2\x1a.google.protobuf.TimestampR\fttlExpiresAt\x129\n" + + "\n" + + "created_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\f \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12.\n" + + "\x13requested_cpu_milli\x18\r \x01(\x03R\x11requestedCpuMilli\x124\n" + + "\x16requested_memory_bytes\x18\x0e \x01(\x03R\x14requestedMemoryBytes\x125\n" + + "\ftarget_ports\x18\x0f \x03(\v2\x12.stack.v1.PortSpecR\vtargetPortsB\x11\n" + + "\x0f_node_public_ip\"\xa9\x02\n" + + "\x12StackStatusSummary\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\x12(\n" + + "\x06status\x18\x02 \x01(\x0e2\x10.stack.v1.StatusR\x06status\x12,\n" + + "\x03ttl\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x03ttl\x12+\n" + + "\x05ports\x18\x04 \x03(\v2\x15.stack.v1.PortMappingR\x05ports\x12)\n" + + "\x0enode_public_ip\x18\x05 \x01(\tH\x00R\fnodePublicIp\x88\x01\x01\x125\n" + + "\ftarget_ports\x18\x06 \x03(\v2\x12.stack.v1.PortSpecR\vtargetPortsB\x11\n" + + "\x0f_node_public_ip\"M\n" + + "\bPortSpec\x12%\n" + + "\x0econtainer_port\x18\x01 \x01(\x05R\rcontainerPort\x12\x1a\n" + + "\bprotocol\x18\x02 \x01(\tR\bprotocol\"m\n" + + "\vPortMapping\x12%\n" + + "\x0econtainer_port\x18\x01 \x01(\x05R\rcontainerPort\x12\x1a\n" + + "\bprotocol\x18\x02 \x01(\tR\bprotocol\x12\x1b\n" + + "\tnode_port\x18\x03 \x01(\x05R\bnodePort\"\xdb\x02\n" + + "\x0eBatchDeleteJob\x12\x15\n" + + "\x06job_id\x18\x01 \x01(\tR\x05jobId\x12+\n" + + "\x06status\x18\x02 \x01(\x0e2\x13.stack.v1.JobStatusR\x06status\x12\x14\n" + + "\x05total\x18\x03 \x01(\x05R\x05total\x12\x18\n" + + "\adeleted\x18\x04 \x01(\x05R\adeleted\x12\x1b\n" + + "\tnot_found\x18\x05 \x01(\x05R\bnotFound\x12\x16\n" + + "\x06failed\x18\x06 \x01(\x05R\x06failed\x12*\n" + + "\x06errors\x18\a \x03(\v2\x12.stack.v1.JobErrorR\x06errors\x129\n" + + "\n" + + "created_at\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\t \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\";\n" + + "\bJobError\x12\x19\n" + + "\bstack_id\x18\x01 \x01(\tR\astackId\x12\x14\n" + + "\x05error\x18\x02 \x01(\tR\x05error*\x89\x01\n" + + "\x06Status\x12\x16\n" + + "\x12STATUS_UNSPECIFIED\x10\x00\x12\x13\n" + + "\x0fSTATUS_CREATING\x10\x01\x12\x12\n" + + "\x0eSTATUS_RUNNING\x10\x02\x12\x12\n" + + "\x0eSTATUS_STOPPED\x10\x03\x12\x11\n" + + "\rSTATUS_FAILED\x10\x04\x12\x17\n" + + "\x13STATUS_NODE_DELETED\x10\x05*\x87\x01\n" + + "\tJobStatus\x12\x1a\n" + + "\x16JOB_STATUS_UNSPECIFIED\x10\x00\x12\x15\n" + + "\x11JOB_STATUS_QUEUED\x10\x01\x12\x16\n" + + "\x12JOB_STATUS_RUNNING\x10\x02\x12\x18\n" + + "\x14JOB_STATUS_COMPLETED\x10\x03\x12\x15\n" + + "\x11JOB_STATUS_FAILED\x10\x042\xe4\x05\n" + + "\fStackService\x12>\n" + + "\aHealthz\x12\x18.stack.v1.HealthzRequest\x1a\x19.stack.v1.HealthzResponse\x12J\n" + + "\vCreateStack\x12\x1c.stack.v1.CreateStackRequest\x1a\x1d.stack.v1.CreateStackResponse\x12A\n" + + "\bGetStack\x12\x19.stack.v1.GetStackRequest\x1a\x1a.stack.v1.GetStackResponse\x12h\n" + + "\x15GetStackStatusSummary\x12&.stack.v1.GetStackStatusSummaryRequest\x1a'.stack.v1.GetStackStatusSummaryResponse\x12J\n" + + "\vDeleteStack\x12\x1c.stack.v1.DeleteStackRequest\x1a\x1d.stack.v1.DeleteStackResponse\x12G\n" + + "\n" + + "ListStacks\x12\x1b.stack.v1.ListStacksRequest\x1a\x1c.stack.v1.ListStacksResponse\x12e\n" + + "\x14CreateBatchDeleteJob\x12%.stack.v1.CreateBatchDeleteJobRequest\x1a&.stack.v1.CreateBatchDeleteJobResponse\x12\\\n" + + "\x11GetBatchDeleteJob\x12\".stack.v1.GetBatchDeleteJobRequest\x1a#.stack.v1.GetBatchDeleteJobResponse\x12A\n" + + "\bGetStats\x12\x19.stack.v1.GetStatsRequest\x1a\x1a.stack.v1.GetStatsResponseB%Z#smctf/internal/gen/stack/v1;stackv1b\x06proto3" + +var ( + file_stack_v1_stack_proto_rawDescOnce sync.Once + file_stack_v1_stack_proto_rawDescData []byte +) + +func file_stack_v1_stack_proto_rawDescGZIP() []byte { + file_stack_v1_stack_proto_rawDescOnce.Do(func() { + file_stack_v1_stack_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_stack_v1_stack_proto_rawDesc), len(file_stack_v1_stack_proto_rawDesc))) + }) + return file_stack_v1_stack_proto_rawDescData +} + +var file_stack_v1_stack_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_stack_v1_stack_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_stack_v1_stack_proto_goTypes = []any{ + (Status)(0), // 0: stack.v1.Status + (JobStatus)(0), // 1: stack.v1.JobStatus + (*HealthzRequest)(nil), // 2: stack.v1.HealthzRequest + (*HealthzResponse)(nil), // 3: stack.v1.HealthzResponse + (*CreateStackRequest)(nil), // 4: stack.v1.CreateStackRequest + (*CreateStackResponse)(nil), // 5: stack.v1.CreateStackResponse + (*GetStackRequest)(nil), // 6: stack.v1.GetStackRequest + (*GetStackResponse)(nil), // 7: stack.v1.GetStackResponse + (*GetStackStatusSummaryRequest)(nil), // 8: stack.v1.GetStackStatusSummaryRequest + (*GetStackStatusSummaryResponse)(nil), // 9: stack.v1.GetStackStatusSummaryResponse + (*DeleteStackRequest)(nil), // 10: stack.v1.DeleteStackRequest + (*DeleteStackResponse)(nil), // 11: stack.v1.DeleteStackResponse + (*ListStacksRequest)(nil), // 12: stack.v1.ListStacksRequest + (*ListStacksResponse)(nil), // 13: stack.v1.ListStacksResponse + (*CreateBatchDeleteJobRequest)(nil), // 14: stack.v1.CreateBatchDeleteJobRequest + (*CreateBatchDeleteJobResponse)(nil), // 15: stack.v1.CreateBatchDeleteJobResponse + (*GetBatchDeleteJobRequest)(nil), // 16: stack.v1.GetBatchDeleteJobRequest + (*GetBatchDeleteJobResponse)(nil), // 17: stack.v1.GetBatchDeleteJobResponse + (*GetStatsRequest)(nil), // 18: stack.v1.GetStatsRequest + (*GetStatsResponse)(nil), // 19: stack.v1.GetStatsResponse + (*Stats)(nil), // 20: stack.v1.Stats + (*Stack)(nil), // 21: stack.v1.Stack + (*StackStatusSummary)(nil), // 22: stack.v1.StackStatusSummary + (*PortSpec)(nil), // 23: stack.v1.PortSpec + (*PortMapping)(nil), // 24: stack.v1.PortMapping + (*BatchDeleteJob)(nil), // 25: stack.v1.BatchDeleteJob + (*JobError)(nil), // 26: stack.v1.JobError + nil, // 27: stack.v1.Stats.NodeDistributionEntry + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp +} +var file_stack_v1_stack_proto_depIdxs = []int32{ + 23, // 0: stack.v1.CreateStackRequest.target_ports:type_name -> stack.v1.PortSpec + 21, // 1: stack.v1.CreateStackResponse.stack:type_name -> stack.v1.Stack + 21, // 2: stack.v1.GetStackResponse.stack:type_name -> stack.v1.Stack + 22, // 3: stack.v1.GetStackStatusSummaryResponse.summary:type_name -> stack.v1.StackStatusSummary + 21, // 4: stack.v1.ListStacksResponse.stacks:type_name -> stack.v1.Stack + 25, // 5: stack.v1.GetBatchDeleteJobResponse.job:type_name -> stack.v1.BatchDeleteJob + 20, // 6: stack.v1.GetStatsResponse.stats:type_name -> stack.v1.Stats + 27, // 7: stack.v1.Stats.node_distribution:type_name -> stack.v1.Stats.NodeDistributionEntry + 24, // 8: stack.v1.Stack.ports:type_name -> stack.v1.PortMapping + 0, // 9: stack.v1.Stack.status:type_name -> stack.v1.Status + 28, // 10: stack.v1.Stack.ttl_expires_at:type_name -> google.protobuf.Timestamp + 28, // 11: stack.v1.Stack.created_at:type_name -> google.protobuf.Timestamp + 28, // 12: stack.v1.Stack.updated_at:type_name -> google.protobuf.Timestamp + 23, // 13: stack.v1.Stack.target_ports:type_name -> stack.v1.PortSpec + 0, // 14: stack.v1.StackStatusSummary.status:type_name -> stack.v1.Status + 28, // 15: stack.v1.StackStatusSummary.ttl:type_name -> google.protobuf.Timestamp + 24, // 16: stack.v1.StackStatusSummary.ports:type_name -> stack.v1.PortMapping + 23, // 17: stack.v1.StackStatusSummary.target_ports:type_name -> stack.v1.PortSpec + 1, // 18: stack.v1.BatchDeleteJob.status:type_name -> stack.v1.JobStatus + 26, // 19: stack.v1.BatchDeleteJob.errors:type_name -> stack.v1.JobError + 28, // 20: stack.v1.BatchDeleteJob.created_at:type_name -> google.protobuf.Timestamp + 28, // 21: stack.v1.BatchDeleteJob.updated_at:type_name -> google.protobuf.Timestamp + 2, // 22: stack.v1.StackService.Healthz:input_type -> stack.v1.HealthzRequest + 4, // 23: stack.v1.StackService.CreateStack:input_type -> stack.v1.CreateStackRequest + 6, // 24: stack.v1.StackService.GetStack:input_type -> stack.v1.GetStackRequest + 8, // 25: stack.v1.StackService.GetStackStatusSummary:input_type -> stack.v1.GetStackStatusSummaryRequest + 10, // 26: stack.v1.StackService.DeleteStack:input_type -> stack.v1.DeleteStackRequest + 12, // 27: stack.v1.StackService.ListStacks:input_type -> stack.v1.ListStacksRequest + 14, // 28: stack.v1.StackService.CreateBatchDeleteJob:input_type -> stack.v1.CreateBatchDeleteJobRequest + 16, // 29: stack.v1.StackService.GetBatchDeleteJob:input_type -> stack.v1.GetBatchDeleteJobRequest + 18, // 30: stack.v1.StackService.GetStats:input_type -> stack.v1.GetStatsRequest + 3, // 31: stack.v1.StackService.Healthz:output_type -> stack.v1.HealthzResponse + 5, // 32: stack.v1.StackService.CreateStack:output_type -> stack.v1.CreateStackResponse + 7, // 33: stack.v1.StackService.GetStack:output_type -> stack.v1.GetStackResponse + 9, // 34: stack.v1.StackService.GetStackStatusSummary:output_type -> stack.v1.GetStackStatusSummaryResponse + 11, // 35: stack.v1.StackService.DeleteStack:output_type -> stack.v1.DeleteStackResponse + 13, // 36: stack.v1.StackService.ListStacks:output_type -> stack.v1.ListStacksResponse + 15, // 37: stack.v1.StackService.CreateBatchDeleteJob:output_type -> stack.v1.CreateBatchDeleteJobResponse + 17, // 38: stack.v1.StackService.GetBatchDeleteJob:output_type -> stack.v1.GetBatchDeleteJobResponse + 19, // 39: stack.v1.StackService.GetStats:output_type -> stack.v1.GetStatsResponse + 31, // [31:40] is the sub-list for method output_type + 22, // [22:31] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name +} + +func init() { file_stack_v1_stack_proto_init() } +func file_stack_v1_stack_proto_init() { + if File_stack_v1_stack_proto != nil { + return + } + file_stack_v1_stack_proto_msgTypes[19].OneofWrappers = []any{} + file_stack_v1_stack_proto_msgTypes[20].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_stack_v1_stack_proto_rawDesc), len(file_stack_v1_stack_proto_rawDesc)), + NumEnums: 2, + NumMessages: 26, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_stack_v1_stack_proto_goTypes, + DependencyIndexes: file_stack_v1_stack_proto_depIdxs, + EnumInfos: file_stack_v1_stack_proto_enumTypes, + MessageInfos: file_stack_v1_stack_proto_msgTypes, + }.Build() + File_stack_v1_stack_proto = out.File + file_stack_v1_stack_proto_goTypes = nil + file_stack_v1_stack_proto_depIdxs = nil +} diff --git a/internal/gen/stack/v1/stack_grpc.pb.go b/internal/gen/stack/v1/stack_grpc.pb.go new file mode 100644 index 0000000..e42c578 --- /dev/null +++ b/internal/gen/stack/v1/stack_grpc.pb.go @@ -0,0 +1,425 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc (unknown) +// source: stack/v1/stack.proto + +package stackv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// 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.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + StackService_Healthz_FullMethodName = "/stack.v1.StackService/Healthz" + StackService_CreateStack_FullMethodName = "/stack.v1.StackService/CreateStack" + StackService_GetStack_FullMethodName = "/stack.v1.StackService/GetStack" + StackService_GetStackStatusSummary_FullMethodName = "/stack.v1.StackService/GetStackStatusSummary" + StackService_DeleteStack_FullMethodName = "/stack.v1.StackService/DeleteStack" + StackService_ListStacks_FullMethodName = "/stack.v1.StackService/ListStacks" + StackService_CreateBatchDeleteJob_FullMethodName = "/stack.v1.StackService/CreateBatchDeleteJob" + StackService_GetBatchDeleteJob_FullMethodName = "/stack.v1.StackService/GetBatchDeleteJob" + StackService_GetStats_FullMethodName = "/stack.v1.StackService/GetStats" +) + +// StackServiceClient is the client API for StackService 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 StackServiceClient interface { + Healthz(ctx context.Context, in *HealthzRequest, opts ...grpc.CallOption) (*HealthzResponse, error) + CreateStack(ctx context.Context, in *CreateStackRequest, opts ...grpc.CallOption) (*CreateStackResponse, error) + GetStack(ctx context.Context, in *GetStackRequest, opts ...grpc.CallOption) (*GetStackResponse, error) + GetStackStatusSummary(ctx context.Context, in *GetStackStatusSummaryRequest, opts ...grpc.CallOption) (*GetStackStatusSummaryResponse, error) + DeleteStack(ctx context.Context, in *DeleteStackRequest, opts ...grpc.CallOption) (*DeleteStackResponse, error) + ListStacks(ctx context.Context, in *ListStacksRequest, opts ...grpc.CallOption) (*ListStacksResponse, error) + CreateBatchDeleteJob(ctx context.Context, in *CreateBatchDeleteJobRequest, opts ...grpc.CallOption) (*CreateBatchDeleteJobResponse, error) + GetBatchDeleteJob(ctx context.Context, in *GetBatchDeleteJobRequest, opts ...grpc.CallOption) (*GetBatchDeleteJobResponse, error) + GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error) +} + +type stackServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewStackServiceClient(cc grpc.ClientConnInterface) StackServiceClient { + return &stackServiceClient{cc} +} + +func (c *stackServiceClient) Healthz(ctx context.Context, in *HealthzRequest, opts ...grpc.CallOption) (*HealthzResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(HealthzResponse) + err := c.cc.Invoke(ctx, StackService_Healthz_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) CreateStack(ctx context.Context, in *CreateStackRequest, opts ...grpc.CallOption) (*CreateStackResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateStackResponse) + err := c.cc.Invoke(ctx, StackService_CreateStack_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) GetStack(ctx context.Context, in *GetStackRequest, opts ...grpc.CallOption) (*GetStackResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetStackResponse) + err := c.cc.Invoke(ctx, StackService_GetStack_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) GetStackStatusSummary(ctx context.Context, in *GetStackStatusSummaryRequest, opts ...grpc.CallOption) (*GetStackStatusSummaryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetStackStatusSummaryResponse) + err := c.cc.Invoke(ctx, StackService_GetStackStatusSummary_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) DeleteStack(ctx context.Context, in *DeleteStackRequest, opts ...grpc.CallOption) (*DeleteStackResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteStackResponse) + err := c.cc.Invoke(ctx, StackService_DeleteStack_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) ListStacks(ctx context.Context, in *ListStacksRequest, opts ...grpc.CallOption) (*ListStacksResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListStacksResponse) + err := c.cc.Invoke(ctx, StackService_ListStacks_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) CreateBatchDeleteJob(ctx context.Context, in *CreateBatchDeleteJobRequest, opts ...grpc.CallOption) (*CreateBatchDeleteJobResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateBatchDeleteJobResponse) + err := c.cc.Invoke(ctx, StackService_CreateBatchDeleteJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) GetBatchDeleteJob(ctx context.Context, in *GetBatchDeleteJobRequest, opts ...grpc.CallOption) (*GetBatchDeleteJobResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetBatchDeleteJobResponse) + err := c.cc.Invoke(ctx, StackService_GetBatchDeleteJob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *stackServiceClient) GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetStatsResponse) + err := c.cc.Invoke(ctx, StackService_GetStats_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// StackServiceServer is the server API for StackService service. +// All implementations must embed UnimplementedStackServiceServer +// for forward compatibility. +type StackServiceServer interface { + Healthz(context.Context, *HealthzRequest) (*HealthzResponse, error) + CreateStack(context.Context, *CreateStackRequest) (*CreateStackResponse, error) + GetStack(context.Context, *GetStackRequest) (*GetStackResponse, error) + GetStackStatusSummary(context.Context, *GetStackStatusSummaryRequest) (*GetStackStatusSummaryResponse, error) + DeleteStack(context.Context, *DeleteStackRequest) (*DeleteStackResponse, error) + ListStacks(context.Context, *ListStacksRequest) (*ListStacksResponse, error) + CreateBatchDeleteJob(context.Context, *CreateBatchDeleteJobRequest) (*CreateBatchDeleteJobResponse, error) + GetBatchDeleteJob(context.Context, *GetBatchDeleteJobRequest) (*GetBatchDeleteJobResponse, error) + GetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error) + mustEmbedUnimplementedStackServiceServer() +} + +// UnimplementedStackServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedStackServiceServer struct{} + +func (UnimplementedStackServiceServer) Healthz(context.Context, *HealthzRequest) (*HealthzResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Healthz not implemented") +} +func (UnimplementedStackServiceServer) CreateStack(context.Context, *CreateStackRequest) (*CreateStackResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateStack not implemented") +} +func (UnimplementedStackServiceServer) GetStack(context.Context, *GetStackRequest) (*GetStackResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetStack not implemented") +} +func (UnimplementedStackServiceServer) GetStackStatusSummary(context.Context, *GetStackStatusSummaryRequest) (*GetStackStatusSummaryResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetStackStatusSummary not implemented") +} +func (UnimplementedStackServiceServer) DeleteStack(context.Context, *DeleteStackRequest) (*DeleteStackResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteStack not implemented") +} +func (UnimplementedStackServiceServer) ListStacks(context.Context, *ListStacksRequest) (*ListStacksResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListStacks not implemented") +} +func (UnimplementedStackServiceServer) CreateBatchDeleteJob(context.Context, *CreateBatchDeleteJobRequest) (*CreateBatchDeleteJobResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateBatchDeleteJob not implemented") +} +func (UnimplementedStackServiceServer) GetBatchDeleteJob(context.Context, *GetBatchDeleteJobRequest) (*GetBatchDeleteJobResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetBatchDeleteJob not implemented") +} +func (UnimplementedStackServiceServer) GetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetStats not implemented") +} +func (UnimplementedStackServiceServer) mustEmbedUnimplementedStackServiceServer() {} +func (UnimplementedStackServiceServer) testEmbeddedByValue() {} + +// UnsafeStackServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to StackServiceServer will +// result in compilation errors. +type UnsafeStackServiceServer interface { + mustEmbedUnimplementedStackServiceServer() +} + +func RegisterStackServiceServer(s grpc.ServiceRegistrar, srv StackServiceServer) { + // If the following call panics, it indicates UnimplementedStackServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&StackService_ServiceDesc, srv) +} + +func _StackService_Healthz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthzRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).Healthz(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_Healthz_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).Healthz(ctx, req.(*HealthzRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_CreateStack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateStackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).CreateStack(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_CreateStack_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).CreateStack(ctx, req.(*CreateStackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_GetStack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).GetStack(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_GetStack_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).GetStack(ctx, req.(*GetStackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_GetStackStatusSummary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStackStatusSummaryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).GetStackStatusSummary(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_GetStackStatusSummary_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).GetStackStatusSummary(ctx, req.(*GetStackStatusSummaryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_DeleteStack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteStackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).DeleteStack(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_DeleteStack_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).DeleteStack(ctx, req.(*DeleteStackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_ListStacks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListStacksRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).ListStacks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_ListStacks_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).ListStacks(ctx, req.(*ListStacksRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_CreateBatchDeleteJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateBatchDeleteJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).CreateBatchDeleteJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_CreateBatchDeleteJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).CreateBatchDeleteJob(ctx, req.(*CreateBatchDeleteJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_GetBatchDeleteJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBatchDeleteJobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).GetBatchDeleteJob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_GetBatchDeleteJob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).GetBatchDeleteJob(ctx, req.(*GetBatchDeleteJobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StackService_GetStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StackServiceServer).GetStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StackService_GetStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StackServiceServer).GetStats(ctx, req.(*GetStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// StackService_ServiceDesc is the grpc.ServiceDesc for StackService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var StackService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "stack.v1.StackService", + HandlerType: (*StackServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Healthz", + Handler: _StackService_Healthz_Handler, + }, + { + MethodName: "CreateStack", + Handler: _StackService_CreateStack_Handler, + }, + { + MethodName: "GetStack", + Handler: _StackService_GetStack_Handler, + }, + { + MethodName: "GetStackStatusSummary", + Handler: _StackService_GetStackStatusSummary_Handler, + }, + { + MethodName: "DeleteStack", + Handler: _StackService_DeleteStack_Handler, + }, + { + MethodName: "ListStacks", + Handler: _StackService_ListStacks_Handler, + }, + { + MethodName: "CreateBatchDeleteJob", + Handler: _StackService_CreateBatchDeleteJob_Handler, + }, + { + MethodName: "GetBatchDeleteJob", + Handler: _StackService_GetBatchDeleteJob_Handler, + }, + { + MethodName: "GetStats", + Handler: _StackService_GetStats_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "stack/v1/stack.proto", +} diff --git a/internal/http/handlers/testenv_test.go b/internal/http/handlers/testenv_test.go index 8532dae..13eff72 100644 --- a/internal/http/handlers/testenv_test.go +++ b/internal/http/handlers/testenv_test.go @@ -119,7 +119,7 @@ func TestMain(m *testing.M) { }, Stack: config.StackConfig{ Enabled: true, - MaxPer: 3, + MaxPer: 3, CreateWindow: time.Minute, CreateMax: 1, }, diff --git a/internal/http/integration/admin_test.go b/internal/http/integration/admin_test.go index bfdb5d8..3728132 100644 --- a/internal/http/integration/admin_test.go +++ b/internal/http/integration/admin_test.go @@ -552,7 +552,7 @@ func TestAdminStackManagement(t *testing.T) { cfg := testCfg cfg.Stack = config.StackConfig{ Enabled: true, - MaxPer: 3, + MaxPer: 3, CreateWindow: time.Minute, CreateMax: 1, } @@ -664,7 +664,7 @@ func TestAdminReportSuccess(t *testing.T) { cfg := testCfg cfg.Stack = config.StackConfig{ Enabled: true, - MaxPer: 3, + MaxPer: 3, CreateWindow: time.Minute, CreateMax: 1, } diff --git a/internal/http/integration/testenv_test.go b/internal/http/integration/testenv_test.go index 83ab1f8..268d7e6 100644 --- a/internal/http/integration/testenv_test.go +++ b/internal/http/integration/testenv_test.go @@ -166,7 +166,7 @@ func TestMain(m *testing.M) { }, Stack: config.StackConfig{ Enabled: true, - MaxPer: 3, + MaxPer: 3, CreateWindow: time.Minute, CreateMax: 1, }, diff --git a/internal/stack/grpc_client.go b/internal/stack/grpc_client.go new file mode 100644 index 0000000..c28dd07 --- /dev/null +++ b/internal/stack/grpc_client.go @@ -0,0 +1,236 @@ +package stack + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + stackv1 "smctf/internal/gen/stack/v1" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type GRPCClient struct { + addr string + apiKey string + timeout time.Duration + conn *grpc.ClientConn + client stackv1.StackServiceClient +} + +func NewGRPCClient(addr, apiKey string, timeout time.Duration) (*GRPCClient, error) { + addr = strings.TrimSpace(addr) + if addr == "" { + return nil, fmt.Errorf("grpc addr is required") + } + + conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, fmt.Errorf("grpc dial: %w", err) + } + + return &GRPCClient{ + addr: addr, + apiKey: apiKey, + timeout: timeout, + conn: conn, + client: stackv1.NewStackServiceClient(conn), + }, nil +} + +func (c *GRPCClient) Close() error { + if c.conn == nil { + return nil + } + + return c.conn.Close() +} + +func (c *GRPCClient) CreateStack(ctx context.Context, targetPorts []TargetPortSpec, podSpec string) (*StackInfo, error) { + ctx, cancel := c.withTimeout(ctx) + defer cancel() + + ctx = c.withAPIKey(ctx) + resp, err := c.client.CreateStack(ctx, &stackv1.CreateStackRequest{ + PodSpec: podSpec, + TargetPorts: toProtoTargetPorts(targetPorts), + }) + if err != nil { + return nil, mapGRPCError(err) + } + + stack := resp.GetStack() + if stack == nil { + return nil, ErrUnexpected + } + + return toStackInfo(stack), nil +} + +func (c *GRPCClient) GetStackStatus(ctx context.Context, stackID string) (*StackStatus, error) { + ctx, cancel := c.withTimeout(ctx) + defer cancel() + + ctx = c.withAPIKey(ctx) + resp, err := c.client.GetStackStatusSummary(ctx, &stackv1.GetStackStatusSummaryRequest{StackId: stackID}) + if err != nil { + return nil, mapGRPCError(err) + } + + summary := resp.GetSummary() + if summary == nil { + return nil, ErrUnexpected + } + + return toStackStatus(summary), nil +} + +func (c *GRPCClient) DeleteStack(ctx context.Context, stackID string) error { + ctx, cancel := c.withTimeout(ctx) + defer cancel() + + ctx = c.withAPIKey(ctx) + _, err := c.client.DeleteStack(ctx, &stackv1.DeleteStackRequest{StackId: stackID}) + if err != nil { + return mapGRPCError(err) + } + + return nil +} + +func (c *GRPCClient) withAPIKey(ctx context.Context) context.Context { + if strings.TrimSpace(c.apiKey) == "" { + return ctx + } + + return metadata.AppendToOutgoingContext(ctx, "x-api-key", c.apiKey) +} + +func (c *GRPCClient) withTimeout(ctx context.Context) (context.Context, context.CancelFunc) { + if c.timeout <= 0 { + return ctx, func() {} + } + + if _, ok := ctx.Deadline(); ok { + return ctx, func() {} + } + + return context.WithTimeout(ctx, c.timeout) +} + +func mapGRPCError(err error) error { + if errors.Is(err, context.DeadlineExceeded) { + return ErrUnavailable + } + + if errors.Is(err, context.Canceled) { + return ErrUnexpected + } + + st, ok := status.FromError(err) + if !ok { + return ErrUnexpected + } + + switch st.Code() { + case codes.NotFound: + return ErrNotFound + case codes.InvalidArgument: + return ErrInvalid + case codes.Unavailable, codes.DeadlineExceeded: + return ErrUnavailable + default: + return ErrUnexpected + } +} + +func toProtoTargetPorts(ports []TargetPortSpec) []*stackv1.PortSpec { + out := make([]*stackv1.PortSpec, 0, len(ports)) + for _, port := range ports { + out = append(out, &stackv1.PortSpec{ + ContainerPort: int32(port.ContainerPort), + Protocol: port.Protocol, + }) + } + + return out +} + +func toStackInfo(stack *stackv1.Stack) *StackInfo { + ports := make([]PortMapping, 0, len(stack.Ports)) + for _, port := range stack.Ports { + ports = append(ports, PortMapping{ + ContainerPort: int(port.ContainerPort), + Protocol: port.Protocol, + NodePort: int(port.NodePort), + }) + } + + return &StackInfo{ + StackID: stack.StackId, + PodID: stack.PodId, + Namespace: stack.Namespace, + NodeID: stack.NodeId, + NodePublicIP: stack.GetNodePublicIp(), + PodSpec: stack.PodSpec, + Ports: ports, + ServiceName: stack.ServiceName, + Status: statusToString(stack.Status), + TTLExpiresAt: timeOrZero(stack.TtlExpiresAt), + CreatedAt: timeOrZero(stack.CreatedAt), + UpdatedAt: timeOrZero(stack.UpdatedAt), + RequestedCPUMilli: int(stack.RequestedCpuMilli), + RequestedMemoryBytes: int(stack.RequestedMemoryBytes), + } +} + +func toStackStatus(summary *stackv1.StackStatusSummary) *StackStatus { + ports := make([]PortMapping, 0, len(summary.Ports)) + for _, port := range summary.Ports { + ports = append(ports, PortMapping{ + ContainerPort: int(port.ContainerPort), + Protocol: port.Protocol, + NodePort: int(port.NodePort), + }) + } + + return &StackStatus{ + StackID: summary.StackId, + Status: statusToString(summary.Status), + TTL: timeOrZero(summary.Ttl), + Ports: ports, + NodePublicIP: summary.GetNodePublicIp(), + } +} + +func timeOrZero(ts *timestamppb.Timestamp) time.Time { + if ts == nil { + return time.Time{} + } + + return ts.AsTime() +} + +func statusToString(status stackv1.Status) string { + switch status { + case stackv1.Status_STATUS_CREATING: + return "creating" + case stackv1.Status_STATUS_RUNNING: + return "running" + case stackv1.Status_STATUS_STOPPED: + return "stopped" + case stackv1.Status_STATUS_FAILED: + return "failed" + case stackv1.Status_STATUS_NODE_DELETED: + return "node_deleted" + default: + return "" + } +} From 45bf0d19154dffb99e0b35018ce86151451ed2fb Mon Sep 17 00:00:00 2001 From: Kim Jun Young Date: Tue, 31 Mar 2026 14:36:07 +0900 Subject: [PATCH 2/3] chore: empty commit for ci From 97d07be3d3afe369429bb48622f9192568c269da Mon Sep 17 00:00:00 2001 From: Kim Jun Young Date: Tue, 31 Mar 2026 16:41:13 +0900 Subject: [PATCH 3/3] chore: applied suggestion --- README.md | 46 +++++++++++++++++------------------ cmd/server/main.go | 9 +++++++ internal/stack/grpc_client.go | 8 ++++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 29db515..a6355ac 100644 --- a/README.md +++ b/README.md @@ -177,29 +177,6 @@ STACKS_PROVISIONER_USE_GRPC=false STACKS_PROVISIONER_GRPC_ADDR=localhost:9090 STACKS_PROVISIONER_API_KEY=change-me STACKS_PROVISIONER_TIMEOUT=5s - -## Buf / BSR (container-provisioner proto) - -This repo consumes the container-provisioner proto via Buf Schema Registry (BSR). - -Setup: - -```bash -make buf-install -buf registry login -``` - -Generate code: - -```bash -make buf-generate -``` - -Module reference is in `buf.gen.yaml`. You can also override via: - -```bash -make buf-generate BUF_MODULE=buf.build//container-provisioner -``` STACKS_CREATE_WINDOW=1m STACKS_CREATE_MAX=1 @@ -228,6 +205,29 @@ S3_PRESIGN_TTL=15m +## Buf / BSR (container-provisioner proto) + +This repo consumes the container-provisioner proto via Buf Schema Registry (BSR). + +Setup: + +```bash +make buf-install +buf registry login +``` + +Generate code: + +```bash +make buf-generate +``` + +Module reference is set via `BUF_MODULE` (Makefile). You can override via: + +```bash +make buf-generate BUF_MODULE=buf.build//container-provisioner +``` + > [!IMPORTANT] > > Make sure to change `JWT_SECRET` to a secure random string in production! diff --git a/cmd/server/main.go b/cmd/server/main.go index e2a03bc..7ab8b28 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -105,6 +105,7 @@ func main() { appConfigSvc := service.NewAppConfigService(appConfigRepo, redisClient, cfg.Cache.AppConfigTTL) var stackClient stack.API + var stackClientCloser func() error if cfg.Stack.ProvisionerUseGRPC { client, err := stack.NewGRPCClient(cfg.Stack.ProvisionerGRPCAddr, cfg.Stack.ProvisionerAPIKey, cfg.Stack.ProvisionerTimeout) if err != nil { @@ -113,9 +114,17 @@ func main() { } stackClient = client + stackClientCloser = client.Close } else { stackClient = stack.NewClient(cfg.Stack.ProvisionerBaseURL, cfg.Stack.ProvisionerAPIKey, cfg.Stack.ProvisionerTimeout) } + if stackClientCloser != nil { + defer func() { + if err := stackClientCloser(); err != nil { + logger.Warn("stack client close error", slog.Any("error", err)) + } + }() + } stackSvc := service.NewStackService(cfg.Stack, stackRepo, challengeRepo, submissionRepo, stackClient, redisClient) diff --git a/internal/stack/grpc_client.go b/internal/stack/grpc_client.go index c28dd07..3cf492c 100644 --- a/internal/stack/grpc_client.go +++ b/internal/stack/grpc_client.go @@ -118,8 +118,12 @@ func (c *GRPCClient) withTimeout(ctx context.Context) (context.Context, context. return ctx, func() {} } - if _, ok := ctx.Deadline(); ok { - return ctx, func() {} + if deadline, ok := ctx.Deadline(); ok { + desired := time.Now().Add(c.timeout) + if deadline.Before(desired) { + return ctx, func() {} + } + return context.WithDeadline(ctx, desired) } return context.WithTimeout(ctx, c.timeout)