diff --git a/.gitignore b/.gitignore index 12b7ab7bc..b94f87b26 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ _dist/ _proto/*.pb.go bin/ rootfs/tiller +rootfs/rudder vendor/ *.exe .idea/ diff --git a/Makefile b/Makefile index d9d869a3b..dbe8e0334 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,10 @@ -DOCKER_REGISTRY ?= gcr.io -IMAGE_PREFIX ?= kubernetes-helm -SHORT_NAME ?= tiller -TARGETS = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64 -DIST_DIRS = find * -type d -exec -APP = helm +DOCKER_REGISTRY ?= gcr.io +IMAGE_PREFIX ?= kubernetes-helm +SHORT_NAME ?= tiller +SHORT_NAME_RUDDER ?= rudder +TARGETS = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64 +DIST_DIRS = find * -type d -exec +APP = helm # go option GO ?= go @@ -66,6 +67,19 @@ docker-build: check-docker docker-binary docker build --rm -t ${IMAGE} rootfs docker tag ${IMAGE} ${MUTABLE_IMAGE} +.PHONY: docker-binary-rudder +docker-binary-rudder: BINDIR = ./rootfs +docker-binary-rudder: GOFLAGS += -a -installsuffix cgo +docker-binary-rudder: + GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -o $(BINDIR)/rudder $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/rudder + +.PHONY: docker-build-experimental +docker-build-experimental: check-docker docker-binary docker-binary-rudder + docker build --rm -t ${IMAGE} rootfs -f rootfs/Dockerfile.experimental + docker tag ${IMAGE} ${MUTABLE_IMAGE} + docker build --rm -t ${IMAGE_RUDDER} rootfs -f rootfs/Dockerfile.rudder + docker tag ${IMAGE_RUDDER} ${MUTABLE_IMAGE_RUDDER} + .PHONY: test test: build test: TESTFLAGS += -race -v diff --git a/_proto/Makefile b/_proto/Makefile index 078514a9c..39f72d441 100644 --- a/_proto/Makefile +++ b/_proto/Makefile @@ -20,6 +20,10 @@ services_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(services_ services_pbs = $(sort $(wildcard hapi/services/*.proto)) services_pkg = services +rudder_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(rudder_pkg),$(addprefix M,$(rudder_pbs)))) +rudder_pbs = $(sort $(wildcard hapi/rudder/*.proto)) +rudder_pkg = rudder + version_ias = $(subst $(space),$(comma),$(addsuffix =$(import_path)/$(version_pkg),$(addprefix M,$(version_pbs)))) version_pbs = $(sort $(wildcard hapi/version/*.proto)) version_pkg = version @@ -27,7 +31,7 @@ version_pkg = version google_deps = Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any .PHONY: all -all: chart release services version +all: chart release services rudder version .PHONY: chart chart: @@ -41,6 +45,10 @@ release: services: PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias),$(release_ias):$(dst) $(services_pbs) +.PHONY: rudder +rudder: + PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps),$(chart_ias),$(version_ias),$(release_ias):$(dst) $(rudder_pbs) + .PHONY: version version: PATH=../bin:$(PATH) protoc --$(target)_out=plugins=$(plugins),$(google_deps):$(dst) $(version_pbs) diff --git a/_proto/hapi/rudder/rudder.proto b/_proto/hapi/rudder/rudder.proto new file mode 100644 index 000000000..bb724ca45 --- /dev/null +++ b/_proto/hapi/rudder/rudder.proto @@ -0,0 +1,118 @@ +// Copyright 2017 The Kubernetes Authors All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package hapi.services.rudder; + +import "hapi/release/info.proto"; +import "hapi/release/release.proto"; + +option go_package = "rudder"; + +service ReleaseModuleService { + rpc Version(VersionReleaseRequest) returns (VersionReleaseResponse) { + } + + // InstallRelease requests installation of a chart as a new release. + rpc InstallRelease(InstallReleaseRequest) returns (InstallReleaseResponse) { + } + + // DeleteRelease requests deletion of a named release. + rpc DeleteRelease(DeleteReleaseRequest) returns (DeleteReleaseResponse) { + } + + // RollbackRelease rolls back a release to a previous version. + rpc RollbackRelease(RollbackReleaseRequest) returns (RollbackReleaseResponse) { + } + + // UpgradeRelease updates release content. + rpc UpgradeRelease(UpgradeReleaseRequest) returns (UpgradeReleaseResponse) { + } + + // ReleaseStatus retrieves release status. + rpc ReleaseStatus(ReleaseStatusRequest) returns (ReleaseStatusResponse) { + } +} + +message Result { + enum Status { + // No status set + UNKNOWN = 0; + // Operation was successful + SUCCESS = 1; + // Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent) + UNCHANGED = 2; + // Operation failed + ERROR = 3; + } + string info = 1; + repeated string log = 2; +} + +message VersionReleaseRequest { +} + +message VersionReleaseResponse { + string name = 1; // The canonical name of the release module + string version = 2; // The version of the release module +} + +message InstallReleaseRequest { + hapi.release.Release release = 1; +} +message InstallReleaseResponse { + hapi.release.Release release = 1; + Result result = 2; +} + +message DeleteReleaseRequest { + hapi.release.Release release = 1; +} +message DeleteReleaseResponse { + hapi.release.Release release = 1; + Result result = 2; +} + +message UpgradeReleaseRequest{ + hapi.release.Release current = 1; + hapi.release.Release target = 2; + int64 Timeout = 3; + bool Wait = 4; + bool Recreate = 5; +} +message UpgradeReleaseResponse{ + hapi.release.Release release = 1; + Result result = 2; +} + +message RollbackReleaseRequest{ + hapi.release.Release current = 1; + hapi.release.Release target = 2; + int64 Timeout = 3; + bool Wait = 4; + bool Recreate = 5; +} +message RollbackReleaseResponse{ + hapi.release.Release release = 1; + Result result = 2; +} + +message ReleaseStatusRequest{ + hapi.release.Release release = 1; +} +message ReleaseStatusResponse{ + hapi.release.Release release = 1; + hapi.release.Info info = 2; +} diff --git a/cmd/rudder/rudder.go b/cmd/rudder/rudder.go new file mode 100644 index 000000000..0a5a97bff --- /dev/null +++ b/cmd/rudder/rudder.go @@ -0,0 +1,138 @@ +/* +Copyright 2017 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + "fmt" + "net" + + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + + "k8s.io/helm/pkg/kube" + rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder" + "k8s.io/helm/pkg/rudder" + "k8s.io/helm/pkg/tiller" + "k8s.io/helm/pkg/version" +) + +var kubeClient *kube.Client +var clientset internalclientset.Interface + +func main() { + var err error + kubeClient = kube.New(nil) + clientset, err = kubeClient.ClientSet() + if err != nil { + grpclog.Fatalf("Cannot initialize Kubernetes connection: %s", err) + } + + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", rudder.GrpcPort)) + if err != nil { + grpclog.Fatalf("failed to listen: %v", err) + } + grpcServer := grpc.NewServer() + rudderAPI.RegisterReleaseModuleServiceServer(grpcServer, &ReleaseModuleServiceServer{}) + + grpclog.Print("Server starting") + grpcServer.Serve(lis) + grpclog.Print("Server started") +} + +// ReleaseModuleServiceServer provides implementation for rudderAPI.ReleaseModuleServiceServer +type ReleaseModuleServiceServer struct{} + +// Version returns Rudder version based on helm version +func (r *ReleaseModuleServiceServer) Version(ctx context.Context, in *rudderAPI.VersionReleaseRequest) (*rudderAPI.VersionReleaseResponse, error) { + grpclog.Print("version") + return &rudderAPI.VersionReleaseResponse{ + Name: "helm-rudder-native", + Version: version.Version, + }, nil +} + +// InstallRelease creates a release using kubeClient.Create +func (r *ReleaseModuleServiceServer) InstallRelease(ctx context.Context, in *rudderAPI.InstallReleaseRequest) (*rudderAPI.InstallReleaseResponse, error) { + grpclog.Print("install") + b := bytes.NewBufferString(in.Release.Manifest) + err := kubeClient.Create(in.Release.Namespace, b, 500, false) + if err != nil { + grpclog.Printf("error when creating release: %v", err) + } + return &rudderAPI.InstallReleaseResponse{}, err +} + +// DeleteRelease deletes a provided release +func (r *ReleaseModuleServiceServer) DeleteRelease(ctx context.Context, in *rudderAPI.DeleteReleaseRequest) (*rudderAPI.DeleteReleaseResponse, error) { + grpclog.Print("delete") + + resp := &rudderAPI.DeleteReleaseResponse{} + rel := in.Release + vs, err := tiller.GetVersionSet(clientset.Discovery()) + if err != nil { + return resp, fmt.Errorf("Could not get apiVersions from Kubernetes: %v", err) + } + + kept, errs := tiller.DeleteRelease(rel, vs, kubeClient) + rel.Manifest = kept + + allErrors := "" + for _, e := range errs { + allErrors = allErrors + "\n" + e.Error() + } + + if len(allErrors) > 0 { + err = fmt.Errorf(allErrors) + } + + return &rudderAPI.DeleteReleaseResponse{ + Release: rel, + }, err +} + +// RollbackRelease rolls back the release +func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *rudderAPI.RollbackReleaseRequest) (*rudderAPI.RollbackReleaseResponse, error) { + grpclog.Print("rollback") + c := bytes.NewBufferString(in.Current.Manifest) + t := bytes.NewBufferString(in.Target.Manifest) + err := kubeClient.Update(in.Target.Namespace, c, t, in.Recreate, in.Timeout, in.Wait) + return &rudderAPI.RollbackReleaseResponse{}, err +} + +// UpgradeRelease upgrades manifests using kubernetes client +func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) { + grpclog.Print("upgrade") + c := bytes.NewBufferString(in.Current.Manifest) + t := bytes.NewBufferString(in.Target.Manifest) + err := kubeClient.Update(in.Target.Namespace, c, t, in.Recreate, in.Timeout, in.Wait) + // upgrade response object should be changed to include status + return &rudderAPI.UpgradeReleaseResponse{}, err +} + +func (r *ReleaseModuleServiceServer) ReleaseStatus(ctx context.Context, in *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) { + grpclog.Print("status") + + resp, err := kubeClient.Get(in.Release.Namespace, bytes.NewBufferString(in.Release.Manifest)) + in.Release.Info.Status.Resources = resp + return &rudderAPI.ReleaseStatusResponse{ + Release: in.Release, + Info: in.Release.Info, + }, err +} diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index 2f193936e..e5f3a33f3 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -70,11 +70,12 @@ var rootServer *grpc.Server var env = environment.New() var ( - grpcAddr = ":44134" - probeAddr = ":44135" - traceAddr = ":44136" - enableTracing = false - store = storageConfigMap + grpcAddr = ":44134" + probeAddr = ":44135" + traceAddr = ":44136" + enableTracing = false + store = storageConfigMap + remoteReleaseModules = false ) var ( @@ -108,6 +109,7 @@ func main() { p.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on") p.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'") p.BoolVar(&enableTracing, "trace", false, "enable rpc tracing") + p.BoolVar(&remoteReleaseModules, "experimental-release", false, "enable experimental release modules") p.BoolVar(&tlsEnable, "tls", tlsEnableEnvVarDefault(), "enable TLS") p.BoolVar(&tlsVerify, "tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate") @@ -173,7 +175,7 @@ func start(c *cobra.Command, args []string) { srvErrCh := make(chan error) probeErrCh := make(chan error) go func() { - svc := tiller.NewReleaseServer(env, clientset) + svc := tiller.NewReleaseServer(env, clientset, remoteReleaseModules) services.RegisterReleaseServiceServer(rootServer, svc) if err := rootServer.Serve(lstn); err != nil { srvErrCh <- err diff --git a/pkg/proto/hapi/rudder/rudder.pb.go b/pkg/proto/hapi/rudder/rudder.pb.go new file mode 100644 index 000000000..af5577678 --- /dev/null +++ b/pkg/proto/hapi/rudder/rudder.pb.go @@ -0,0 +1,706 @@ +// Code generated by protoc-gen-go. +// source: hapi/rudder/rudder.proto +// DO NOT EDIT! + +/* +Package rudder is a generated protocol buffer package. + +It is generated from these files: + hapi/rudder/rudder.proto + +It has these top-level messages: + Result + VersionReleaseRequest + VersionReleaseResponse + InstallReleaseRequest + InstallReleaseResponse + DeleteReleaseRequest + DeleteReleaseResponse + UpgradeReleaseRequest + UpgradeReleaseResponse + RollbackReleaseRequest + RollbackReleaseResponse + ReleaseStatusRequest + ReleaseStatusResponse +*/ +package rudder + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release" +import hapi_release5 "k8s.io/helm/pkg/proto/hapi/release" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Result_Status int32 + +const ( + // No status set + Result_UNKNOWN Result_Status = 0 + // Operation was successful + Result_SUCCESS Result_Status = 1 + // Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent) + Result_UNCHANGED Result_Status = 2 + // Operation failed + Result_ERROR Result_Status = 3 +) + +var Result_Status_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SUCCESS", + 2: "UNCHANGED", + 3: "ERROR", +} +var Result_Status_value = map[string]int32{ + "UNKNOWN": 0, + "SUCCESS": 1, + "UNCHANGED": 2, + "ERROR": 3, +} + +func (x Result_Status) String() string { + return proto.EnumName(Result_Status_name, int32(x)) +} +func (Result_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +type Result struct { + Info string `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"` + Log []string `protobuf:"bytes,2,rep,name=log" json:"log,omitempty"` +} + +func (m *Result) Reset() { *m = Result{} } +func (m *Result) String() string { return proto.CompactTextString(m) } +func (*Result) ProtoMessage() {} +func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Result) GetInfo() string { + if m != nil { + return m.Info + } + return "" +} + +func (m *Result) GetLog() []string { + if m != nil { + return m.Log + } + return nil +} + +type VersionReleaseRequest struct { +} + +func (m *VersionReleaseRequest) Reset() { *m = VersionReleaseRequest{} } +func (m *VersionReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*VersionReleaseRequest) ProtoMessage() {} +func (*VersionReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +type VersionReleaseResponse struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` +} + +func (m *VersionReleaseResponse) Reset() { *m = VersionReleaseResponse{} } +func (m *VersionReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*VersionReleaseResponse) ProtoMessage() {} +func (*VersionReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *VersionReleaseResponse) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *VersionReleaseResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +type InstallReleaseRequest struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` +} + +func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } +func (m *InstallReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*InstallReleaseRequest) ProtoMessage() {} +func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *InstallReleaseRequest) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +type InstallReleaseResponse struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} } +func (m *InstallReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*InstallReleaseResponse) ProtoMessage() {} +func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *InstallReleaseResponse) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +func (m *InstallReleaseResponse) GetResult() *Result { + if m != nil { + return m.Result + } + return nil +} + +type DeleteReleaseRequest struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` +} + +func (m *DeleteReleaseRequest) Reset() { *m = DeleteReleaseRequest{} } +func (m *DeleteReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteReleaseRequest) ProtoMessage() {} +func (*DeleteReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *DeleteReleaseRequest) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +type DeleteReleaseResponse struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *DeleteReleaseResponse) Reset() { *m = DeleteReleaseResponse{} } +func (m *DeleteReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteReleaseResponse) ProtoMessage() {} +func (*DeleteReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *DeleteReleaseResponse) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +func (m *DeleteReleaseResponse) GetResult() *Result { + if m != nil { + return m.Result + } + return nil +} + +type UpgradeReleaseRequest struct { + Current *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"` + Target *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"` + Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"` + Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"` + Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"` +} + +func (m *UpgradeReleaseRequest) Reset() { *m = UpgradeReleaseRequest{} } +func (m *UpgradeReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*UpgradeReleaseRequest) ProtoMessage() {} +func (*UpgradeReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *UpgradeReleaseRequest) GetCurrent() *hapi_release5.Release { + if m != nil { + return m.Current + } + return nil +} + +func (m *UpgradeReleaseRequest) GetTarget() *hapi_release5.Release { + if m != nil { + return m.Target + } + return nil +} + +func (m *UpgradeReleaseRequest) GetTimeout() int64 { + if m != nil { + return m.Timeout + } + return 0 +} + +func (m *UpgradeReleaseRequest) GetWait() bool { + if m != nil { + return m.Wait + } + return false +} + +func (m *UpgradeReleaseRequest) GetRecreate() bool { + if m != nil { + return m.Recreate + } + return false +} + +type UpgradeReleaseResponse struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *UpgradeReleaseResponse) Reset() { *m = UpgradeReleaseResponse{} } +func (m *UpgradeReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*UpgradeReleaseResponse) ProtoMessage() {} +func (*UpgradeReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *UpgradeReleaseResponse) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +func (m *UpgradeReleaseResponse) GetResult() *Result { + if m != nil { + return m.Result + } + return nil +} + +type RollbackReleaseRequest struct { + Current *hapi_release5.Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"` + Target *hapi_release5.Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"` + Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"` + Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"` + Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"` +} + +func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} } +func (m *RollbackReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*RollbackReleaseRequest) ProtoMessage() {} +func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +func (m *RollbackReleaseRequest) GetCurrent() *hapi_release5.Release { + if m != nil { + return m.Current + } + return nil +} + +func (m *RollbackReleaseRequest) GetTarget() *hapi_release5.Release { + if m != nil { + return m.Target + } + return nil +} + +func (m *RollbackReleaseRequest) GetTimeout() int64 { + if m != nil { + return m.Timeout + } + return 0 +} + +func (m *RollbackReleaseRequest) GetWait() bool { + if m != nil { + return m.Wait + } + return false +} + +func (m *RollbackReleaseRequest) GetRecreate() bool { + if m != nil { + return m.Recreate + } + return false +} + +type RollbackReleaseResponse struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *RollbackReleaseResponse) Reset() { *m = RollbackReleaseResponse{} } +func (m *RollbackReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*RollbackReleaseResponse) ProtoMessage() {} +func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +func (m *RollbackReleaseResponse) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +func (m *RollbackReleaseResponse) GetResult() *Result { + if m != nil { + return m.Result + } + return nil +} + +type ReleaseStatusRequest struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` +} + +func (m *ReleaseStatusRequest) Reset() { *m = ReleaseStatusRequest{} } +func (m *ReleaseStatusRequest) String() string { return proto.CompactTextString(m) } +func (*ReleaseStatusRequest) ProtoMessage() {} +func (*ReleaseStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +func (m *ReleaseStatusRequest) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +type ReleaseStatusResponse struct { + Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Info *hapi_release3.Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` +} + +func (m *ReleaseStatusResponse) Reset() { *m = ReleaseStatusResponse{} } +func (m *ReleaseStatusResponse) String() string { return proto.CompactTextString(m) } +func (*ReleaseStatusResponse) ProtoMessage() {} +func (*ReleaseStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +func (m *ReleaseStatusResponse) GetRelease() *hapi_release5.Release { + if m != nil { + return m.Release + } + return nil +} + +func (m *ReleaseStatusResponse) GetInfo() *hapi_release3.Info { + if m != nil { + return m.Info + } + return nil +} + +func init() { + proto.RegisterType((*Result)(nil), "hapi.services.rudder.Result") + proto.RegisterType((*VersionReleaseRequest)(nil), "hapi.services.rudder.VersionReleaseRequest") + proto.RegisterType((*VersionReleaseResponse)(nil), "hapi.services.rudder.VersionReleaseResponse") + proto.RegisterType((*InstallReleaseRequest)(nil), "hapi.services.rudder.InstallReleaseRequest") + proto.RegisterType((*InstallReleaseResponse)(nil), "hapi.services.rudder.InstallReleaseResponse") + proto.RegisterType((*DeleteReleaseRequest)(nil), "hapi.services.rudder.DeleteReleaseRequest") + proto.RegisterType((*DeleteReleaseResponse)(nil), "hapi.services.rudder.DeleteReleaseResponse") + proto.RegisterType((*UpgradeReleaseRequest)(nil), "hapi.services.rudder.UpgradeReleaseRequest") + proto.RegisterType((*UpgradeReleaseResponse)(nil), "hapi.services.rudder.UpgradeReleaseResponse") + proto.RegisterType((*RollbackReleaseRequest)(nil), "hapi.services.rudder.RollbackReleaseRequest") + proto.RegisterType((*RollbackReleaseResponse)(nil), "hapi.services.rudder.RollbackReleaseResponse") + proto.RegisterType((*ReleaseStatusRequest)(nil), "hapi.services.rudder.ReleaseStatusRequest") + proto.RegisterType((*ReleaseStatusResponse)(nil), "hapi.services.rudder.ReleaseStatusResponse") + proto.RegisterEnum("hapi.services.rudder.Result_Status", Result_Status_name, Result_Status_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for ReleaseModuleService service + +type ReleaseModuleServiceClient interface { + Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error) + // InstallRelease requests installation of a chart as a new release. + InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) + // DeleteRelease requests deletion of a named release. + DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error) + // RollbackRelease rolls back a release to a previous version. + RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error) + // UpgradeRelease updates release content. + UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) + // ReleaseStatus retrieves release status. + ReleaseStatus(ctx context.Context, in *ReleaseStatusRequest, opts ...grpc.CallOption) (*ReleaseStatusResponse, error) +} + +type releaseModuleServiceClient struct { + cc *grpc.ClientConn +} + +func NewReleaseModuleServiceClient(cc *grpc.ClientConn) ReleaseModuleServiceClient { + return &releaseModuleServiceClient{cc} +} + +func (c *releaseModuleServiceClient) Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error) { + out := new(VersionReleaseResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/Version", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *releaseModuleServiceClient) InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) { + out := new(InstallReleaseResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/InstallRelease", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *releaseModuleServiceClient) DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error) { + out := new(DeleteReleaseResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/DeleteRelease", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *releaseModuleServiceClient) RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error) { + out := new(RollbackReleaseResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/RollbackRelease", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *releaseModuleServiceClient) UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) { + out := new(UpgradeReleaseResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *releaseModuleServiceClient) ReleaseStatus(ctx context.Context, in *ReleaseStatusRequest, opts ...grpc.CallOption) (*ReleaseStatusResponse, error) { + out := new(ReleaseStatusResponse) + err := grpc.Invoke(ctx, "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for ReleaseModuleService service + +type ReleaseModuleServiceServer interface { + Version(context.Context, *VersionReleaseRequest) (*VersionReleaseResponse, error) + // InstallRelease requests installation of a chart as a new release. + InstallRelease(context.Context, *InstallReleaseRequest) (*InstallReleaseResponse, error) + // DeleteRelease requests deletion of a named release. + DeleteRelease(context.Context, *DeleteReleaseRequest) (*DeleteReleaseResponse, error) + // RollbackRelease rolls back a release to a previous version. + RollbackRelease(context.Context, *RollbackReleaseRequest) (*RollbackReleaseResponse, error) + // UpgradeRelease updates release content. + UpgradeRelease(context.Context, *UpgradeReleaseRequest) (*UpgradeReleaseResponse, error) + // ReleaseStatus retrieves release status. + ReleaseStatus(context.Context, *ReleaseStatusRequest) (*ReleaseStatusResponse, error) +} + +func RegisterReleaseModuleServiceServer(s *grpc.Server, srv ReleaseModuleServiceServer) { + s.RegisterService(&_ReleaseModuleService_serviceDesc, srv) +} + +func _ReleaseModuleService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).Version(ctx, req.(*VersionReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ReleaseModuleService_InstallRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InstallReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/InstallRelease", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, req.(*InstallReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ReleaseModuleService_DeleteRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/DeleteRelease", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, req.(*DeleteReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ReleaseModuleService_RollbackRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RollbackReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/RollbackRelease", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, req.(*RollbackReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ReleaseModuleService_UpgradeRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpgradeReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/UpgradeRelease", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, req.(*UpgradeReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ReleaseModuleService_ReleaseStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReleaseStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReleaseModuleServiceServer).ReleaseStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/hapi.services.rudder.ReleaseModuleService/ReleaseStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReleaseModuleServiceServer).ReleaseStatus(ctx, req.(*ReleaseStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ReleaseModuleService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "hapi.services.rudder.ReleaseModuleService", + HandlerType: (*ReleaseModuleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Version", + Handler: _ReleaseModuleService_Version_Handler, + }, + { + MethodName: "InstallRelease", + Handler: _ReleaseModuleService_InstallRelease_Handler, + }, + { + MethodName: "DeleteRelease", + Handler: _ReleaseModuleService_DeleteRelease_Handler, + }, + { + MethodName: "RollbackRelease", + Handler: _ReleaseModuleService_RollbackRelease_Handler, + }, + { + MethodName: "UpgradeRelease", + Handler: _ReleaseModuleService_UpgradeRelease_Handler, + }, + { + MethodName: "ReleaseStatus", + Handler: _ReleaseModuleService_ReleaseStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "hapi/rudder/rudder.proto", +} + +func init() { proto.RegisterFile("hapi/rudder/rudder.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 584 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x56, 0xd1, 0x8e, 0xd2, 0x40, + 0x14, 0xa5, 0xcb, 0x52, 0xe0, 0x92, 0x55, 0x32, 0xd9, 0x42, 0xd3, 0xf8, 0x40, 0xfa, 0x60, 0x88, + 0xeb, 0x96, 0x04, 0x7d, 0xf4, 0x45, 0x59, 0xdc, 0xdd, 0x18, 0xd9, 0x64, 0x2a, 0x6e, 0xe2, 0x5b, + 0x17, 0x2e, 0x58, 0x2d, 0x6d, 0x9d, 0x4e, 0xf7, 0x51, 0xfd, 0x1a, 0xff, 0x43, 0xbf, 0xcc, 0xb4, + 0xd3, 0x12, 0x5b, 0xa7, 0x11, 0xd7, 0x84, 0xc4, 0xa7, 0xce, 0xf4, 0x1e, 0xee, 0x9c, 0x73, 0x7a, + 0xe7, 0x04, 0xd0, 0xdf, 0x3b, 0xa1, 0x3b, 0x62, 0xf1, 0x72, 0x89, 0x2c, 0x7b, 0x58, 0x21, 0x0b, + 0x78, 0x40, 0x8e, 0x93, 0x8a, 0x15, 0x21, 0xbb, 0x75, 0x17, 0x18, 0x59, 0xa2, 0x66, 0xf4, 0x05, + 0x1e, 0x3d, 0x74, 0x22, 0x1c, 0xb9, 0xfe, 0x2a, 0x10, 0x70, 0xc3, 0x28, 0x14, 0xb2, 0xa7, 0xa8, + 0x99, 0x1e, 0xa8, 0x14, 0xa3, 0xd8, 0xe3, 0x84, 0xc0, 0x61, 0xf2, 0x1b, 0x5d, 0x19, 0x28, 0xc3, + 0x36, 0x4d, 0xd7, 0xa4, 0x0b, 0x75, 0x2f, 0x58, 0xeb, 0x07, 0x83, 0xfa, 0xb0, 0x4d, 0x93, 0xa5, + 0xf9, 0x0c, 0x54, 0x9b, 0x3b, 0x3c, 0x8e, 0x48, 0x07, 0x9a, 0xf3, 0xd9, 0xab, 0xd9, 0xd5, 0xf5, + 0xac, 0x5b, 0x4b, 0x36, 0xf6, 0x7c, 0x32, 0x99, 0xda, 0x76, 0x57, 0x21, 0x47, 0xd0, 0x9e, 0xcf, + 0x26, 0x17, 0xcf, 0x67, 0xe7, 0xd3, 0xb3, 0xee, 0x01, 0x69, 0x43, 0x63, 0x4a, 0xe9, 0x15, 0xed, + 0xd6, 0xcd, 0x3e, 0x68, 0x6f, 0x91, 0x45, 0x6e, 0xe0, 0x53, 0xc1, 0x82, 0xe2, 0xa7, 0x18, 0x23, + 0x6e, 0xbe, 0x84, 0x5e, 0xb9, 0x10, 0x85, 0x81, 0x1f, 0x61, 0x42, 0xcb, 0x77, 0x36, 0x98, 0xd3, + 0x4a, 0xd6, 0x44, 0x87, 0xe6, 0xad, 0x40, 0xeb, 0x07, 0xe9, 0xeb, 0x7c, 0x6b, 0x5e, 0x80, 0x76, + 0xe9, 0x47, 0xdc, 0xf1, 0xbc, 0xe2, 0x01, 0x64, 0x04, 0xcd, 0x4c, 0x78, 0xda, 0xa9, 0x33, 0xd6, + 0xac, 0xd4, 0xc4, 0xdc, 0x8d, 0x1c, 0x9e, 0xa3, 0xcc, 0x2f, 0xd0, 0x2b, 0x77, 0xca, 0x18, 0xfd, + 0x6d, 0x2b, 0xf2, 0x14, 0x54, 0x96, 0x7a, 0x9c, 0xb2, 0xed, 0x8c, 0x1f, 0x58, 0xb2, 0xef, 0x67, + 0x89, 0xef, 0x40, 0x33, 0xac, 0x79, 0x0e, 0xc7, 0x67, 0xe8, 0x21, 0xc7, 0x7f, 0x55, 0xf2, 0x19, + 0xb4, 0x52, 0xa3, 0xfd, 0x0a, 0xf9, 0xae, 0x80, 0x36, 0x0f, 0xd7, 0xcc, 0x59, 0x4a, 0xa4, 0x2c, + 0x62, 0xc6, 0xd0, 0xe7, 0x7f, 0x20, 0x90, 0xa1, 0xc8, 0x29, 0xa8, 0xdc, 0x61, 0x6b, 0xcc, 0x09, + 0x54, 0xe0, 0x33, 0x50, 0x32, 0x27, 0x6f, 0xdc, 0x0d, 0x06, 0x31, 0xd7, 0xeb, 0x03, 0x65, 0x58, + 0xa7, 0xf9, 0x36, 0x99, 0xaa, 0x6b, 0xc7, 0xe5, 0xfa, 0xe1, 0x40, 0x19, 0xb6, 0x68, 0xba, 0x26, + 0x06, 0xb4, 0x28, 0x2e, 0x18, 0x3a, 0x1c, 0xf5, 0x46, 0xfa, 0x7e, 0xbb, 0x4f, 0xa6, 0xa1, 0x2c, + 0x61, 0xbf, 0x26, 0xfe, 0x50, 0xa0, 0x47, 0x03, 0xcf, 0xbb, 0x71, 0x16, 0x1f, 0xff, 0x5b, 0x17, + 0xbf, 0x2a, 0xd0, 0xff, 0x4d, 0xc4, 0xde, 0x6f, 0x55, 0xd6, 0x49, 0xc4, 0xd8, 0x9d, 0x6f, 0x55, + 0x08, 0x5a, 0xa9, 0xd1, 0x5d, 0x85, 0x3c, 0xcc, 0x82, 0x57, 0xc8, 0x20, 0x45, 0xf4, 0xa5, 0xbf, + 0x0a, 0x44, 0x18, 0x8f, 0xbf, 0x35, 0xb6, 0xdc, 0x5f, 0x07, 0xcb, 0xd8, 0x43, 0x5b, 0x48, 0x25, + 0x2b, 0x68, 0x66, 0xe1, 0x49, 0x4e, 0xe4, 0x26, 0x48, 0x43, 0xd7, 0x78, 0xbc, 0x1b, 0x58, 0xe8, + 0x32, 0x6b, 0x64, 0x03, 0xf7, 0x8a, 0x91, 0x58, 0x75, 0x9c, 0x34, 0x82, 0xab, 0x8e, 0x93, 0xa7, + 0xac, 0x59, 0x23, 0x1f, 0xe0, 0xa8, 0x90, 0x5b, 0xe4, 0x91, 0xbc, 0x81, 0x2c, 0x25, 0x8d, 0x93, + 0x9d, 0xb0, 0xdb, 0xb3, 0x42, 0xb8, 0x5f, 0x1a, 0x4c, 0x52, 0x41, 0x57, 0x7e, 0x09, 0x8d, 0xd3, + 0x1d, 0xd1, 0xbf, 0x9a, 0x59, 0x4c, 0x94, 0x2a, 0x33, 0xa5, 0xd1, 0x59, 0x65, 0xa6, 0x3c, 0xa4, + 0x84, 0x99, 0x85, 0x71, 0xad, 0x32, 0x53, 0x76, 0x39, 0xaa, 0xcc, 0x94, 0xce, 0xbf, 0x59, 0x7b, + 0xd1, 0x7a, 0xa7, 0x0a, 0xc4, 0x8d, 0x9a, 0xfe, 0xc9, 0x78, 0xf2, 0x33, 0x00, 0x00, 0xff, 0xff, + 0x52, 0x0c, 0xa8, 0x50, 0xcb, 0x08, 0x00, 0x00, +} diff --git a/pkg/rudder/client.go b/pkg/rudder/client.go new file mode 100644 index 000000000..219bb010a --- /dev/null +++ b/pkg/rudder/client.go @@ -0,0 +1,91 @@ +/* +Copyright 2017 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rudder // import "k8s.io/helm/pkg/rudder" + +import ( + "fmt" + + "golang.org/x/net/context" + "google.golang.org/grpc" + + rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder" +) + +// GrpcPort specifies port on which rudder will spawn a server +const ( + GrpcPort = 10001 +) + +var grpcAddr = fmt.Sprintf("127.0.0.1:%d", GrpcPort) + +// InstallRelease calls Rudder InstallRelease method which should create provided release +func InstallRelease(rel *rudderAPI.InstallReleaseRequest) (*rudderAPI.InstallReleaseResponse, error) { + //TODO(mkwiek): parametrize this + conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure()) + if err != nil { + return nil, err + } + + defer conn.Close() + client := rudderAPI.NewReleaseModuleServiceClient(conn) + return client.InstallRelease(context.Background(), rel) +} + +// UpgradeRelease calls Rudder UpgradeRelease method which should perform update +func UpgradeRelease(req *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) { + conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer conn.Close() + client := rudderAPI.NewReleaseModuleServiceClient(conn) + return client.UpgradeRelease(context.Background(), req) +} + +// RollbackRelease calls Rudder RollbackRelease method which should perform update +func RollbackRelease(req *rudderAPI.RollbackReleaseRequest) (*rudderAPI.RollbackReleaseResponse, error) { + conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer conn.Close() + client := rudderAPI.NewReleaseModuleServiceClient(conn) + return client.RollbackRelease(context.Background(), req) +} + +// ReleaseStatus calls Rudder ReleaseStatus method which should perform update +func ReleaseStatus(req *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) { + conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer conn.Close() + client := rudderAPI.NewReleaseModuleServiceClient(conn) + return client.ReleaseStatus(context.Background(), req) +} + +// DeleteRelease calls Rudder DeleteRelease method which should uninstall provided release +func DeleteRelease(rel *rudderAPI.DeleteReleaseRequest) (*rudderAPI.DeleteReleaseResponse, error) { + conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure()) + if err != nil { + return nil, err + } + + defer conn.Close() + client := rudderAPI.NewReleaseModuleServiceClient(conn) + return client.DeleteRelease(context.Background(), rel) +} diff --git a/pkg/tiller/release_modules.go b/pkg/tiller/release_modules.go new file mode 100644 index 000000000..e13b26de9 --- /dev/null +++ b/pkg/tiller/release_modules.go @@ -0,0 +1,172 @@ +/* +Copyright 2017 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tiller + +import ( + "bytes" + "errors" + "fmt" + "log" + "strings" + + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + + "k8s.io/helm/pkg/chartutil" + "k8s.io/helm/pkg/kube" + "k8s.io/helm/pkg/proto/hapi/release" + rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder" + "k8s.io/helm/pkg/proto/hapi/services" + relutil "k8s.io/helm/pkg/releaseutil" + "k8s.io/helm/pkg/rudder" + "k8s.io/helm/pkg/tiller/environment" +) + +// ReleaseModule is an interface that allows ReleaseServer to run operations on release via either local implementation or Rudder service +type ReleaseModule interface { + Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error + Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error + Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error + Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error) + Delete(r *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (string, []error) +} + +// LocalReleaseModule is a local implementation of ReleaseModule +type LocalReleaseModule struct { + clientset internalclientset.Interface +} + +// Create creates a release via kubeclient from provided environment +func (m *LocalReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error { + b := bytes.NewBufferString(r.Manifest) + return env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait) +} + +// Update performs an update from current to target release +func (m *LocalReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error { + c := bytes.NewBufferString(current.Manifest) + t := bytes.NewBufferString(target.Manifest) + return env.KubeClient.Update(target.Namespace, c, t, req.Recreate, req.Timeout, req.Wait) +} + +// Rollback performs a rollback from current to target release +func (m *LocalReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error { + c := bytes.NewBufferString(current.Manifest) + t := bytes.NewBufferString(target.Manifest) + return env.KubeClient.Update(target.Namespace, c, t, req.Recreate, req.Timeout, req.Wait) +} + +// Status returns kubectl-like formatted status of release objects +func (m *LocalReleaseModule) Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error) { + return env.KubeClient.Get(r.Namespace, bytes.NewBufferString(r.Manifest)) +} + +// Delete deletes the release and returns manifests that were kept in the deletion process +func (m *LocalReleaseModule) Delete(rel *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (kept string, errs []error) { + vs, err := GetVersionSet(m.clientset.Discovery()) + if err != nil { + return rel.Manifest, []error{fmt.Errorf("Could not get apiVersions from Kubernetes: %v", err)} + } + return DeleteRelease(rel, vs, env.KubeClient) +} + +// RemoteReleaseModule is a ReleaseModule which calls Rudder service to operate on a release +type RemoteReleaseModule struct{} + +// Create calls rudder.InstallRelease +func (m *RemoteReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error { + request := &rudderAPI.InstallReleaseRequest{Release: r} + _, err := rudder.InstallRelease(request) + return err +} + +// Update calls rudder.UpgradeRelease +func (m *RemoteReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error { + upgrade := &rudderAPI.UpgradeReleaseRequest{ + Current: current, + Target: target, + Recreate: req.Recreate, + Timeout: req.Timeout, + Wait: req.Wait, + } + _, err := rudder.UpgradeRelease(upgrade) + return err +} + +// Rollback calls rudder.Rollback +func (m *RemoteReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error { + rollback := &rudderAPI.RollbackReleaseRequest{ + Current: current, + Target: target, + Recreate: req.Recreate, + Timeout: req.Timeout, + Wait: req.Wait, + } + _, err := rudder.RollbackRelease(rollback) + return err +} + +// Status returns status retrieved from rudder.ReleaseStatus +func (m *RemoteReleaseModule) Status(r *release.Release, req *services.GetReleaseStatusRequest, env *environment.Environment) (string, error) { + statusRequest := &rudderAPI.ReleaseStatusRequest{Release: r} + resp, err := rudder.ReleaseStatus(statusRequest) + return resp.Info.Status.Resources, err +} + +// Delete calls rudder.DeleteRelease +func (m *RemoteReleaseModule) Delete(r *release.Release, req *services.UninstallReleaseRequest, env *environment.Environment) (string, []error) { + deleteRequest := &rudderAPI.DeleteReleaseRequest{Release: r} + resp, err := rudder.DeleteRelease(deleteRequest) + if err != nil { + return resp.Release.Manifest, []error{err} + } + return resp.Release.Manifest, []error{} +} + +// DeleteRelease is a helper that allows Rudder to delete a release without exposing most of Tiller inner functions +func DeleteRelease(rel *release.Release, vs chartutil.VersionSet, kubeClient environment.KubeClient) (kept string, errs []error) { + manifests := relutil.SplitManifests(rel.Manifest) + _, files, err := sortManifests(manifests, vs, UninstallOrder) + if err != nil { + // We could instead just delete everything in no particular order. + // FIXME: One way to delete at this point would be to try a label-based + // deletion. The problem with this is that we could get a false positive + // and delete something that was not legitimately part of this release. + return rel.Manifest, []error{fmt.Errorf("corrupted release record. You must manually delete the resources: %s", err)} + } + + filesToKeep, filesToDelete := filterManifestsToKeep(files) + if len(filesToKeep) > 0 { + kept = summarizeKeptManifests(filesToKeep) + } + + errs = []error{} + for _, file := range filesToDelete { + b := bytes.NewBufferString(strings.TrimSpace(file.content)) + if b.Len() == 0 { + continue + } + if err := kubeClient.Delete(rel.Namespace, b); err != nil { + log.Printf("uninstall: Failed deletion of %q: %s", rel.Name, err) + if err == kube.ErrNoObjectsVisited { + // Rewrite the message from "no objects visited" + err = errors.New("object not found, skipping delete") + } + errs = append(errs, err) + } + } + return kept, errs +} diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index bd480fb32..adc4ddf3c 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -33,7 +33,6 @@ import ( "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/hooks" - "k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" @@ -82,15 +81,26 @@ var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+ // ReleaseServer implements the server-side gRPC endpoint for the HAPI services. type ReleaseServer struct { + ReleaseModule env *environment.Environment clientset internalclientset.Interface } // NewReleaseServer creates a new release server. -func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface) *ReleaseServer { +func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface, useRemote bool) *ReleaseServer { + var releaseModule ReleaseModule + if useRemote { + releaseModule = &RemoteReleaseModule{} + } else { + releaseModule = &LocalReleaseModule{ + clientset: clientset, + } + } + return &ReleaseServer{ - env: env, - clientset: clientset, + env: env, + clientset: clientset, + ReleaseModule: releaseModule, } } @@ -253,8 +263,7 @@ func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetRelease // Ok, we got the status of the release as we had jotted down, now we need to match the // manifest we stashed away with reality from the cluster. - kubeCli := s.env.KubeClient - resp, err := kubeCli.Get(rel.Namespace, bytes.NewBufferString(rel.Manifest)) + resp, err := s.ReleaseModule.Status(rel, req, s.env) if sc == release.Status_DELETED || sc == release.Status_FAILED { // Skip errors if this is already deleted or failed. return statusResp, nil @@ -323,8 +332,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R return res, err } } - - if err := s.performKubeUpdate(originalRelease, updatedRelease, req.Recreate, req.Timeout, req.Wait); err != nil { + if err := s.ReleaseModule.Update(originalRelease, updatedRelease, req, s.env); err != nil { msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err) log.Printf("warning: %s", msg) originalRelease.Info.Status.Code = release.Status_SUPERSEDED @@ -511,7 +519,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R } } - if err := s.performKubeUpdate(currentRelease, targetRelease, req.Recreate, req.Timeout, req.Wait); err != nil { + if err := s.ReleaseModule.Rollback(currentRelease, targetRelease, req, s.env); err != nil { msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err) log.Printf("warning: %s", msg) currentRelease.Info.Status.Code = release.Status_SUPERSEDED @@ -537,13 +545,6 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R return res, nil } -func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release, recreate bool, timeout int64, shouldWait bool) error { - kubeCli := s.env.KubeClient - current := bytes.NewBufferString(currentRelease.Manifest) - target := bytes.NewBufferString(targetRelease.Manifest) - return kubeCli.Update(targetRelease.Namespace, current, target, recreate, timeout, shouldWait) -} - // prepareRollback finds the previous release and prepares a new release object with // the previous release's configuration func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) { @@ -681,7 +682,7 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e if err != nil { return nil, err } - vs, err := getVersionSet(disc) + vs, err := GetVersionSet(disc) if err != nil { return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err) } @@ -769,7 +770,8 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re return rel, err } -func getVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) { +// GetVersionSet retrieves a set of available k8s API versions +func GetVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) { groups, err := client.ServerGroups() if err != nil { return chartutil.DefaultVersionSet, err @@ -892,8 +894,12 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install // update new release with next revision number // so as to append to the old release's history r.Version = old.Version + 1 - - if err := s.performKubeUpdate(old, r, false, req.Timeout, req.Wait); err != nil { + updateReq := &services.UpdateReleaseRequest{ + Wait: req.Wait, + Recreate: false, + Timeout: req.Timeout, + } + if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil { msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err) log.Printf("warning: %s", msg) old.Info.Status.Code = release.Status_SUPERSEDED @@ -907,8 +913,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install default: // nothing to replace, create as normal // regular manifests - b := bytes.NewBufferString(r.Manifest) - if err := s.env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait); err != nil { + if err := s.ReleaseModule.Create(r, req, s.env); err != nil { msg := fmt.Sprintf("Release %q failed: %s", r.Name, err) log.Printf("warning: %s", msg) r.Info.Status.Code = release.Status_FAILED @@ -1047,47 +1052,19 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR } } - vs, err := getVersionSet(s.clientset.Discovery()) - if err != nil { - return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err) - } - // From here on out, the release is currently considered to be in Status_DELETING // state. if err := s.env.Releases.Update(rel); err != nil { log.Printf("uninstall: Failed to store updated release: %s", err) } - manifests := relutil.SplitManifests(rel.Manifest) - _, files, err := sortManifests(manifests, vs, UninstallOrder) - if err != nil { - // We could instead just delete everything in no particular order. - // FIXME: One way to delete at this point would be to try a label-based - // deletion. The problem with this is that we could get a false positive - // and delete something that was not legitimately part of this release. - return nil, fmt.Errorf("corrupted release record. You must manually delete the resources: %s", err) - } + kept, errs := s.ReleaseModule.Delete(rel, req, s.env) + res.Info = kept - filesToKeep, filesToDelete := filterManifestsToKeep(files) - if len(filesToKeep) > 0 { - res.Info = summarizeKeptManifests(filesToKeep) - } - - // Collect the errors, and return them later. - es := []string{} - for _, file := range filesToDelete { - b := bytes.NewBufferString(strings.TrimSpace(file.content)) - if b.Len() == 0 { - continue - } - if err := s.env.KubeClient.Delete(rel.Namespace, b); err != nil { - log.Printf("uninstall: Failed deletion of %q: %s", req.Name, err) - if err == kube.ErrNoObjectsVisited { - // Rewrite the message from "no objects visited" - err = errors.New("object not found, skipping delete") - } - es = append(es, err.Error()) - } + es := make([]string, 0, len(errs)) + for _, e := range errs { + log.Printf("error: %v", e) + es = append(es, e.Error()) } if !req.DisableHooks { diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 596f0803b..fd09fa47b 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -98,9 +98,13 @@ data: ` func rsFixture() *ReleaseServer { + clientset := fake.NewSimpleClientset() return &ReleaseServer{ + ReleaseModule: &LocalReleaseModule{ + clientset: clientset, + }, env: MockEnvironment(), - clientset: fake.NewSimpleClientset(), + clientset: clientset, } } @@ -206,7 +210,7 @@ func TestValidName(t *testing.T) { func TestGetVersionSet(t *testing.T) { rs := rsFixture() - vs, err := getVersionSet(rs.clientset.Discovery()) + vs, err := GetVersionSet(rs.clientset.Discovery()) if err != nil { t.Error(err) } diff --git a/rootfs/Dockerfile.experimental b/rootfs/Dockerfile.experimental new file mode 100644 index 000000000..8f3bce3c0 --- /dev/null +++ b/rootfs/Dockerfile.experimental @@ -0,0 +1,24 @@ +# Copyright 2017 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM alpine:3.3 + +ENV HOME /tmp + +COPY tiller /tiller + +EXPOSE 44134 + +CMD ["/tiller", "--experimental-release"] + diff --git a/rootfs/Dockerfile.rudder b/rootfs/Dockerfile.rudder new file mode 100644 index 000000000..7821096c5 --- /dev/null +++ b/rootfs/Dockerfile.rudder @@ -0,0 +1,23 @@ +# Copyright 2017 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM alpine:3.3 + +ENV HOME /tmp + +COPY rudder /rudder + +EXPOSE 10001 + +CMD ["/rudder"] diff --git a/versioning.mk b/versioning.mk index 83921f04d..2333530d9 100644 --- a/versioning.mk +++ b/versioning.mk @@ -22,12 +22,13 @@ endif ifneq ($(GIT_TAG),) LDFLAGS += -X k8s.io/helm/pkg/version.BuildMetadata= endif - LDFLAGS += -X k8s.io/helm/pkg/version.GitCommit=${GIT_COMMIT} LDFLAGS += -X k8s.io/helm/pkg/version.GitTreeState=${GIT_DIRTY} -IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION} -MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION} +IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION} +IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION} +MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION} +MUTABLE_IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION} DOCKER_PUSH = docker push ifeq ($(DOCKER_REGISTRY),gcr.io)