diff --git a/.dockerignore b/.dockerignore index e3a9fdfeb..2612530ed 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,10 @@ * !bin/dev/porter-linux-amd64 +!bin/dev/porter-linux-arm64 +!bin/dev/porter-api-server-linux-amd64 +!bin/dev/porter-api-server-linux-arm64 !bin/dev/agent-linux-amd64 +!bin/dev/agent-linux-arm64 !bin/mixins/exec/dev/exec-linux-amd64 +!bin/mixins/exec/dev/exec-linux-arm64 diff --git a/.github/workflows/build-publish-from-fork.yaml b/.github/workflows/build-publish-from-fork.yaml new file mode 100644 index 000000000..7a2ff2b9f --- /dev/null +++ b/.github/workflows/build-publish-from-fork.yaml @@ -0,0 +1,36 @@ +name: build-publish-from-fork +on: + workflow_dispatch: {} + push: {} + pull_request: {} + +jobs: + build: + runs-on: ubuntu-latest + if: github.repository != 'getporter/porter' + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + cache: true + cache-dependency-path: go.sum + - name: Set up Mage + run: go run mage.go EnsureMage + - name: Publish + if: ${{ github.event_name != 'pull_request' }} + env: + PORTER_REGISTRY: ghcr.io/${{ github.repository }} + run: | + mage -v XBuildAll + mage -v PublishServerMultiArchImages diff --git a/.gitignore b/.gitignore index 3e72e2382..f23f81a9b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,11 @@ examples/**/Dockerfile workshop/**/Dockerfile .vscode +*.code-workspace .idea kind.config +grpc-porter-tls.crt +grpc-porter-tls.key +grpc-porter.csr +.grpcurl/ +config.yaml diff --git a/build/images/server/Dockerfile b/build/images/server/Dockerfile new file mode 100644 index 000000000..f9a19bf0b --- /dev/null +++ b/build/images/server/Dockerfile @@ -0,0 +1,28 @@ +FROM alpine:3 as builder +ARG TARGETARCH +WORKDIR /app/.porter + +RUN mkdir runtimes && \ + mkdir -p mixins/exec/runtimes + +# Install porter-api-server, agent, and the exec mixin, everything else +COPY bin/dev/porter-api-server-linux-$TARGETARCH porter +COPY bin/dev/agent-linux-$TARGETARCH agent +COPY bin/mixins/exec/dev/exec-linux-$TARGETARCH mixins/exec/exec +RUN ln -s /app/.porter/porter runtimes/porter-runtime && \ + ln -s /app/.porter/mixins/exec/exec mixins/exec/runtimes/exec-runtime + +# Copy the porter installation into a distroless container +# Explicitly not using the nonroot tag because we don't want the user to exist so it is placed in the root group +# This allows us to run with a random UID, and access a mounted docker socket (which is only accessible via the root group) +FROM gcr.io/distroless/static +WORKDIR /app +COPY --from=builder --chown=65532:0 --chmod=770 /app/.porter /app/.porter +ENV PATH "$PATH:/app/.porter" +# This is where files that need to be copied into /app/.porter/ should be mounted +VOLUME /porter-config +ENV PORTER_HOME /app/.porter + +# Run as a nonroot user +USER 65532 +ENTRYPOINT ["/app/.porter/agent"] \ No newline at end of file diff --git a/build/protoc.Dockerfile b/build/protoc.Dockerfile new file mode 100644 index 000000000..495047491 --- /dev/null +++ b/build/protoc.Dockerfile @@ -0,0 +1,5 @@ +FROM golang:1.19.0 +RUN apt-get update && apt-get -y install protobuf-compiler +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 +WORKDIR /proto diff --git a/cmd/porter/main.go b/cmd/porter/main.go index 0f4d1c6a1..388a42e75 100644 --- a/cmd/porter/main.go +++ b/cmd/porter/main.go @@ -7,6 +7,7 @@ import ( "os" "os/signal" "runtime/debug" + "strconv" "strings" "get.porter.sh/porter/pkg/cli" @@ -19,6 +20,8 @@ import ( var includeDocsCommand = false +var includeGRPCServer string = "false" + //go:embed helptext/usage.txt var usageText string @@ -226,6 +229,11 @@ Try our QuickStart https://getporter.org/quickstart to learn how to use Porter. cmd.AddCommand(buildCredentialsCommands(p)) cmd.AddCommand(buildParametersCommands(p)) cmd.AddCommand(buildCompletionCommand(p)) + //use -ldflags "-X main.includeGRPCServer=true" during build to include + grpcServer, _ := strconv.ParseBool(includeGRPCServer) + if grpcServer { + cmd.AddCommand(buildGRPCServerCommands(p)) + } for _, alias := range buildAliasCommands(p) { cmd.AddCommand(alias) diff --git a/cmd/porter/server.go b/cmd/porter/server.go new file mode 100644 index 000000000..de0cbda00 --- /dev/null +++ b/cmd/porter/server.go @@ -0,0 +1,58 @@ +package main + +import ( + "time" + + grpc "get.porter.sh/porter/pkg/grpc" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/signals" + "github.com/spf13/cobra" +) + +func buildGRPCServerCommands(p *porter.Porter) *cobra.Command { + cmd := &cobra.Command{ + Use: "api-server", + Short: "API server", + Long: "Launch API server for porter", + Hidden: true, // This is a hidden command and is currently only meant to be used by the porter operator + } + cmd.Annotations = map[string]string{ + "group": "api-server", + } + cmd.AddCommand(buildServerRunCommand(p)) + return cmd +} + +func buildServerRunCommand(p *porter.Porter) *cobra.Command { + opts := porter.ServiceOptions{} + cmd := &cobra.Command{ + Use: "run", + Short: "Run the gRPC server", + Long: `Run the gRPC server for porter. + +This command starts the gRPC server for porter which is able to expose limited porter functionality via RPC. +Currently only data operations are supported, creation of resources such as installations, credential sets, or parameter sets is not supported. + +A list of the supported RPCs can be found at +`, + PreRunE: func(cmd *cobra.Command, args []string) error { + return opts.Validate() + }, + RunE: func(cmd *cobra.Command, args []string) error { + srv, err := grpc.NewServer(cmd.Context(), &opts) + if err != nil { + return err + } + grpcServer, err := srv.ListenAndServe() + stopCh := signals.SetupSignalHandler() + serverShutdownTimeout := time.Duration(time.Second * 30) + sd, _ := signals.NewShutdown(serverShutdownTimeout, cmd.Context()) + sd.Graceful(stopCh, grpcServer, cmd.Context()) + return err + }, + } + f := cmd.Flags() + f.Int64VarP(&opts.Port, "port", "p", 3001, "Port to run the server on") + f.StringVarP(&opts.ServiceName, "service-name", "s", "api-server", "Server service name") + return cmd +} diff --git a/docker-bake.json b/docker-bake.json new file mode 100644 index 000000000..a06a3e01d --- /dev/null +++ b/docker-bake.json @@ -0,0 +1,19 @@ +{ + "group": { + "default": { + "targets": [ + "server" + ] + } + }, + "target": { + "server": { + "platforms": [ + "linux/amd64", + "linux/arm64" + ], + "dockerfile": "build/images/server/Dockerfile", + "context": "./" + } + } +} \ No newline at end of file diff --git a/gen/proto/go/porterapis/installation/v1alpha1/installation.pb.go b/gen/proto/go/porterapis/installation/v1alpha1/installation.pb.go new file mode 100644 index 000000000..0b35ddd8f --- /dev/null +++ b/gen/proto/go/porterapis/installation/v1alpha1/installation.pb.go @@ -0,0 +1,1385 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: installation/v1alpha1/installation.proto + +package installationv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Bundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Repository string `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *Bundle) Reset() { + *x = Bundle{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Bundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Bundle) ProtoMessage() {} + +func (x *Bundle) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Bundle.ProtoReflect.Descriptor instead. +func (*Bundle) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{0} +} + +func (x *Bundle) GetRepository() string { + if x != nil { + return x.Repository + } + return "" +} + +func (x *Bundle) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +type InstallationStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RunId string `protobuf:"bytes,1,opt,name=runId,proto3" json:"runId,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + ResultId string `protobuf:"bytes,3,opt,name=resultId,proto3" json:"resultId,omitempty"` + ResultStatus string `protobuf:"bytes,4,opt,name=resultStatus,proto3" json:"resultStatus,omitempty"` + Created *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` + Modified *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=modified,proto3" json:"modified,omitempty"` + Installed *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=installed,proto3" json:"installed,omitempty"` + Uninstalled *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=uninstalled,proto3" json:"uninstalled,omitempty"` + BundleReference string `protobuf:"bytes,9,opt,name=bundleReference,proto3" json:"bundleReference,omitempty"` + BundleVersion string `protobuf:"bytes,10,opt,name=bundleVersion,proto3" json:"bundleVersion,omitempty"` + BundleDigest string `protobuf:"bytes,11,opt,name=bundleDigest,proto3" json:"bundleDigest,omitempty"` +} + +func (x *InstallationStatus) Reset() { + *x = InstallationStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstallationStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstallationStatus) ProtoMessage() {} + +func (x *InstallationStatus) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstallationStatus.ProtoReflect.Descriptor instead. +func (*InstallationStatus) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{1} +} + +func (x *InstallationStatus) GetRunId() string { + if x != nil { + return x.RunId + } + return "" +} + +func (x *InstallationStatus) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *InstallationStatus) GetResultId() string { + if x != nil { + return x.ResultId + } + return "" +} + +func (x *InstallationStatus) GetResultStatus() string { + if x != nil { + return x.ResultStatus + } + return "" +} + +func (x *InstallationStatus) GetCreated() *timestamppb.Timestamp { + if x != nil { + return x.Created + } + return nil +} + +func (x *InstallationStatus) GetModified() *timestamppb.Timestamp { + if x != nil { + return x.Modified + } + return nil +} + +func (x *InstallationStatus) GetInstalled() *timestamppb.Timestamp { + if x != nil { + return x.Installed + } + return nil +} + +func (x *InstallationStatus) GetUninstalled() *timestamppb.Timestamp { + if x != nil { + return x.Uninstalled + } + return nil +} + +func (x *InstallationStatus) GetBundleReference() string { + if x != nil { + return x.BundleReference + } + return "" +} + +func (x *InstallationStatus) GetBundleVersion() string { + if x != nil { + return x.BundleVersion + } + return "" +} + +func (x *InstallationStatus) GetBundleDigest() string { + if x != nil { + return x.BundleDigest + } + return "" +} + +type Calculated struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayInstallationState string `protobuf:"bytes,1,opt,name=displayInstallationState,proto3" json:"displayInstallationState,omitempty"` + DisplayInstallationStatus string `protobuf:"bytes,2,opt,name=displayInstallationStatus,proto3" json:"displayInstallationStatus,omitempty"` + ResolvedParameters structpb.NullValue `protobuf:"varint,3,opt,name=resolvedParameters,proto3,enum=google.protobuf.NullValue" json:"resolvedParameters,omitempty"` +} + +func (x *Calculated) Reset() { + *x = Calculated{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Calculated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Calculated) ProtoMessage() {} + +func (x *Calculated) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Calculated.ProtoReflect.Descriptor instead. +func (*Calculated) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{2} +} + +func (x *Calculated) GetDisplayInstallationState() string { + if x != nil { + return x.DisplayInstallationState + } + return "" +} + +func (x *Calculated) GetDisplayInstallationStatus() string { + if x != nil { + return x.DisplayInstallationStatus + } + return "" +} + +func (x *Calculated) GetResolvedParameters() structpb.NullValue { + if x != nil { + return x.ResolvedParameters + } + return structpb.NullValue(0) +} + +type Installation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique installation ID + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SchemaType string `protobuf:"bytes,2,opt,name=schemaType,proto3" json:"schemaType,omitempty"` + SchemaVersion string `protobuf:"bytes,3,opt,name=schemaVersion,proto3" json:"schemaVersion,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Namespace string `protobuf:"bytes,5,opt,name=namespace,proto3" json:"namespace,omitempty"` + Bundle *Bundle `protobuf:"bytes,6,opt,name=bundle,proto3" json:"bundle,omitempty"` + CredentialSets []string `protobuf:"bytes,7,rep,name=credentialSets,proto3" json:"credentialSets,omitempty"` + ParameterSets []string `protobuf:"bytes,8,rep,name=parameterSets,proto3" json:"parameterSets,omitempty"` + Status *InstallationStatus `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` + Calculated *Calculated `protobuf:"bytes,10,opt,name=calculated,json=_calculated,proto3" json:"calculated,omitempty"` +} + +func (x *Installation) Reset() { + *x = Installation{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Installation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Installation) ProtoMessage() {} + +func (x *Installation) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Installation.ProtoReflect.Descriptor instead. +func (*Installation) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{3} +} + +func (x *Installation) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Installation) GetSchemaType() string { + if x != nil { + return x.SchemaType + } + return "" +} + +func (x *Installation) GetSchemaVersion() string { + if x != nil { + return x.SchemaVersion + } + return "" +} + +func (x *Installation) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Installation) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *Installation) GetBundle() *Bundle { + if x != nil { + return x.Bundle + } + return nil +} + +func (x *Installation) GetCredentialSets() []string { + if x != nil { + return x.CredentialSets + } + return nil +} + +func (x *Installation) GetParameterSets() []string { + if x != nil { + return x.ParameterSets + } + return nil +} + +func (x *Installation) GetStatus() *InstallationStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *Installation) GetCalculated() *Calculated { + if x != nil { + return x.Calculated + } + return nil +} + +// Installations +type ListInstallationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Namespace *string `protobuf:"bytes,2,opt,name=namespace,proto3,oneof" json:"namespace,omitempty"` + Limit *int64 `protobuf:"varint,3,opt,name=limit,proto3,oneof" json:"limit,omitempty"` + Skip *int64 `protobuf:"varint,4,opt,name=skip,proto3,oneof" json:"skip,omitempty"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AllNamespaces *bool `protobuf:"varint,6,opt,name=allNamespaces,proto3,oneof" json:"allNamespaces,omitempty"` +} + +func (x *ListInstallationsRequest) Reset() { + *x = ListInstallationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationsRequest) ProtoMessage() {} + +func (x *ListInstallationsRequest) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationsRequest.ProtoReflect.Descriptor instead. +func (*ListInstallationsRequest) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{4} +} + +func (x *ListInstallationsRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListInstallationsRequest) GetNamespace() string { + if x != nil && x.Namespace != nil { + return *x.Namespace + } + return "" +} + +func (x *ListInstallationsRequest) GetLimit() int64 { + if x != nil && x.Limit != nil { + return *x.Limit + } + return 0 +} + +func (x *ListInstallationsRequest) GetSkip() int64 { + if x != nil && x.Skip != nil { + return *x.Skip + } + return 0 +} + +func (x *ListInstallationsRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *ListInstallationsRequest) GetAllNamespaces() bool { + if x != nil && x.AllNamespaces != nil { + return *x.AllNamespaces + } + return false +} + +type ListInstallationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Installation []*Installation `protobuf:"bytes,1,rep,name=installation,proto3" json:"installation,omitempty"` +} + +func (x *ListInstallationsResponse) Reset() { + *x = ListInstallationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationsResponse) ProtoMessage() {} + +func (x *ListInstallationsResponse) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationsResponse.ProtoReflect.Descriptor instead. +func (*ListInstallationsResponse) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{5} +} + +func (x *ListInstallationsResponse) GetInstallation() []*Installation { + if x != nil { + return x.Installation + } + return nil +} + +// InstallationRuns +type InstallationRun struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Action string `protobuf:"bytes,4,opt,name=action,proto3" json:"action,omitempty"` + Paramters map[string]string `protobuf:"bytes,5,rep,name=paramters,proto3" json:"paramters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Started *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=started,proto3" json:"started,omitempty"` + Stopped *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=stopped,proto3" json:"stopped,omitempty"` + Status string `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *InstallationRun) Reset() { + *x = InstallationRun{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstallationRun) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstallationRun) ProtoMessage() {} + +func (x *InstallationRun) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstallationRun.ProtoReflect.Descriptor instead. +func (*InstallationRun) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{6} +} + +func (x *InstallationRun) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *InstallationRun) GetBundle() string { + if x != nil { + return x.Bundle + } + return "" +} + +func (x *InstallationRun) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *InstallationRun) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *InstallationRun) GetParamters() map[string]string { + if x != nil { + return x.Paramters + } + return nil +} + +func (x *InstallationRun) GetStarted() *timestamppb.Timestamp { + if x != nil { + return x.Started + } + return nil +} + +func (x *InstallationRun) GetStopped() *timestamppb.Timestamp { + if x != nil { + return x.Stopped + } + return nil +} + +func (x *InstallationRun) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type ListInstallationRunsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Installation *Installation `protobuf:"bytes,1,opt,name=installation,proto3" json:"installation,omitempty"` +} + +func (x *ListInstallationRunsRequest) Reset() { + *x = ListInstallationRunsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationRunsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationRunsRequest) ProtoMessage() {} + +func (x *ListInstallationRunsRequest) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationRunsRequest.ProtoReflect.Descriptor instead. +func (*ListInstallationRunsRequest) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{7} +} + +func (x *ListInstallationRunsRequest) GetInstallation() *Installation { + if x != nil { + return x.Installation + } + return nil +} + +type ListInstallationRunsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Run []*InstallationRun `protobuf:"bytes,1,rep,name=run,proto3" json:"run,omitempty"` +} + +func (x *ListInstallationRunsResponse) Reset() { + *x = ListInstallationRunsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationRunsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationRunsResponse) ProtoMessage() {} + +func (x *ListInstallationRunsResponse) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationRunsResponse.ProtoReflect.Descriptor instead. +func (*ListInstallationRunsResponse) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{8} +} + +func (x *ListInstallationRunsResponse) GetRun() []*InstallationRun { + if x != nil { + return x.Run + } + return nil +} + +type PorterValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Sensitive bool `protobuf:"varint,3,opt,name=sensitive,proto3" json:"sensitive,omitempty"` + Value *structpb.Value `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *PorterValue) Reset() { + *x = PorterValue{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PorterValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PorterValue) ProtoMessage() {} + +func (x *PorterValue) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PorterValue.ProtoReflect.Descriptor instead. +func (*PorterValue) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{9} +} + +func (x *PorterValue) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PorterValue) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *PorterValue) GetSensitive() bool { + if x != nil { + return x.Sensitive + } + return false +} + +func (x *PorterValue) GetValue() *structpb.Value { + if x != nil { + return x.Value + } + return nil +} + +type InstallationOutputs struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Output []*PorterValue `protobuf:"bytes,1,rep,name=output,proto3" json:"output,omitempty"` +} + +func (x *InstallationOutputs) Reset() { + *x = InstallationOutputs{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstallationOutputs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstallationOutputs) ProtoMessage() {} + +func (x *InstallationOutputs) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstallationOutputs.ProtoReflect.Descriptor instead. +func (*InstallationOutputs) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{10} +} + +func (x *InstallationOutputs) GetOutput() []*PorterValue { + if x != nil { + return x.Output + } + return nil +} + +type ListInstallationLatestOutputRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Namespace *string `protobuf:"bytes,2,opt,name=namespace,proto3,oneof" json:"namespace,omitempty"` +} + +func (x *ListInstallationLatestOutputRequest) Reset() { + *x = ListInstallationLatestOutputRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationLatestOutputRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationLatestOutputRequest) ProtoMessage() {} + +func (x *ListInstallationLatestOutputRequest) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationLatestOutputRequest.ProtoReflect.Descriptor instead. +func (*ListInstallationLatestOutputRequest) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{11} +} + +func (x *ListInstallationLatestOutputRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ListInstallationLatestOutputRequest) GetNamespace() string { + if x != nil && x.Namespace != nil { + return *x.Namespace + } + return "" +} + +// InstallationRunOutputs +type ListInstallationLatestOutputResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Outputs []*PorterValue `protobuf:"bytes,1,rep,name=outputs,proto3" json:"outputs,omitempty"` +} + +func (x *ListInstallationLatestOutputResponse) Reset() { + *x = ListInstallationLatestOutputResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInstallationLatestOutputResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInstallationLatestOutputResponse) ProtoMessage() {} + +func (x *ListInstallationLatestOutputResponse) ProtoReflect() protoreflect.Message { + mi := &file_installation_v1alpha1_installation_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInstallationLatestOutputResponse.ProtoReflect.Descriptor instead. +func (*ListInstallationLatestOutputResponse) Descriptor() ([]byte, []int) { + return file_installation_v1alpha1_installation_proto_rawDescGZIP(), []int{12} +} + +func (x *ListInstallationLatestOutputResponse) GetOutputs() []*PorterValue { + if x != nil { + return x.Outputs + } + return nil +} + +var File_installation_v1alpha1_installation_proto protoreflect.FileDescriptor + +var file_installation_v1alpha1_installation_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x42, 0x0a, 0x06, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xdc, 0x03, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x64, + 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x0b, + 0x75, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x75, + 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0xd2, + 0x01, 0x0a, 0x0a, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3a, 0x0a, + 0x18, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x18, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x19, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x22, 0xa2, 0x03, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x06, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x06, 0x62, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x53, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, + 0x73, 0x12, 0x41, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x52, 0x0b, 0x5f, 0x63, 0x61, + 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x22, 0xf3, 0x02, 0x0a, 0x18, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x88, 0x01, 0x01, + 0x12, 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x3b, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x0d, + 0x61, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x88, 0x01, 0x01, + 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x10, 0x0a, 0x0e, + 0x5f, 0x61, 0x6c, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x64, + 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x82, 0x03, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x74, 0x65, 0x72, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x34, 0x0a, + 0x07, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x70, + 0x70, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x66, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x58, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x38, 0x0a, 0x03, 0x72, 0x75, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x52, 0x03, 0x72, 0x75, 0x6e, 0x22, 0x81, 0x01, 0x0a, 0x0b, + 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x51, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, + 0x6f, 0x72, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x22, 0x6a, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x88, 0x01, 0x01, + 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x64, + 0x0a, 0x24, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x73, 0x42, 0xfc, 0x01, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x42, 0x11, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x57, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x72, 0x2e, 0x73, 0x68, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x72, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xa2, 0x02, 0x03, 0x49, 0x58, 0x58, 0xaa, 0x02, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, + 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x21, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_installation_v1alpha1_installation_proto_rawDescOnce sync.Once + file_installation_v1alpha1_installation_proto_rawDescData = file_installation_v1alpha1_installation_proto_rawDesc +) + +func file_installation_v1alpha1_installation_proto_rawDescGZIP() []byte { + file_installation_v1alpha1_installation_proto_rawDescOnce.Do(func() { + file_installation_v1alpha1_installation_proto_rawDescData = protoimpl.X.CompressGZIP(file_installation_v1alpha1_installation_proto_rawDescData) + }) + return file_installation_v1alpha1_installation_proto_rawDescData +} + +var file_installation_v1alpha1_installation_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_installation_v1alpha1_installation_proto_goTypes = []interface{}{ + (*Bundle)(nil), // 0: installation.v1alpha1.Bundle + (*InstallationStatus)(nil), // 1: installation.v1alpha1.InstallationStatus + (*Calculated)(nil), // 2: installation.v1alpha1.Calculated + (*Installation)(nil), // 3: installation.v1alpha1.Installation + (*ListInstallationsRequest)(nil), // 4: installation.v1alpha1.ListInstallationsRequest + (*ListInstallationsResponse)(nil), // 5: installation.v1alpha1.ListInstallationsResponse + (*InstallationRun)(nil), // 6: installation.v1alpha1.InstallationRun + (*ListInstallationRunsRequest)(nil), // 7: installation.v1alpha1.ListInstallationRunsRequest + (*ListInstallationRunsResponse)(nil), // 8: installation.v1alpha1.ListInstallationRunsResponse + (*PorterValue)(nil), // 9: installation.v1alpha1.PorterValue + (*InstallationOutputs)(nil), // 10: installation.v1alpha1.InstallationOutputs + (*ListInstallationLatestOutputRequest)(nil), // 11: installation.v1alpha1.ListInstallationLatestOutputRequest + (*ListInstallationLatestOutputResponse)(nil), // 12: installation.v1alpha1.ListInstallationLatestOutputResponse + nil, // 13: installation.v1alpha1.ListInstallationsRequest.LabelsEntry + nil, // 14: installation.v1alpha1.InstallationRun.ParamtersEntry + (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp + (structpb.NullValue)(0), // 16: google.protobuf.NullValue + (*structpb.Value)(nil), // 17: google.protobuf.Value +} +var file_installation_v1alpha1_installation_proto_depIdxs = []int32{ + 15, // 0: installation.v1alpha1.InstallationStatus.created:type_name -> google.protobuf.Timestamp + 15, // 1: installation.v1alpha1.InstallationStatus.modified:type_name -> google.protobuf.Timestamp + 15, // 2: installation.v1alpha1.InstallationStatus.installed:type_name -> google.protobuf.Timestamp + 15, // 3: installation.v1alpha1.InstallationStatus.uninstalled:type_name -> google.protobuf.Timestamp + 16, // 4: installation.v1alpha1.Calculated.resolvedParameters:type_name -> google.protobuf.NullValue + 0, // 5: installation.v1alpha1.Installation.bundle:type_name -> installation.v1alpha1.Bundle + 1, // 6: installation.v1alpha1.Installation.status:type_name -> installation.v1alpha1.InstallationStatus + 2, // 7: installation.v1alpha1.Installation.calculated:type_name -> installation.v1alpha1.Calculated + 13, // 8: installation.v1alpha1.ListInstallationsRequest.labels:type_name -> installation.v1alpha1.ListInstallationsRequest.LabelsEntry + 3, // 9: installation.v1alpha1.ListInstallationsResponse.installation:type_name -> installation.v1alpha1.Installation + 14, // 10: installation.v1alpha1.InstallationRun.paramters:type_name -> installation.v1alpha1.InstallationRun.ParamtersEntry + 15, // 11: installation.v1alpha1.InstallationRun.started:type_name -> google.protobuf.Timestamp + 15, // 12: installation.v1alpha1.InstallationRun.stopped:type_name -> google.protobuf.Timestamp + 3, // 13: installation.v1alpha1.ListInstallationRunsRequest.installation:type_name -> installation.v1alpha1.Installation + 6, // 14: installation.v1alpha1.ListInstallationRunsResponse.run:type_name -> installation.v1alpha1.InstallationRun + 17, // 15: installation.v1alpha1.PorterValue.value:type_name -> google.protobuf.Value + 9, // 16: installation.v1alpha1.InstallationOutputs.output:type_name -> installation.v1alpha1.PorterValue + 9, // 17: installation.v1alpha1.ListInstallationLatestOutputResponse.outputs:type_name -> installation.v1alpha1.PorterValue + 18, // [18:18] is the sub-list for method output_type + 18, // [18:18] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name +} + +func init() { file_installation_v1alpha1_installation_proto_init() } +func file_installation_v1alpha1_installation_proto_init() { + if File_installation_v1alpha1_installation_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_installation_v1alpha1_installation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Bundle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InstallationStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Calculated); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Installation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InstallationRun); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationRunsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationRunsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PorterValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InstallationOutputs); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationLatestOutputRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_installation_v1alpha1_installation_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInstallationLatestOutputResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_installation_v1alpha1_installation_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_installation_v1alpha1_installation_proto_msgTypes[11].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_installation_v1alpha1_installation_proto_rawDesc, + NumEnums: 0, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_installation_v1alpha1_installation_proto_goTypes, + DependencyIndexes: file_installation_v1alpha1_installation_proto_depIdxs, + MessageInfos: file_installation_v1alpha1_installation_proto_msgTypes, + }.Build() + File_installation_v1alpha1_installation_proto = out.File + file_installation_v1alpha1_installation_proto_rawDesc = nil + file_installation_v1alpha1_installation_proto_goTypes = nil + file_installation_v1alpha1_installation_proto_depIdxs = nil +} diff --git a/gen/proto/go/porterapis/porter/v1alpha1/porter.pb.go b/gen/proto/go/porterapis/porter/v1alpha1/porter.pb.go new file mode 100644 index 000000000..5e7c10a57 --- /dev/null +++ b/gen/proto/go/porterapis/porter/v1alpha1/porter.pb.go @@ -0,0 +1,108 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: porter/v1alpha1/porter.proto + +//option go_package = "get.porter.sh/porter/gen/proto/go/installation/v1alpha1"; + +package porterv1alpha1 + +import ( + v1alpha1 "get.porter.sh/porter/gen/proto/go/porterapis/installation/v1alpha1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +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) +) + +var File_porter_v1alpha1_porter_proto protoreflect.FileDescriptor + +var file_porter_v1alpha1_porter_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, + 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x9f, 0x02, 0x0a, 0x06, 0x50, 0x6f, + 0x72, 0x74, 0x65, 0x72, 0x12, 0x78, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x9a, + 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, + 0x12, 0x3a, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcc, 0x01, 0x0a, 0x13, + 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x42, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x73, + 0x68, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x61, 0x70, 0x69, 0x73, + 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x3b, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, + 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0f, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0f, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, + 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1b, 0x50, 0x6f, 0x72, 0x74, + 0x65, 0x72, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x72, + 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var file_porter_v1alpha1_porter_proto_goTypes = []interface{}{ + (*v1alpha1.ListInstallationsRequest)(nil), // 0: installation.v1alpha1.ListInstallationsRequest + (*v1alpha1.ListInstallationLatestOutputRequest)(nil), // 1: installation.v1alpha1.ListInstallationLatestOutputRequest + (*v1alpha1.ListInstallationsResponse)(nil), // 2: installation.v1alpha1.ListInstallationsResponse + (*v1alpha1.ListInstallationLatestOutputResponse)(nil), // 3: installation.v1alpha1.ListInstallationLatestOutputResponse +} +var file_porter_v1alpha1_porter_proto_depIdxs = []int32{ + 0, // 0: porter.v1alpha1.Porter.ListInstallations:input_type -> installation.v1alpha1.ListInstallationsRequest + 1, // 1: porter.v1alpha1.Porter.ListInstallationLatestOutputs:input_type -> installation.v1alpha1.ListInstallationLatestOutputRequest + 2, // 2: porter.v1alpha1.Porter.ListInstallations:output_type -> installation.v1alpha1.ListInstallationsResponse + 3, // 3: porter.v1alpha1.Porter.ListInstallationLatestOutputs:output_type -> installation.v1alpha1.ListInstallationLatestOutputResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_porter_v1alpha1_porter_proto_init() } +func file_porter_v1alpha1_porter_proto_init() { + if File_porter_v1alpha1_porter_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_porter_v1alpha1_porter_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_porter_v1alpha1_porter_proto_goTypes, + DependencyIndexes: file_porter_v1alpha1_porter_proto_depIdxs, + }.Build() + File_porter_v1alpha1_porter_proto = out.File + file_porter_v1alpha1_porter_proto_rawDesc = nil + file_porter_v1alpha1_porter_proto_goTypes = nil + file_porter_v1alpha1_porter_proto_depIdxs = nil +} diff --git a/gen/proto/go/porterapis/porter/v1alpha1/porter_grpc.pb.go b/gen/proto/go/porterapis/porter/v1alpha1/porter_grpc.pb.go new file mode 100644 index 000000000..9b91558a2 --- /dev/null +++ b/gen/proto/go/porterapis/porter/v1alpha1/porter_grpc.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: porter/v1alpha1/porter.proto + +package porterv1alpha1 + +import ( + context "context" + v1alpha1 "get.porter.sh/porter/gen/proto/go/porterapis/installation/v1alpha1" + 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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PorterClient is the client API for Porter 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 PorterClient interface { + // Returns a list of all installations + ListInstallations(ctx context.Context, in *v1alpha1.ListInstallationsRequest, opts ...grpc.CallOption) (*v1alpha1.ListInstallationsResponse, error) + // Returns a list of all outputs for the latest installation run + ListInstallationLatestOutputs(ctx context.Context, in *v1alpha1.ListInstallationLatestOutputRequest, opts ...grpc.CallOption) (*v1alpha1.ListInstallationLatestOutputResponse, error) +} + +type porterClient struct { + cc grpc.ClientConnInterface +} + +func NewPorterClient(cc grpc.ClientConnInterface) PorterClient { + return &porterClient{cc} +} + +func (c *porterClient) ListInstallations(ctx context.Context, in *v1alpha1.ListInstallationsRequest, opts ...grpc.CallOption) (*v1alpha1.ListInstallationsResponse, error) { + out := new(v1alpha1.ListInstallationsResponse) + err := c.cc.Invoke(ctx, "/porter.v1alpha1.Porter/ListInstallations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *porterClient) ListInstallationLatestOutputs(ctx context.Context, in *v1alpha1.ListInstallationLatestOutputRequest, opts ...grpc.CallOption) (*v1alpha1.ListInstallationLatestOutputResponse, error) { + out := new(v1alpha1.ListInstallationLatestOutputResponse) + err := c.cc.Invoke(ctx, "/porter.v1alpha1.Porter/ListInstallationLatestOutputs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PorterServer is the server API for Porter service. +// All implementations must embed UnimplementedPorterServer +// for forward compatibility +type PorterServer interface { + // Returns a list of all installations + ListInstallations(context.Context, *v1alpha1.ListInstallationsRequest) (*v1alpha1.ListInstallationsResponse, error) + // Returns a list of all outputs for the latest installation run + ListInstallationLatestOutputs(context.Context, *v1alpha1.ListInstallationLatestOutputRequest) (*v1alpha1.ListInstallationLatestOutputResponse, error) + mustEmbedUnimplementedPorterServer() +} + +// UnimplementedPorterServer must be embedded to have forward compatible implementations. +type UnimplementedPorterServer struct { +} + +func (UnimplementedPorterServer) ListInstallations(context.Context, *v1alpha1.ListInstallationsRequest) (*v1alpha1.ListInstallationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListInstallations not implemented") +} +func (UnimplementedPorterServer) ListInstallationLatestOutputs(context.Context, *v1alpha1.ListInstallationLatestOutputRequest) (*v1alpha1.ListInstallationLatestOutputResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListInstallationLatestOutputs not implemented") +} +func (UnimplementedPorterServer) mustEmbedUnimplementedPorterServer() {} + +// UnsafePorterServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PorterServer will +// result in compilation errors. +type UnsafePorterServer interface { + mustEmbedUnimplementedPorterServer() +} + +func RegisterPorterServer(s grpc.ServiceRegistrar, srv PorterServer) { + s.RegisterService(&Porter_ServiceDesc, srv) +} + +func _Porter_ListInstallations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1alpha1.ListInstallationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PorterServer).ListInstallations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/porter.v1alpha1.Porter/ListInstallations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PorterServer).ListInstallations(ctx, req.(*v1alpha1.ListInstallationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Porter_ListInstallationLatestOutputs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1alpha1.ListInstallationLatestOutputRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PorterServer).ListInstallationLatestOutputs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/porter.v1alpha1.Porter/ListInstallationLatestOutputs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PorterServer).ListInstallationLatestOutputs(ctx, req.(*v1alpha1.ListInstallationLatestOutputRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Porter_ServiceDesc is the grpc.ServiceDesc for Porter service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Porter_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "porter.v1alpha1.Porter", + HandlerType: (*PorterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListInstallations", + Handler: _Porter_ListInstallations_Handler, + }, + { + MethodName: "ListInstallationLatestOutputs", + Handler: _Porter_ListInstallationLatestOutputs_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "porter/v1alpha1/porter.proto", +} diff --git a/go.mod b/go.mod index 739df6df6..5c6c56a99 100644 --- a/go.mod +++ b/go.mod @@ -33,8 +33,10 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/ghodss/yaml v1.0.0 github.com/google/go-cmp v0.5.9 - github.com/google/go-containerregistry v0.13.0 + github.com/google/go-containerregistry v0.15.2 + github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-plugin v1.4.0 @@ -45,16 +47,19 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/mmcdole/gofeed v1.2.1 github.com/moby/buildkit v0.11.5 - github.com/moby/term v0.0.0-20221120202655-abb19827d345 + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 github.com/olekukonko/tablewriter v0.0.5 github.com/opencontainers/go-digest v1.0.0 github.com/osteele/liquid v1.3.0 github.com/pelletier/go-toml v1.9.5 + github.com/prometheus/client_golang v1.14.0 github.com/spf13/afero v1.9.5 - github.com/spf13/cobra v1.6.1 + github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.14.0 github.com/stretchr/testify v1.8.2 + github.com/tidwall/gjson v1.14.4 + github.com/tidwall/sjson v1.2.5 github.com/xeipuuv/gojsonschema v1.2.0 go.mongodb.org/mongo-driver v1.11.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 @@ -72,13 +77,14 @@ require ( gopkg.in/AlecAivazis/survey.v1 v1.8.8 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 ) require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/PaesslerAG/gval v1.0.0 // indirect github.com/PuerkitoBio/goquery v1.8.0 // indirect github.com/Shopify/logrus-bugsnag v0.0.0-20230117174420-439a4b8ba167 // indirect @@ -146,7 +152,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/kr/pty v1.1.5 // indirect github.com/magiconair/properties v1.8.1 // indirect @@ -175,13 +181,12 @@ require ( github.com/nxadm/tail v1.4.8 // indirect github.com/oklog/run v1.0.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect + github.com/opencontainers/image-spec v1.1.0-rc3 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/osteele/tuesday v1.0.3 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect @@ -193,11 +198,13 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/theupdateframework/notary v0.6.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect github.com/ulikunitz/xz v0.5.10 // indirect - github.com/vbatts/tar-split v0.11.2 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect github.com/weppos/publicsuffix-go v0.5.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.1 // indirect @@ -216,14 +223,14 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.2.0 // indirect - golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/oauth2 v0.6.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sys v0.7.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.1.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect @@ -235,8 +242,9 @@ require ( k8s.io/client-go v0.26.2 // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +//replace get.porter.sh/magefiles v0.3.3 => ../magefiles diff --git a/go.sum b/go.sum index 935073272..5e4173dbc 100644 --- a/go.sum +++ b/go.sum @@ -25,7 +25,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= @@ -52,6 +52,7 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.15.5+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -60,8 +61,8 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0 github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= @@ -210,7 +211,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= @@ -395,8 +396,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.0.0-20191015185424-71da34e4d9b3/go.mod h1:ZXFeSndFcK4vB1NR4voH1Zm38K7ViUNiYtfIBDxrwf0= -github.com/google/go-containerregistry v0.13.0 h1:y1C7Z3e149OJbOPDBxLYR8ITPz8dTKqQwjErKVHJC8k= -github.com/google/go-containerregistry v0.13.0/go.mod h1:J9FQ+eSS4a1aC2GNZxvNpbWhgp0487v+cgiilB4FqDo= +github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE= +github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -420,6 +421,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -437,6 +439,7 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -485,7 +488,6 @@ github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -526,8 +528,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= -github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= @@ -627,8 +629,8 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= -github.com/moby/term v0.0.0-20221120202655-abb19827d345 h1:J9c53/kxIH+2nTKBEfZYFMlhghtHpIHSXpm5VRGHSnU= -github.com/moby/term v0.0.0-20221120202655-abb19827d345/go.mod h1:15ce4BGCFxt7I5NQKT+HV0yEDxmf6fSysfEDiVo3zFM= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -679,8 +681,8 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= +github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -788,7 +790,6 @@ github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -810,8 +811,8 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -837,6 +838,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -844,8 +846,16 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0= github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa h1:XOFp/3aBXlqmOFAg3r6e0qQjPnK5I970LilqX+Is1W8= @@ -860,9 +870,9 @@ github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= -github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= +github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= +github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= +github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= @@ -1002,8 +1012,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1050,8 +1060,8 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1065,8 +1075,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1155,6 +1165,7 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1162,8 +1173,8 @@ golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1173,8 +1184,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1239,8 +1250,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/mage/setup/tools.go b/mage/setup/tools.go index d19e05dcf..189f78883 100644 --- a/mage/setup/tools.go +++ b/mage/setup/tools.go @@ -1,11 +1,23 @@ package setup import ( + "os/exec" + "runtime" + "github.com/carolynvs/magex/mgx" "github.com/carolynvs/magex/pkg" + "github.com/carolynvs/magex/pkg/archive" + "github.com/carolynvs/magex/pkg/downloads" + "github.com/magefile/mage/mg" ) func EnsureProtobufTools() { + //TODO: add more tools + // https://github.com/bufbuild/buf/releases protoc-gen-buf-breaking, protoc-gen-buf-lint + // protoc https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip`` + //TODO: add more tools + // https://github.com/bufbuild/buf/releases protoc-gen-buf-breaking, protoc-gen-buf-lint + // protoc https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip`` mgx.Must(pkg.EnsurePackageWith(pkg.EnsurePackageOptions{ Name: "google.golang.org/protobuf/cmd/protoc-gen-go", DefaultVersion: "v1.28", @@ -17,3 +29,67 @@ func EnsureProtobufTools() { VersionCommand: "--version", })) } + +// IsCommandInPath determines if a command can be called based on the current PATH. +func IsCommandInPath(cmd string) (bool, error) { + _, err := exec.LookPath(cmd) + if err != nil { + return false, err + } + return true, nil +} + +func EnsureBufBuild() { + mg.Deps(EnsureProtobufTools) + if ok, _ := pkg.IsCommandAvailable("buf", "--version", "1.11.0"); ok { + return + } + opts := downloads.DownloadOptions{ + UrlTemplate: "https://github.com/bufbuild/buf/releases/download/v{{.VERSION}}/buf-{{.GOOS}}-{{.GOARCH}}{{.EXT}}", + Name: "buf", + Version: "1.11.0", + OsReplacement: map[string]string{ + "darwin": "Darwin", + "linux": "Linux", + "windows": "Windows", + }, + ArchReplacement: map[string]string{ + "amd64": "x86_64", + }, + } + err := downloads.DownloadToGopathBin(opts) + mgx.Must(err) +} + +func EnsureGRPCurl() { + if ok, _ := IsCommandInPath("grpcurl"); ok { + return + } + + target := "grpcurl{{.EXT}}" + if runtime.GOOS == "windows" { + target = "grpcurl.exe" + } + + opts := archive.DownloadArchiveOptions{ + DownloadOptions: downloads.DownloadOptions{ + UrlTemplate: "https://github.com/fullstorydev/grpcurl/releases/download/v{{.VERSION}}/grpcurl_{{.VERSION}}_{{.GOOS}}_{{.GOARCH}}{{.EXT}}", + Name: "grpcurl", + Version: "1.8.7", + OsReplacement: map[string]string{ + "darwin": "osx", + }, + ArchReplacement: map[string]string{ + "amd64": "x86_64", + }, + }, + ArchiveExtensions: map[string]string{ + "linux": ".tar.gz", + "darwin": ".tar.gz", + "windows": ".zip", + }, + TargetFileTemplate: target, + } + err := archive.DownloadToGopathBin(opts) + mgx.Must(err) +} diff --git a/magefile.go b/magefile.go index d8cf2871b..039261c4d 100644 --- a/magefile.go +++ b/magefile.go @@ -56,6 +56,12 @@ func CheckGoVersion() { tools.EnforceGoVersion(GoVersion) } +func GenerateGRPCProtobufs() { + mg.Deps(setup.EnsureBufBuild) + must.Command("buf", "build").In("proto").RunV() + must.Command("buf", "generate").In("proto").RunV() +} + // Builds all code artifacts in the repository func Build() { mg.SerialDeps(InstallBuildTools, BuildPorter, BuildExecMixin, BuildAgent, DocsGen) @@ -63,7 +69,7 @@ func Build() { } func InstallBuildTools() { - mg.Deps(setup.EnsureProtobufTools) + mg.Deps(setup.EnsureProtobufTools, setup.EnsureGRPCurl, setup.EnsureBufBuild) } // Build the porter client and runtime @@ -73,6 +79,38 @@ func BuildPorter() { mgx.Must(releases.BuildAll(PKG, "porter", "bin")) } +// TODO: add support to decouple dir and command name to magefile repo +// TODO: add support for additional ldflags to magefile repo +// Build the porter client and runtime with gRPC server enabled +func XBuildPorterGRPCServer() { + var g errgroup.Group + supportedClientGOOS := []string{"linux", "darwin", "windows"} + supportedClientGOARCH := []string{"amd64", "arm64"} + srcCmd := "porter" + srcPath := "./cmd/" + srcCmd + outPath := "bin/dev" + info := releases.LoadMetadata() + ldflags := fmt.Sprintf("-w -X main.includeGRPCServer=true -X %s/pkg.Version=%s -X %s/pkg.Commit=%s", PKG, info.Version, PKG, info.Commit) + os.MkdirAll(filepath.Dir(outPath), 0770) + for _, goos := range supportedClientGOOS { + goos := goos + for _, goarch := range supportedClientGOARCH { + goarch := goarch + g.Go(func() error { + cmdName := fmt.Sprintf("%s-api-server-%s-%s", srcCmd, goos, goarch) + if goos == "windows" { + cmdName = cmdName + ".exe" + } + out := filepath.Join(outPath, cmdName) + return shx.Command("go", "build", "-ldflags", ldflags, "-o", out, srcPath). + Env("CGO_ENABLED=0", "GO111MODULE=on", "GOOS="+goos, "GOARCH="+goarch). + RunV() + }) + } + } + mgx.Must(g.Wait()) +} + func copySchema() { // Copy the porter manifest schema into our templates directory with the other schema // We can't use symbolic links because that doesn't work on windows @@ -95,9 +133,16 @@ func BuildAgent() { releases.XBuild(PKG, "agent", "bin", "linux", "amd64") } +// Cross compile agent for multiple archs in linux +func XBuildAgent() { + mg.Deps(BuildAgent) + releases.XBuild(PKG, "agent", "bin", "linux", "arm64") +} + // Cross-compile porter and the exec mixin func XBuildAll() { - mg.Deps(XBuildPorter, XBuildMixins, BuildAgent) + mg.Deps(XBuildPorter, XBuildMixins, XBuildAgent) + mg.SerialDeps(XBuildPorterGRPCServer) } // Cross-compile porter @@ -251,6 +296,21 @@ func TestSmoke() error { return shx.Command("go", "test", "-count=1", "-timeout=20m", "-tags", "smoke", v, "./tests/smoke/...").CollapseArgs().RunV() } +// Run grpc service tests +func TestGRPCService() { + var run string + runTest := os.Getenv("PORTER_RUN_TEST") + if runTest != "" { + run = "-run=" + runTest + } + + verbose := "" + if mg.Verbose() { + verbose = "-v" + } + must.Command("go", "test", verbose, "-timeout=5m", run, "./tests/grpc/...").CollapseArgs().RunV() +} + func getRegistry() string { registry := os.Getenv("PORTER_REGISTRY") if registry == "" { @@ -266,6 +326,22 @@ func BuildImages() { buildImages(registry, info) } +func buildGRPCProtocImage() { + var g errgroup.Group + + enableBuildKit := "DOCKER_BUILDKIT=1" + g.Go(func() error { + img := "protoc:local" + err := shx.Command("docker", "build", "-t", img, "-f", "build/protoc.Dockerfile", "."). + Env(enableBuildKit).RunV() + if err != nil { + return err + } + return nil + }) + mgx.Must(g.Wait()) +} + func buildImages(registry string, info releases.GitMetadata) { var g errgroup.Group @@ -304,7 +380,6 @@ func buildImages(registry string, info releases.GitMetadata) { return shx.Run("docker", "tag", img, fmt.Sprintf("%s/workshop:%s", registry, info.Permalink)) }) - mgx.Must(g.Wait()) } @@ -340,6 +415,41 @@ func pushImagesTo(registry string, info releases.GitMetadata) { } } +func PublishServerMultiArchImages() { + registry := getRegistry() + info := releases.LoadMetadata() + buildAndPushServerMultiArch(registry, info) +} + +func buildAndPushServerMultiArch(registry string, info releases.GitMetadata) { + img := fmt.Sprintf("%s/server:%s", registry, info.Version) + must.RunV("docker", "buildx", "create", "--use") + must.RunV("docker", "buildx", "bake", "-f", "docker-bake.json", "--push", "--set", "server.tags="+img, "server") +} + +// Build a local image for the server based off of local architecture +func BuildLocalServerImage() { + registry := getRegistry() + info := releases.LoadMetadata() + goarch := runtime.GOARCH + buildServerImage(registry, info, goarch) +} + +// Builds an image for the server based off of the goarch +func buildServerImage(registry string, info releases.GitMetadata, goarch string) { + var platform string + switch goarch { + case "arm64": + platform = "linux/arm64" + case "amd64": + platform = "linux/amd64" + default: + platform = "linux/amd64" + } + img := fmt.Sprintf("%s/server:%s", registry, info.Version) + must.RunV("docker", "build", "-f", "build/images/server/Dockerfile", "-t", img, "--platform="+platform, ".") +} + func pushImages(registry string, tag string) { pushImage(fmt.Sprintf("%s/porter:%s", registry, tag)) pushImage(fmt.Sprintf("%s/porter-agent:%s", registry, tag)) diff --git a/pkg/grpc/portergrpc/context.go b/pkg/grpc/portergrpc/context.go new file mode 100644 index 000000000..acd80ba34 --- /dev/null +++ b/pkg/grpc/portergrpc/context.go @@ -0,0 +1,28 @@ +package portergrpc + +import ( + "context" + "errors" + + "get.porter.sh/porter/pkg/porter" +) + +type ctxKey int + +const porterConnCtxKey ctxKey = 0 + +// GetPorterConnectionFromContext returns the porter connection from the give context. +// Use AddPorterConnectionToContext to add one. +func GetPorterConnectionFromContext(ctx context.Context) (*porter.Porter, error) { + p, ok := ctx.Value(porterConnCtxKey).(*porter.Porter) + if !ok { + return nil, errors.New("Unable to find porter connection in context") + } + return p, nil +} + +// AddPorterConnectionToContext adds the porter connection to the given context +// use GetPorterConnectionFromContext to read it back out +func AddPorterConnectionToContext(p *porter.Porter, ctx context.Context) context.Context { + return context.WithValue(ctx, porterConnCtxKey, p) +} diff --git a/pkg/grpc/portergrpc/context_test.go b/pkg/grpc/portergrpc/context_test.go new file mode 100644 index 000000000..1502eb07b --- /dev/null +++ b/pkg/grpc/portergrpc/context_test.go @@ -0,0 +1,33 @@ +package portergrpc + +import ( + "context" + "testing" + + "get.porter.sh/porter/pkg/porter" + "github.com/stretchr/testify/assert" +) + +func TestGetPorterConnectionFromContextReturnsErrIfNoConnectionInContext(t *testing.T) { + ctx := context.Background() + p, err := GetPorterConnectionFromContext(ctx) + assert.Nil(t, p) + assert.EqualError(t, err, "Unable to find porter connection in context") +} + +func TestGetPorterConnectionFromContextReturnsPorterConnection(t *testing.T) { + p := porter.New() + ctx := context.Background() + ctx = context.WithValue(ctx, porterConnCtxKey, p) + newP, err := GetPorterConnectionFromContext(ctx) + assert.Nil(t, err) + assert.Equal(t, p, newP) +} +func TestAddPorterConnectionToContextReturnsContextUpdatedWithPorterConnection(t *testing.T) { + p := porter.New() + ctx := context.Background() + ctx = AddPorterConnectionToContext(p, ctx) + newP, ok := ctx.Value(porterConnCtxKey).(*porter.Porter) + assert.True(t, ok) + assert.Equal(t, p, newP) +} diff --git a/pkg/grpc/portergrpc/installation.go b/pkg/grpc/portergrpc/installation.go new file mode 100644 index 000000000..174f0f333 --- /dev/null +++ b/pkg/grpc/portergrpc/installation.go @@ -0,0 +1,125 @@ +package portergrpc + +import ( + "context" + "encoding/json" + "fmt" + + iGRPCv1alpha1 "get.porter.sh/porter/gen/proto/go/porterapis/installation/v1alpha1" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/tracing" + "google.golang.org/protobuf/encoding/protojson" +) + +func newInstallationOptsFromLabels(labels map[string]string) []string { + var retLabels []string + for k, v := range labels { + retLabels = append(retLabels, fmt.Sprintf("%s=%s", k, v)) + } + return retLabels +} + +// populateGRPCInstallation populates a GRPC Installation (generated from protobuf) +// a native porter DisplayInstallation +func populateGRPCInstallation(ctx context.Context, inst porter.DisplayInstallation, gInst *iGRPCv1alpha1.Installation) error { + _, log := tracing.StartSpan(ctx) + defer log.EndSpan() + bInst, err := json.Marshal(inst) + if err != nil { + return log.Errorf("porter.DisplayInstallation marshal error: %e", err) + } + pjum := protojson.UnmarshalOptions{} + err = pjum.Unmarshal(bInst, gInst) + if err != nil { + return log.Errorf("installation GRPC Installation unmarshal error: %e", err) + } + return nil +} + +// populateGRPCPorterValue populates a GRPC PorterValue (generated from protobuf) +// from a native porter DisplayValue +func populateGRPCPorterValue(ctx context.Context, dv porter.DisplayValue, gInstOut *iGRPCv1alpha1.PorterValue) error { + _, log := tracing.StartSpan(ctx) + defer log.EndSpan() + bInstOut, err := json.Marshal(dv) + if err != nil { + return log.Errorf("PorterValue marshal error: %e", err) + } + pjum := protojson.UnmarshalOptions{} + err = pjum.Unmarshal(bInstOut, gInstOut) + if err != nil { + return log.Errorf("installation GRPC InstallationOutputs unmarshal error: %e", err) + } + return nil +} + +// ListInstallations takes a GRPC ListInstallationsRequest and returns a filtered list of +// porter installations as a GRPC ListInstallationsResponse +func (s *PorterServer) ListInstallations(ctx context.Context, req *iGRPCv1alpha1.ListInstallationsRequest) (*iGRPCv1alpha1.ListInstallationsResponse, error) { + ctx, log := tracing.StartSpan(ctx) + defer log.EndSpan() + p, err := GetPorterConnectionFromContext(ctx) + // Maybe try to setup a new porter connection instead of erring? + if err != nil { + return nil, err + } + opts := porter.ListOptions{ + Name: req.GetName(), + Namespace: req.GetNamespace(), + Labels: newInstallationOptsFromLabels(req.GetLabels()), + AllNamespaces: req.GetAllNamespaces(), + Skip: req.GetSkip(), + Limit: req.GetLimit(), + } + installations, err := p.ListInstallations(ctx, opts) + if err != nil { + return nil, err + } + insts := []*iGRPCv1alpha1.Installation{} + for _, pInst := range installations { + gInst := &iGRPCv1alpha1.Installation{} + err := populateGRPCInstallation(ctx, pInst, gInst) + if err != nil { + return nil, err + } + insts = append(insts, gInst) + } + res := iGRPCv1alpha1.ListInstallationsResponse{ + Installation: insts, + } + return &res, nil +} + +// ListInstallationLatestOutputs takes a GRPC ListInstallationLatestOutputRequest and returns +// the most recent outputs for the porter installation as a GRPC ListInstallationLatestOutputResponse +func (s *PorterServer) ListInstallationLatestOutputs(ctx context.Context, req *iGRPCv1alpha1.ListInstallationLatestOutputRequest) (*iGRPCv1alpha1.ListInstallationLatestOutputResponse, error) { + ctx, log := tracing.StartSpan(ctx) + defer log.EndSpan() + p, err := GetPorterConnectionFromContext(ctx) + // Maybe try to setup a new porter connection instead of erring? + if err != nil { + return nil, err + } + + opts := porter.OutputListOptions{} + opts.Name = req.GetName() + opts.Namespace = req.GetNamespace() + opts.Format = "json" + pdv, err := p.ListBundleOutputs(ctx, &opts) + if err != nil { + return nil, err + } + gInstOuts := []*iGRPCv1alpha1.PorterValue{} + for _, dv := range pdv { + gInstOut := &iGRPCv1alpha1.PorterValue{} + err = populateGRPCPorterValue(ctx, dv, gInstOut) + if err != nil { + return nil, err + } + gInstOuts = append(gInstOuts, gInstOut) + } + res := &iGRPCv1alpha1.ListInstallationLatestOutputResponse{ + Outputs: gInstOuts, + } + return res, nil +} diff --git a/pkg/grpc/portergrpc/installation_test.go b/pkg/grpc/portergrpc/installation_test.go new file mode 100644 index 000000000..3d257a028 --- /dev/null +++ b/pkg/grpc/portergrpc/installation_test.go @@ -0,0 +1,139 @@ +package portergrpc + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + iGRPC "get.porter.sh/porter/gen/proto/go/porterapis/installation/v1alpha1" + "get.porter.sh/porter/pkg/cnab" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/storage" + "get.porter.sh/porter/tests" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/encoding/protojson" + "k8s.io/utils/pointer" +) + +type instInfo struct { + namespace string + name string +} + +func TestListInstallationReturnsListOfCorrectPorterInstallations(t *testing.T) { + testNamespace := "test" + testInstallationName := "foo" + filterOpts := []struct { + name string + opts *iGRPC.ListInstallationsRequest + }{ + { + name: "FilterByAllNamespaces", + opts: &iGRPC.ListInstallationsRequest{AllNamespaces: pointer.Bool(true)}, + }, + { + name: "FilterByNamespace", + opts: &iGRPC.ListInstallationsRequest{Namespace: &testNamespace}, + }, + { + name: "FilterByInstallationNameAndNamespace", + opts: &iGRPC.ListInstallationsRequest{Namespace: &testNamespace, Name: testInstallationName}, + }, + } + tests := []struct { + name string + instInfo []instInfo + // Number of expected installations when filtering by all namespaces, all installations in a single namespace, and a single installation in a namespace + numExpInsts []int + }{ + { + name: "NoInstallations", + instInfo: []instInfo{}, + numExpInsts: []int{0, 0, 0}, + }, + { + name: "SingleInstallationDefaultNamespace", + instInfo: []instInfo{ + {namespace: "", name: "test"}, + }, + numExpInsts: []int{1, 0, 0}, + }, + { + name: "SingleInstallationInMultipleNamespaces", + instInfo: []instInfo{ + {namespace: testNamespace, name: testInstallationName}, + {namespace: "bar", name: "test"}, + }, + numExpInsts: []int{2, 1, 1}, + }, + { + name: "MultipleInstallationSInMultipleNamespaces", + instInfo: []instInfo{ + {namespace: "foo", name: "test1"}, + {namespace: "foo", name: "test2"}, + {namespace: testNamespace, name: testInstallationName}, + {namespace: testNamespace, name: "test4"}, + }, + numExpInsts: []int{4, 2, 1}, + }, + } + for _, test := range tests { + ctx, insts := setupTestPorterWithInstallations(t, test.instInfo) + for i, opts := range filterOpts { + t.Run(fmt.Sprintf("%s%s", test.name, opts.name), func(t *testing.T) { + instSvc := PorterServer{} + resp, err := instSvc.ListInstallations(ctx, opts.opts) + installations := resp.GetInstallation() + assert.Nil(t, err) + assert.Len(t, installations, test.numExpInsts[i]) + verifyInstallations(t, installations, insts) + }) + } + } +} + +func TestListInstallationsReturnsErrorIfUnableToGetPorterConnectionFromRequestContext(t *testing.T) { + instSvc := PorterServer{} + req := &iGRPC.ListInstallationsRequest{} + ctx := context.TODO() + resp, err := instSvc.ListInstallations(ctx, req) + assert.Error(t, err) + assert.Nil(t, resp) + +} + +func setupTestPorterWithInstallations(t *testing.T, installations []instInfo) (context.Context, map[string]porter.DisplayInstallation) { + p := porter.NewTestPorter(t) + insts := map[string]porter.DisplayInstallation{} + for _, inst := range installations { + installation := storage.NewInstallation(inst.namespace, inst.name) + storeInst := p.TestInstallations.CreateInstallation(installation, p.TestInstallations.SetMutableInstallationValues, func(i *storage.Installation) { + // Overwrite the default ID set by SetMutableInstallationValues because it is always the same + i.ID = uuid.NewString() + i.Status.BundleVersion = "v0.1.0" + i.Status.ResultStatus = cnab.StatusSucceeded + i.Bundle.Repository = "test-bundle" + i.Bundle.Version = "v0.1.0" + }) + insts[storeInst.ID] = porter.NewDisplayInstallation(storeInst) + } + ctx := AddPorterConnectionToContext(p.Porter, context.TODO()) + return ctx, insts +} + +func verifyInstallations(t *testing.T, installations []*iGRPC.Installation, allInsts map[string]porter.DisplayInstallation) { + for _, inst := range installations { + i, ok := allInsts[inst.Id] + assert.True(t, ok) + bExpInst, err := json.Marshal(i) + assert.NoError(t, err) + grpcExpInst, err := tests.GRPCDisplayInstallationExpectedJSON(bExpInst) + assert.NoError(t, err) + pjm := protojson.MarshalOptions{EmitUnpopulated: true} + bActInst, err := pjm.Marshal(inst) + assert.NoError(t, err) + assert.JSONEq(t, string(grpcExpInst), string(bActInst)) + } +} diff --git a/pkg/grpc/portergrpc/portergrpc.go b/pkg/grpc/portergrpc/portergrpc.go new file mode 100644 index 000000000..53f6201a9 --- /dev/null +++ b/pkg/grpc/portergrpc/portergrpc.go @@ -0,0 +1,41 @@ +package portergrpc + +import ( + "context" + + pGRPC "get.porter.sh/porter/gen/proto/go/porterapis/porter/v1alpha1" + "get.porter.sh/porter/pkg/config" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/secrets" + secretsplugin "get.porter.sh/porter/pkg/secrets/pluginstore" + "get.porter.sh/porter/pkg/storage" + storageplugin "get.porter.sh/porter/pkg/storage/pluginstore" + "google.golang.org/grpc" +) + +// PorterServer defines the struct for managing a porter GRPC server +type PorterServer struct { + PorterConfig *config.Config + pGRPC.UnimplementedPorterServer +} + +// NewPorterServer creates a new instance of the PorterServer for a config +func NewPorterServer(cfg *config.Config) (*PorterServer, error) { + return &PorterServer{PorterConfig: cfg}, nil +} + +// NewConnectionInterceptor creates a middleware interceptor for the GRPC server that manages creating a porter connection for each requested RPC stream. +// If the connection is unable to be created for the RPC then the RPC fails, otherwise the connection is added to the RPC context and the next handler in the +// chain is called +func (s *PorterServer) NewConnectionInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + storage := storage.NewPluginAdapter(storageplugin.NewStore(s.PorterConfig)) + secretStorage := secrets.NewPluginAdapter(secretsplugin.NewStore(s.PorterConfig)) + p := porter.NewFor(s.PorterConfig, storage, secretStorage) + if _, err := p.Connect(ctx); err != nil { + return nil, err + } + defer p.Close() + + ctx = AddPorterConnectionToContext(p, ctx) + return handler(ctx, req) +} diff --git a/pkg/grpc/portergrpc/portergrpc_test.go b/pkg/grpc/portergrpc/portergrpc_test.go new file mode 100644 index 000000000..d25641e2b --- /dev/null +++ b/pkg/grpc/portergrpc/portergrpc_test.go @@ -0,0 +1,29 @@ +package portergrpc + +import ( + "context" + "testing" + + "get.porter.sh/porter/pkg/config" + "get.porter.sh/porter/pkg/porter" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" +) + +func TestNewConnectionInterceptorCallsNextHandlerInTheChainWithThePorterConnectionInTheContext(t *testing.T) { + cfg := config.NewTestConfig(t) + srv := PorterServer{PorterConfig: cfg.Config} + parentUnaryInfo := &grpc.UnaryServerInfo{FullMethod: "SomeService.StreamMethod"} + input := "input" + testHandler := func(ctx context.Context, req interface{}) (interface{}, error) { + p, err := GetPorterConnectionFromContext(ctx) + return p, err + } + ctx := context.Background() + chain := grpc_middleware.ChainUnaryServer(srv.NewConnectionInterceptor) + newP, err := chain(ctx, input, parentUnaryInfo, testHandler) + assert.Nil(t, err) + assert.NotNil(t, newP) + assert.IsType(t, &porter.Porter{}, newP) +} diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go new file mode 100644 index 000000000..20920f3ce --- /dev/null +++ b/pkg/grpc/server.go @@ -0,0 +1,124 @@ +package grpc + +import ( + "context" + "fmt" + "net" + "net/http" + "os" + + pGRPCv1alpha1 "get.porter.sh/porter/gen/proto/go/porterapis/porter/v1alpha1" + "get.porter.sh/porter/pkg/config" + pserver "get.porter.sh/porter/pkg/grpc/portergrpc" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/tracing" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/reflection" +) + +var ( + reg = prometheus.NewRegistry() + // Create some standard server metrics. + grpcMetrics = grpc_prometheus.NewServerMetrics() + + // Create a customized counter metric. + customizedCounterMetric = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "demo_server_say_hello_method_handle_count", + Help: "Total number of RPCs handled on the server.", + }, []string{"name"}) +) + +func init() { + reg.MustRegister(grpcMetrics, customizedCounterMetric) + customizedCounterMetric.WithLabelValues("Test") +} + +type PorterGRPCService struct { + PorterConfig *config.Config + opts *porter.ServiceOptions + ctx context.Context +} + +func NewServer(ctx context.Context, opts *porter.ServiceOptions) (*PorterGRPCService, error) { + pCfg := config.New() + srv := &PorterGRPCService{ + PorterConfig: pCfg, + opts: opts, + ctx: ctx, + } + return srv, nil +} + +func (s *PorterGRPCService) ListenAndServe() (*grpc.Server, error) { + _, log := tracing.StartSpan(s.ctx) + defer log.EndSpan() + log.Infof("Starting gRPC on %v", s.opts.Port) + listener, err := net.Listen("tcp", fmt.Sprintf(":%v", s.opts.Port)) + if err != nil { + return nil, fmt.Errorf("failed to listen on %d: %s", s.opts.Port, err) + } + httpServer := &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: fmt.Sprintf("0.0.0.0:%d", 9092)} + + healthServer := health.NewServer() + psrv, err := pserver.NewPorterServer(s.PorterConfig) + if err != nil { + return nil, err + } + srv := grpc.NewServer( + grpc.StreamInterceptor(grpcMetrics.StreamServerInterceptor()), + grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + grpcMetrics.UnaryServerInterceptor(), + psrv.NewConnectionInterceptor), + ), + ) + reflection.Register(srv) + + pGRPCv1alpha1.RegisterPorterServer(srv, psrv) + healthServer.SetServingStatus(s.opts.ServiceName, grpc_health_v1.HealthCheckResponse_SERVING) + grpc_prometheus.Register(srv) + + srvErrCh := make(chan error, 1) + go func() { + if err := srv.Serve(listener); err != nil { + srvErrCh <- err + } + }() + + select { + case err := <-srvErrCh: + if err != nil { + log.Errorf("failed to serve GRPC listener: %w", err) + os.Exit(1) + } + default: + // Continue if no error is received yet + } + + http.Handle("/metrics", promhttp.Handler()) + + // Start your http server for prometheus. + go func() { + if err := httpServer.ListenAndServe(); err != nil { + srvErrCh <- err + } + }() + select { + case err := <-srvErrCh: + if err != nil { + log.Errorf("Unable to start a http server. %w", err) + os.Exit(1) + } + default: + // Continue if no error is received yet + } + + grpcMetrics.InitializeMetrics(srv) + return srv, nil +} diff --git a/pkg/grpc/server_test.go b/pkg/grpc/server_test.go new file mode 100644 index 000000000..21e034e4c --- /dev/null +++ b/pkg/grpc/server_test.go @@ -0,0 +1 @@ +package grpc diff --git a/pkg/porter/service.go b/pkg/porter/service.go new file mode 100644 index 000000000..a842629a7 --- /dev/null +++ b/pkg/porter/service.go @@ -0,0 +1,10 @@ +package porter + +type ServiceOptions struct { + Port int64 + ServiceName string +} + +func (o *ServiceOptions) Validate() error { + return nil +} diff --git a/pkg/service/service.go b/pkg/service/service.go new file mode 100644 index 000000000..687ab278b --- /dev/null +++ b/pkg/service/service.go @@ -0,0 +1,4 @@ +package service + +type ServiceOpts struct { +} diff --git a/pkg/signals/shutdown.go b/pkg/signals/shutdown.go new file mode 100644 index 000000000..475b29e8d --- /dev/null +++ b/pkg/signals/shutdown.go @@ -0,0 +1,53 @@ +package signals + +import ( + "context" + "time" + + "get.porter.sh/porter/pkg/tracing" + "github.com/spf13/viper" + oteltrace "go.opentelemetry.io/otel/sdk/trace" + "google.golang.org/grpc" +) + +type Shutdown struct { + tracerProvider *oteltrace.TracerProvider + serverShutdownTimeout time.Duration +} + +func NewShutdown(serverShutdownTimeout time.Duration, ctx context.Context) (*Shutdown, error) { + srv := &Shutdown{ + serverShutdownTimeout: serverShutdownTimeout, + } + + return srv, nil +} + +func (s *Shutdown) Graceful(stopCh <-chan struct{}, grpcServer *grpc.Server, ctx context.Context) { + ctx, log := tracing.StartSpan(ctx) + + // wait for SIGTERM or SIGINT + <-stopCh + ctx, cancel := context.WithTimeout(ctx, s.serverShutdownTimeout) + defer cancel() + + // wait for Kubernetes readiness probe to remove this instance from the load balancer + // the readiness check interval must be lower than the timeout + if viper.GetString("level") != "debug" { + time.Sleep(3 * time.Second) + } + + // stop OpenTelemetry tracer provider + if s.tracerProvider != nil { + if err := s.tracerProvider.Shutdown(ctx); err != nil { + log.Warnf("stopping tracer provider: ", err) + } + } + + // determine if the GRPC was started + if grpcServer != nil { + log.Infof("Shutting down GRPC server: ", s.serverShutdownTimeout) + grpcServer.GracefulStop() + } + +} diff --git a/pkg/signals/signal.go b/pkg/signals/signal.go new file mode 100644 index 000000000..f82aafbbd --- /dev/null +++ b/pkg/signals/signal.go @@ -0,0 +1,27 @@ +package signals + +import ( + "os" + "os/signal" +) + +var onlyOneSignalHandler = make(chan struct{}) + +// SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned +// which is closed on one of these signals. If a second signal is caught, the program +// is terminated with exit code 1. +func SetupSignalHandler() (stopCh <-chan struct{}) { + close(onlyOneSignalHandler) // panics when called twice + + stop := make(chan struct{}) + c := make(chan os.Signal, 2) + signal.Notify(c, shutdownSignals...) + go func() { + <-c + close(stop) + <-c + os.Exit(1) // second signal. Exit directly. + }() + + return stop +} diff --git a/pkg/signals/signal_posix.go b/pkg/signals/signal_posix.go new file mode 100644 index 000000000..80d74d277 --- /dev/null +++ b/pkg/signals/signal_posix.go @@ -0,0 +1,11 @@ +//go:build !windows +// +build !windows + +package signals + +import ( + "os" + "syscall" +) + +var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGINT} diff --git a/pkg/signals/signal_windows.go b/pkg/signals/signal_windows.go new file mode 100644 index 000000000..f2015c1a3 --- /dev/null +++ b/pkg/signals/signal_windows.go @@ -0,0 +1,7 @@ +package signals + +import ( + "os" +) + +var shutdownSignals = []os.Signal{os.Interrupt} diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml new file mode 100644 index 000000000..dbaf1372f --- /dev/null +++ b/proto/buf.gen.yaml @@ -0,0 +1,14 @@ +version: v1 +managed: + enabled: true + go_package_prefix: + default: get.porter.sh/porter/gen/proto/go/porterapis + except: + - buf.build/googleapis/googleapis +plugins: + - plugin: go + out: ../gen/proto/go/porterapis + opt: module=get.porter.sh/porter/gen/proto/go/porterapis + - plugin: go-grpc + out: ../gen/proto/go/porterapis + opt: module=get.porter.sh/porter/gen/proto/go/porterapis diff --git a/proto/buf.work.yaml b/proto/buf.work.yaml new file mode 100644 index 000000000..94e6fe5ff --- /dev/null +++ b/proto/buf.work.yaml @@ -0,0 +1,3 @@ +version: v1 +directories: + - porterapis diff --git a/proto/porterapis/buf.lock b/proto/porterapis/buf.lock new file mode 100644 index 000000000..19abf63fb --- /dev/null +++ b/proto/porterapis/buf.lock @@ -0,0 +1,7 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: googleapis + repository: googleapis + commit: 75b4300737fb4efca0831636be94e517 diff --git a/proto/porterapis/buf.md b/proto/porterapis/buf.md new file mode 100644 index 000000000..e69de29bb diff --git a/proto/porterapis/buf.yaml b/proto/porterapis/buf.yaml new file mode 100644 index 000000000..97bac4a1a --- /dev/null +++ b/proto/porterapis/buf.yaml @@ -0,0 +1,10 @@ +version: v1 +name: buf.build/porter/porter +deps: + - buf.build/googleapis/googleapis +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/proto/porterapis/installation/buf.yaml b/proto/porterapis/installation/buf.yaml new file mode 100644 index 000000000..54de6a058 --- /dev/null +++ b/proto/porterapis/installation/buf.yaml @@ -0,0 +1,8 @@ +version: v1 +name: buf.build/porter/installationsapi +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/proto/porterapis/installation/v1alpha1/installation.proto b/proto/porterapis/installation/v1alpha1/installation.proto new file mode 100644 index 000000000..d18c0be01 --- /dev/null +++ b/proto/porterapis/installation/v1alpha1/installation.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; +//option go_package = "get.porter.sh/porter/gen/proto/go/installation/v1alpha1"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; +package installation.v1alpha1; + +message Bundle { + string repository = 1; + string version = 2; +} + +message InstallationStatus { + string runId = 1; + string action = 2; + string resultId = 3; + string resultStatus = 4; + google.protobuf.Timestamp created = 5; + google.protobuf.Timestamp modified = 6; + google.protobuf.Timestamp installed = 7; + google.protobuf.Timestamp uninstalled = 8; + string bundleReference = 9; + string bundleVersion = 10; + string bundleDigest = 11; +} + +message Calculated { + string displayInstallationState = 1; + string displayInstallationStatus = 2; + google.protobuf.NullValue resolvedParameters = 3; +} +message Installation { + // Unique installation ID + string id = 1; + string schemaType = 2; + string schemaVersion = 3; + string name = 4; + string namespace = 5; + Bundle bundle = 6; + repeated string credentialSets = 7; + repeated string parameterSets = 8; + InstallationStatus status = 9; + Calculated calculated = 10 [json_name="_calculated"]; +} + +//Installations +message ListInstallationsRequest { + string name = 1; + optional string namespace = 2; + optional int64 limit = 3; + optional int64 skip = 4; + map labels = 5; + optional bool allNamespaces = 6; +} + +message ListInstallationsResponse { + repeated Installation installation = 1; +} + +//InstallationRuns +message InstallationRun { + int64 id = 1; + string bundle = 2; + string version = 3; + string action = 4; + map paramters = 5; + google.protobuf.Timestamp started = 6; + google.protobuf.Timestamp stopped = 7; + string status = 8; +} + +message ListInstallationRunsRequest { + Installation installation = 1; +} + +message ListInstallationRunsResponse { + repeated InstallationRun run = 1; +} + +message PorterValue { + string name = 1; + string type = 2; + bool sensitive = 3; + google.protobuf.Value value = 4; +} + +message InstallationOutputs { + repeated PorterValue output = 1; +} + +message ListInstallationLatestOutputRequest { + string name = 1; + optional string namespace = 2; +} + +//InstallationRunOutputs +message ListInstallationLatestOutputResponse { + repeated PorterValue outputs = 1; +} \ No newline at end of file diff --git a/proto/porterapis/porter/buf.yaml b/proto/porterapis/porter/buf.yaml new file mode 100644 index 000000000..cf86b8789 --- /dev/null +++ b/proto/porterapis/porter/buf.yaml @@ -0,0 +1,8 @@ +version: v1 +name: buf.build/porter/porter +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/proto/porterapis/porter/v1alpha1/porter.proto b/proto/porterapis/porter/v1alpha1/porter.proto new file mode 100644 index 000000000..a7621c021 --- /dev/null +++ b/proto/porterapis/porter/v1alpha1/porter.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +//option go_package = "get.porter.sh/porter/gen/proto/go/installation/v1alpha1"; +package porter.v1alpha1; + +import "installation/v1alpha1/installation.proto"; + +service Porter { + //Returns a list of all installations + rpc ListInstallations (installation.v1alpha1.ListInstallationsRequest) returns (installation.v1alpha1.ListInstallationsResponse) {} + + //Returns a list of all outputs for the latest installation run + rpc ListInstallationLatestOutputs(installation.v1alpha1.ListInstallationLatestOutputRequest) returns(installation.v1alpha1.ListInstallationLatestOutputResponse) {} +} \ No newline at end of file diff --git a/tests/grpc/installation_test.go b/tests/grpc/installation_test.go new file mode 100644 index 000000000..1d48e183f --- /dev/null +++ b/tests/grpc/installation_test.go @@ -0,0 +1,187 @@ +package grpc + +import ( + "bytes" + "context" + "encoding/json" + "strconv" + "testing" + + iGRPC "get.porter.sh/porter/gen/proto/go/porterapis/installation/v1alpha1" + pGRPC "get.porter.sh/porter/gen/proto/go/porterapis/porter/v1alpha1" + "get.porter.sh/porter/pkg/cnab" + "get.porter.sh/porter/pkg/porter" + "get.porter.sh/porter/pkg/storage" + "get.porter.sh/porter/tests" + "github.com/cnabio/cnab-go/bundle" + "github.com/cnabio/cnab-go/bundle/definition" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/protobuf/encoding/protojson" +) + +type testOutputOpt struct { + name string + value string + bundleOutput bundle.Output +} +type testInstallationOpts struct { + bundleDefs *map[string]*definition.Schema + outputs *[]testOutputOpt +} + +// TODO: add opts structure for different installation options +func newTestInstallation(t *testing.T, namespace, name string, grpcSvr *TestPorterGRPCServer, opts testInstallationOpts) storage.Installation { + //Bundle Definition with required porter-state + bd := definition.Definitions{ + "porter-state": &definition.Schema{ + Type: "string", + Comment: "porter-internal", + }, + } + for name, schema := range *opts.bundleDefs { + bd[name] = schema + } + //Bundle Output with required porter-state + bo := map[string]bundle.Output{ + "porter-state": { + Definition: "porter-state", + Path: "/cnab/app/outputs/porter-state.tgz", + }, + } + for _, out := range *opts.outputs { + bo[out.name] = out.bundleOutput + } + b := bundle.Bundle{ + Definitions: bd, + Outputs: bo, + } + extB := cnab.NewBundle(b) + storeInst := grpcSvr.TestPorter.TestInstallations.CreateInstallation(storage.NewInstallation(namespace, name), grpcSvr.TestPorter.TestInstallations.SetMutableInstallationValues, func(i *storage.Installation) { + i.Status.BundleVersion = "v0.1.0" + i.Status.ResultStatus = cnab.StatusSucceeded + i.Bundle.Repository = "test-bundle" + i.Bundle.Version = "v0.1.0" + }) + c := grpcSvr.TestPorter.TestInstallations.CreateRun(storeInst.NewRun(cnab.ActionInstall, cnab.ExtendedBundle{}), func(sRun *storage.Run) { + sRun.Bundle = b + sRun.ParameterOverrides.Parameters = grpcSvr.TestPorter.SanitizeParameters(sRun.ParameterOverrides.Parameters, sRun.ID, extB) + }) + sRes := grpcSvr.TestPorter.TestInstallations.CreateResult(c.NewResult(cnab.StatusSucceeded)) + for _, out := range *opts.outputs { + grpcSvr.TestPorter.CreateOutput(sRes.NewOutput(out.name, []byte(out.value)), extB) + } + return storeInst +} + +func TestInstall_installationMessage(t *testing.T) { + writeOnly := true + basicInstOpts := testInstallationOpts{ + bundleDefs: &map[string]*definition.Schema{ + "foo": {Type: "string", WriteOnly: &writeOnly}, + "bar": {Type: "string", WriteOnly: &writeOnly}, + }, + outputs: &[]testOutputOpt{ + { + name: "foo", + value: "foo-data", + bundleOutput: bundle.Output{Definition: "foo", Path: "/path/to/foo"}, + }, + { + name: "bar", + value: "bar-data", + bundleOutput: bundle.Output{Definition: "bar", Path: "/path/to/bar"}, + }, + }, + } + tests := []struct { + testName string + instName string + instNamespace string "" + instOpts testInstallationOpts + }{ + { + testName: "basic installation", + instName: "test", + instOpts: basicInstOpts, + }, + { + testName: "another installation", + instName: "another-test", + instOpts: basicInstOpts, + }, + } + for _, test := range tests { + t.Run(test.testName, func(t *testing.T) { + //Server setup + grpcSvr, err := NewTestGRPCServer(t) + require.NoError(t, err) + server := grpcSvr.ListenAndServe() + defer server.Stop() + + //Client setup + ctx := context.TODO() + client, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer client.Close() + instClient := pGRPC.NewPorterClient(client) + + inst := newTestInstallation(t, test.instNamespace, test.instName, grpcSvr, test.instOpts) + + //Call ListInstallations + resp, err := instClient.ListInstallations(ctx, &iGRPC.ListInstallationsRequest{}) + require.NoError(t, err) + assert.Len(t, resp.Installation, 1) + // Validation + validateInstallations(t, inst, resp.GetInstallation()[0]) + + //Call ListInstallationLatestOutputRequest + req := &iGRPC.ListInstallationLatestOutputRequest{Name: test.instName, Namespace: &test.instNamespace} + oresp, err := instClient.ListInstallationLatestOutputs(ctx, req) + require.NoError(t, err) + assert.Len(t, oresp.GetOutputs(), len(*test.instOpts.outputs)) + + oOpts := &porter.OutputListOptions{} + oOpts.Name = test.instName + oOpts.Namespace = test.instNamespace + oOpts.Format = "json" + dvs, err := grpcSvr.TestPorter.ListBundleOutputs(ctx, oOpts) + require.NoError(t, err) + + //Validation + validateOutputs(t, dvs, oresp) + }) + } +} + +func validateInstallations(t *testing.T, expected storage.Installation, actual *iGRPC.Installation) { + assert.Equal(t, actual.Name, expected.Name) + bExpInst, err := json.Marshal(porter.NewDisplayInstallation(expected)) + require.NoError(t, err) + bExpInst, err = tests.GRPCDisplayInstallationExpectedJSON(bExpInst) + require.NoError(t, err) + pjm := protojson.MarshalOptions{EmitUnpopulated: true} + bActInst, err := pjm.Marshal(actual) + require.NoError(t, err) + var pJson bytes.Buffer + json.Indent(&pJson, bActInst, "", " ") + assert.JSONEq(t, string(bExpInst), string(bActInst)) +} + +func validateOutputs(t *testing.T, dvs porter.DisplayValues, actual *iGRPC.ListInstallationLatestOutputResponse) { + //Get expected json + bExpOuts, err := json.MarshalIndent(dvs, "", " ") + require.NoError(t, err) + pjm := protojson.MarshalOptions{EmitUnpopulated: true, Multiline: true, Indent: " "} + //Get actual json response + for i, gPV := range actual.GetOutputs() { + bActOut, err := pjm.Marshal(gPV) + require.NoError(t, err) + //TODO: make this not dependant on order + bExpOut := gjson.GetBytes(bExpOuts, strconv.Itoa(i)).String() + assert.JSONEq(t, bExpOut, string(bActOut)) + } +} diff --git a/tests/grpc/test_utils.go b/tests/grpc/test_utils.go new file mode 100644 index 000000000..52013c551 --- /dev/null +++ b/tests/grpc/test_utils.go @@ -0,0 +1,73 @@ +package grpc + +import ( + "context" + "fmt" + "net" + "testing" + + pGRPC "get.porter.sh/porter/gen/proto/go/porterapis/porter/v1alpha1" + "get.porter.sh/porter/pkg/config" + pServer "get.porter.sh/porter/pkg/grpc/portergrpc" + "get.porter.sh/porter/pkg/porter" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + + //"go.opentelemetry.io/otel/attribute" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/reflection" + "google.golang.org/grpc/test/bufconn" +) + +type TestPorterGRPCServer struct { + TestPorter *porter.TestPorter + TestPorterConfig *config.TestConfig +} + +var lis *bufconn.Listener + +func NewTestGRPCServer(t *testing.T) (*TestPorterGRPCServer, error) { + srv := &TestPorterGRPCServer{ + TestPorter: porter.NewTestPorter(t), + TestPorterConfig: config.NewTestConfig(t), + } + return srv, nil +} + +func (s *TestPorterGRPCServer) newTestInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + ctx = pServer.AddPorterConnectionToContext(s.TestPorter.Porter, ctx) + h, err := handler(ctx, req) + return h, err +} + +func (s *TestPorterGRPCServer) ListenAndServe() *grpc.Server { + bufSize := 1024 * 1024 + lis = bufconn.Listen(bufSize) + + srv := grpc.NewServer( + grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + s.newTestInterceptor, + ))) + + healthServer := health.NewServer() + reflection.Register(srv) + grpc_health_v1.RegisterHealthServer(srv, healthServer) + pSvc, err := pServer.NewPorterServer(s.TestPorter.Config) + if err != nil { + panic(err) + } + pGRPC.RegisterPorterServer(srv, pSvc) + healthServer.SetServingStatus("test-health", grpc_health_v1.HealthCheckResponse_SERVING) + + go func() { + if err := srv.Serve(lis); err != nil { + panic(fmt.Errorf("failed to serve: %w", err)) + } + }() + return srv +} + +func bufDialer(context.Context, string) (net.Conn, error) { + return lis.Dial() +} diff --git a/tests/helpers.go b/tests/helpers.go index c93508472..f35053418 100644 --- a/tests/helpers.go +++ b/tests/helpers.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" ) // RequireErrorContains fails the test when the error doesn't contain @@ -70,3 +72,23 @@ func RequireOutputContains(t *testing.T, output string, substring string, msgAnd t.FailNow() } } + +// GRPCDisplayInstallationExpectedJSON converts a json byte string from +// a porter.DisplayInstallation to one expected from a GRPC Installation +func GRPCDisplayInstallationExpectedJSON(bExpInst []byte) ([]byte, error) { + // if no credentialSets or parameterSets add as empty list to + // match GRPCInstallation expectations + var err error + empty := make([]string, 0) + emptySets := []string{"credentialSets", "parameterSets"} + for _, es := range emptySets { + res := gjson.GetBytes(bExpInst, es) + if !res.Exists() { + bExpInst, err = sjson.SetBytes(bExpInst, es, empty) + if err != nil { + return nil, err + } + } + } + return bExpInst, nil +} diff --git a/tests/integration/archive_test.go b/tests/integration/archive_test.go index 8a2bfdb4d..ca0604c23 100644 --- a/tests/integration/archive_test.go +++ b/tests/integration/archive_test.go @@ -57,7 +57,7 @@ func TestArchive_StableDigest(t *testing.T) { assert.Equal(p.T(), hash1, getHash(p, archiveFile2), "shasum of archive did not stay the same on the second call to archive") // the archive should match the hash below regardless of OS architecture, user and execution time - consistentHash := "27c2cf6ef0dfac6f120290a79def2e3417656d0d44adc80991d864d7c8c398ed" + consistentHash := "6f63a27bd8fa3886192ce9d4d561d9b2f5d5235b17a140af6d1608921fe00e7f" assert.Equal(p.T(), consistentHash, hash1, "shasum of archive did not match expected hash") // Publish bundle from archive, with new reference