Experimental Rudder implementation

This change introduces the concept of Rudders - pluggable modules that
Tiller communicates with via grpc, which allow to decouple orchestration
logic from Tiller into separate service.

This commit consists of simple Rudder implementation which does exactly
the same thing as built in Tiller orchestrator - it creates all k8s
objects from provided manifest without orchestrating them.

--experimental-release flag is introduced to enable this behaviour.

This change allows to use the service and tiller outside of the cluster.
Following commits will add Rudder to helm deployment.
pull/2079/head
Maciej Kwiek 8 years ago committed by Maciej Kwiek
parent 7c5363b028
commit c1fcaf09ce

@ -0,0 +1,83 @@
syntax = "proto3";
package hapi.release;
import "hapi/release/release.proto";
option go_package = "release";
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) {
}
}
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 release = 1;
}
message UpgradeReleaseResponse{
hapi.release.Release release = 1;
Result result = 2;
}
message RollbackReleaseRequest{
hapi.release.Release release = 1;
}
message RollbackReleaseResponse{
hapi.release.Release release = 1;
Result result = 2;
}

@ -0,0 +1,84 @@
/*
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 "k8s.io/helm/cmd/rudder"
import (
"bytes"
"fmt"
"net"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/rudder"
)
var kubeClient = kube.New(nil)
func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", rudder.GrpcAddr))
if err != nil {
grpclog.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
release.RegisterReleaseModuleServiceServer(grpcServer, &ReleaseModuleServiceServer{})
grpclog.Print("Server starting")
grpcServer.Serve(lis)
grpclog.Print("Server started")
}
// ReleaseModuleServiceServer provides implementation for release.ReleaseModuleServiceServer
type ReleaseModuleServiceServer struct{}
// Version is not yet implemented
func (r *ReleaseModuleServiceServer) Version(ctx context.Context, in *release.VersionReleaseRequest) (*release.VersionReleaseResponse, error) {
grpclog.Print("version")
return &release.VersionReleaseResponse{}, nil
}
// InstallRelease creates a release using kubeClient.Create
func (r *ReleaseModuleServiceServer) InstallRelease(ctx context.Context, in *release.InstallReleaseRequest) (*release.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: %s", err)
}
return &release.InstallReleaseResponse{}, err
}
// DeleteRelease is not implemented
func (r *ReleaseModuleServiceServer) DeleteRelease(ctx context.Context, in *release.DeleteReleaseRequest) (*release.DeleteReleaseResponse, error) {
grpclog.Print("delete")
return nil, nil
}
// RollbackRelease is not implemented
func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *release.RollbackReleaseRequest) (*release.RollbackReleaseResponse, error) {
grpclog.Print("rollback")
return nil, nil
}
// UpgradeRelease is not implemented
func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *release.UpgradeReleaseRequest) (*release.UpgradeReleaseResponse, error) {
grpclog.Print("upgrade")
return nil, nil
}

@ -70,11 +70,12 @@ var rootServer *grpc.Server
var env = environment.New() var env = environment.New()
var ( var (
grpcAddr = ":44134" grpcAddr = ":44134"
probeAddr = ":44135" probeAddr = ":44135"
traceAddr = ":44136" traceAddr = ":44136"
enableTracing = false enableTracing = false
store = storageConfigMap store = storageConfigMap
remoteReleaseModules = false
) )
var ( var (
@ -108,6 +109,7 @@ func main() {
p.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on") 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.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'")
p.BoolVar(&enableTracing, "trace", false, "enable rpc tracing") 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(&tlsEnable, "tls", tlsEnableEnvVarDefault(), "enable TLS")
p.BoolVar(&tlsVerify, "tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate") 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) srvErrCh := make(chan error)
probeErrCh := make(chan error) probeErrCh := make(chan error)
go func() { go func() {
svc := tiller.NewReleaseServer(env, clientset) svc := tiller.NewReleaseServer(env, clientset, remoteReleaseModules)
services.RegisterReleaseServiceServer(rootServer, svc) services.RegisterReleaseServiceServer(rootServer, svc)
if err := rootServer.Serve(lstn); err != nil { if err := rootServer.Serve(lstn); err != nil {
srvErrCh <- err srvErrCh <- err

@ -8,6 +8,7 @@ Package release is a generated protocol buffer package.
It is generated from these files: It is generated from these files:
hapi/release/hook.proto hapi/release/hook.proto
hapi/release/info.proto hapi/release/info.proto
hapi/release/modules.proto
hapi/release/release.proto hapi/release/release.proto
hapi/release/status.proto hapi/release/status.proto
hapi/release/test_run.proto hapi/release/test_run.proto
@ -16,6 +17,17 @@ It is generated from these files:
It has these top-level messages: It has these top-level messages:
Hook Hook
Info Info
Result
VersionReleaseRequest
VersionReleaseResponse
InstallReleaseRequest
InstallReleaseResponse
DeleteReleaseRequest
DeleteReleaseResponse
UpgradeReleaseRequest
UpgradeReleaseResponse
RollbackReleaseRequest
RollbackReleaseResponse
Release Release
Status Status
TestRun TestRun

@ -0,0 +1,500 @@
// Code generated by protoc-gen-go.
// source: hapi/release/modules.proto
// DO NOT EDIT!
package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
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
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 fileDescriptor2, []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 fileDescriptor2, []int{0} }
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 fileDescriptor2, []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 fileDescriptor2, []int{2} }
type InstallReleaseRequest struct {
Release *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 fileDescriptor2, []int{3} }
func (m *InstallReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type InstallReleaseResponse struct {
Release *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 fileDescriptor2, []int{4} }
func (m *InstallReleaseResponse) GetRelease() *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 *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 fileDescriptor2, []int{5} }
func (m *DeleteReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type DeleteReleaseResponse struct {
Release *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 fileDescriptor2, []int{6} }
func (m *DeleteReleaseResponse) GetRelease() *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 {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,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 fileDescriptor2, []int{7} }
func (m *UpgradeReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type UpgradeReleaseResponse struct {
Release *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 fileDescriptor2, []int{8} }
func (m *UpgradeReleaseResponse) GetRelease() *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 {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,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 fileDescriptor2, []int{9} }
func (m *RollbackReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type RollbackReleaseResponse struct {
Release *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 fileDescriptor2, []int{10} }
func (m *RollbackReleaseResponse) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
func (m *RollbackReleaseResponse) GetResult() *Result {
if m != nil {
return m.Result
}
return nil
}
func init() {
proto.RegisterType((*Result)(nil), "hapi.release.Result")
proto.RegisterType((*VersionReleaseRequest)(nil), "hapi.release.VersionReleaseRequest")
proto.RegisterType((*VersionReleaseResponse)(nil), "hapi.release.VersionReleaseResponse")
proto.RegisterType((*InstallReleaseRequest)(nil), "hapi.release.InstallReleaseRequest")
proto.RegisterType((*InstallReleaseResponse)(nil), "hapi.release.InstallReleaseResponse")
proto.RegisterType((*DeleteReleaseRequest)(nil), "hapi.release.DeleteReleaseRequest")
proto.RegisterType((*DeleteReleaseResponse)(nil), "hapi.release.DeleteReleaseResponse")
proto.RegisterType((*UpgradeReleaseRequest)(nil), "hapi.release.UpgradeReleaseRequest")
proto.RegisterType((*UpgradeReleaseResponse)(nil), "hapi.release.UpgradeReleaseResponse")
proto.RegisterType((*RollbackReleaseRequest)(nil), "hapi.release.RollbackReleaseRequest")
proto.RegisterType((*RollbackReleaseResponse)(nil), "hapi.release.RollbackReleaseResponse")
proto.RegisterEnum("hapi.release.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.SupportPackageIsVersion3
// 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)
}
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.release.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.release.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.release.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.release.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.release.ReleaseModuleService/UpgradeRelease", 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)
}
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.release.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.release.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.release.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.release.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.release.ReleaseModuleService/UpgradeRelease",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, req.(*UpgradeReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
var _ReleaseModuleService_serviceDesc = grpc.ServiceDesc{
ServiceName: "hapi.release.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,
},
},
Streams: []grpc.StreamDesc{},
Metadata: fileDescriptor2,
}
func init() { proto.RegisterFile("hapi/release/modules.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 450 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x5d, 0x6b, 0xd4, 0x40,
0x14, 0xdd, 0x0f, 0xdd, 0x25, 0x77, 0xad, 0x86, 0xcb, 0x66, 0x1b, 0xf2, 0x54, 0xa6, 0x0a, 0x7d,
0x90, 0x2c, 0xac, 0xaf, 0xbe, 0xe8, 0x76, 0xed, 0x16, 0x31, 0x85, 0x09, 0xa9, 0x50, 0x10, 0x4c,
0xdb, 0x6b, 0x0d, 0x4e, 0x33, 0x31, 0x93, 0xac, 0xfe, 0x66, 0x7f, 0x85, 0xe4, 0x4b, 0x9a, 0x31,
0x54, 0x64, 0xcb, 0x3e, 0x65, 0x26, 0xf7, 0xe4, 0xe4, 0x9c, 0x3b, 0xf7, 0x0c, 0x38, 0x5f, 0xc3,
0x24, 0x9a, 0xa7, 0x24, 0x28, 0x54, 0x34, 0xbf, 0x95, 0xd7, 0xb9, 0x20, 0xe5, 0x26, 0xa9, 0xcc,
0x24, 0x3e, 0x29, 0x6a, 0x6e, 0x5d, 0x73, 0xda, 0xc8, 0xfa, 0x59, 0x21, 0x99, 0x80, 0x11, 0x27,
0x95, 0x8b, 0x0c, 0x11, 0x1e, 0x45, 0xf1, 0x17, 0x69, 0xf7, 0x0f, 0xfa, 0x47, 0x06, 0x2f, 0xd7,
0x68, 0xc2, 0x50, 0xc8, 0x1b, 0x7b, 0x70, 0x30, 0x3c, 0x32, 0x78, 0xb1, 0x64, 0xaf, 0x61, 0xe4,
0x67, 0x61, 0x96, 0x2b, 0x9c, 0xc0, 0x38, 0xf0, 0xde, 0x7b, 0x67, 0x1f, 0x3d, 0xb3, 0x57, 0x6c,
0xfc, 0x60, 0xb9, 0x5c, 0xf9, 0xbe, 0xd9, 0xc7, 0x3d, 0x30, 0x02, 0x6f, 0xb9, 0x7e, 0xe3, 0x9d,
0xac, 0x8e, 0xcd, 0x01, 0x1a, 0xf0, 0x78, 0xc5, 0xf9, 0x19, 0x37, 0x87, 0x6c, 0x1f, 0xac, 0x73,
0x4a, 0x55, 0x24, 0x63, 0x5e, 0xa9, 0xe0, 0xf4, 0x3d, 0x27, 0x95, 0xb1, 0x77, 0x30, 0xd3, 0x0b,
0x2a, 0x91, 0xb1, 0xa2, 0x42, 0x56, 0x1c, 0xde, 0x52, 0x23, 0xab, 0x58, 0xa3, 0x0d, 0xe3, 0x4d,
0x85, 0xb6, 0x07, 0xe5, 0xeb, 0x66, 0xcb, 0xd6, 0x60, 0x9d, 0xc6, 0x2a, 0x0b, 0x85, 0x68, 0xff,
0x00, 0xe7, 0x30, 0xae, 0x8d, 0x97, 0x4c, 0x93, 0x85, 0xe5, 0xde, 0xed, 0x91, 0xdb, 0xc0, 0x1b,
0x14, 0xfb, 0x01, 0x33, 0x9d, 0xa9, 0x56, 0xf4, 0xbf, 0x54, 0xf8, 0x12, 0x46, 0x69, 0xd9, 0xe3,
0x52, 0xed, 0x64, 0x31, 0xd5, 0xf1, 0x45, 0x8d, 0xd7, 0x18, 0x76, 0x02, 0xd3, 0x63, 0x12, 0x94,
0xd1, 0xb6, 0x0e, 0x36, 0x60, 0x69, 0x44, 0xbb, 0x31, 0xb0, 0x06, 0x2b, 0x48, 0x6e, 0xd2, 0xf0,
0x9a, 0x1e, 0xe0, 0x0c, 0x74, 0xa6, 0xdd, 0x58, 0x38, 0x85, 0x19, 0x97, 0x42, 0x5c, 0x86, 0x57,
0xdf, 0xb6, 0xf5, 0xf0, 0x13, 0xf6, 0xff, 0xa2, 0xda, 0x89, 0x89, 0xc5, 0xaf, 0x21, 0x4c, 0x6b,
0x8a, 0x0f, 0xe5, 0xed, 0xe0, 0x53, 0xba, 0x89, 0xae, 0x08, 0xcf, 0x61, 0x5c, 0x87, 0x0d, 0x0f,
0xdb, 0x0c, 0x9d, 0xe1, 0x74, 0x9e, 0xdf, 0x0f, 0xaa, 0xdc, 0xb0, 0x1e, 0x7e, 0x82, 0xa7, 0xed,
0xc8, 0xe8, 0xf4, 0x9d, 0xd1, 0xd4, 0xe9, 0xbb, 0x53, 0xc7, 0x7a, 0x78, 0x01, 0x7b, 0xad, 0x79,
0x46, 0xd6, 0xfe, 0xb0, 0x2b, 0x35, 0xce, 0xe1, 0xbd, 0x98, 0x3f, 0xdc, 0x9f, 0xe1, 0x99, 0x76,
0x4a, 0xa8, 0xc9, 0xea, 0x9e, 0x07, 0xe7, 0xc5, 0x3f, 0x50, 0x77, 0x9b, 0xd3, 0x9e, 0x65, 0xbd,
0x39, 0x9d, 0x99, 0xd1, 0x9b, 0xd3, 0x1d, 0x07, 0xd6, 0x7b, 0x6b, 0x5c, 0x34, 0x53, 0x72, 0x39,
0x2a, 0x6f, 0xf6, 0x57, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x89, 0x83, 0xd3, 0x0a, 0x21, 0x06,
0x00, 0x00,
}

@ -40,7 +40,7 @@ type Release struct {
func (m *Release) Reset() { *m = Release{} } func (m *Release) Reset() { *m = Release{} }
func (m *Release) String() string { return proto.CompactTextString(m) } func (m *Release) String() string { return proto.CompactTextString(m) }
func (*Release) ProtoMessage() {} func (*Release) ProtoMessage() {}
func (*Release) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } func (*Release) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (m *Release) GetName() string { func (m *Release) GetName() string {
if m != nil { if m != nil {
@ -102,9 +102,9 @@ func init() {
proto.RegisterType((*Release)(nil), "hapi.release.Release") proto.RegisterType((*Release)(nil), "hapi.release.Release")
} }
func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor2) } func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor3) }
var fileDescriptor2 = []byte{ var fileDescriptor3 = []byte{
// 256 bytes of a gzipped FileDescriptorProto // 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xbf, 0x4e, 0xc3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xbf, 0x4e, 0xc3, 0x40,
0x0c, 0xc6, 0x95, 0x36, 0x7f, 0x1a, 0xc3, 0x82, 0x07, 0xb0, 0x22, 0x86, 0x88, 0x01, 0x22, 0x86, 0x0c, 0xc6, 0x95, 0x36, 0x7f, 0x1a, 0xc3, 0x82, 0x07, 0xb0, 0x22, 0x86, 0x88, 0x01, 0x22, 0x86,

@ -51,7 +51,7 @@ var Status_Code_value = map[string]int32{
func (x Status_Code) String() string { func (x Status_Code) String() string {
return proto.EnumName(Status_Code_name, int32(x)) return proto.EnumName(Status_Code_name, int32(x))
} }
func (Status_Code) EnumDescriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 0} } func (Status_Code) EnumDescriptor() ([]byte, []int) { return fileDescriptor4, []int{0, 0} }
// Status defines the status of a release. // Status defines the status of a release.
type Status struct { type Status struct {
@ -67,7 +67,7 @@ type Status struct {
func (m *Status) Reset() { *m = Status{} } func (m *Status) Reset() { *m = Status{} }
func (m *Status) String() string { return proto.CompactTextString(m) } func (m *Status) String() string { return proto.CompactTextString(m) }
func (*Status) ProtoMessage() {} func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} }
func (m *Status) GetCode() Status_Code { func (m *Status) GetCode() Status_Code {
if m != nil { if m != nil {
@ -102,9 +102,9 @@ func init() {
proto.RegisterEnum("hapi.release.Status_Code", Status_Code_name, Status_Code_value) proto.RegisterEnum("hapi.release.Status_Code", Status_Code_name, Status_Code_value)
} }
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor3) } func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor4) }
var fileDescriptor3 = []byte{ var fileDescriptor4 = []byte{
// 291 bytes of a gzipped FileDescriptorProto // 291 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xdf, 0x6a, 0xc2, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xdf, 0x6a, 0xc2, 0x30,
0x14, 0xc6, 0x57, 0xad, 0x3a, 0x8f, 0x22, 0x21, 0x1b, 0xac, 0xca, 0x06, 0xc5, 0xab, 0xde, 0xac, 0x14, 0xc6, 0x57, 0xad, 0x3a, 0x8f, 0x22, 0x21, 0x1b, 0xac, 0xca, 0x06, 0xc5, 0xab, 0xde, 0xac,

@ -36,7 +36,7 @@ var TestRun_Status_value = map[string]int32{
func (x TestRun_Status) String() string { func (x TestRun_Status) String() string {
return proto.EnumName(TestRun_Status_name, int32(x)) return proto.EnumName(TestRun_Status_name, int32(x))
} }
func (TestRun_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor4, []int{0, 0} } func (TestRun_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor5, []int{0, 0} }
type TestRun struct { type TestRun struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
@ -49,7 +49,7 @@ type TestRun struct {
func (m *TestRun) Reset() { *m = TestRun{} } func (m *TestRun) Reset() { *m = TestRun{} }
func (m *TestRun) String() string { return proto.CompactTextString(m) } func (m *TestRun) String() string { return proto.CompactTextString(m) }
func (*TestRun) ProtoMessage() {} func (*TestRun) ProtoMessage() {}
func (*TestRun) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} } func (*TestRun) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
func (m *TestRun) GetName() string { func (m *TestRun) GetName() string {
if m != nil { if m != nil {
@ -91,9 +91,9 @@ func init() {
proto.RegisterEnum("hapi.release.TestRun_Status", TestRun_Status_name, TestRun_Status_value) proto.RegisterEnum("hapi.release.TestRun_Status", TestRun_Status_name, TestRun_Status_value)
} }
func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor4) } func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor5) }
var fileDescriptor4 = []byte{ var fileDescriptor5 = []byte{
// 265 bytes of a gzipped FileDescriptorProto // 265 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x41, 0x4b, 0xfb, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x41, 0x4b, 0xfb, 0x40,
0x14, 0xc4, 0xff, 0xc9, 0xbf, 0x26, 0x64, 0x53, 0x24, 0xec, 0x29, 0x54, 0xc1, 0xd0, 0x53, 0x4e, 0x14, 0xc4, 0xff, 0xc9, 0xbf, 0x26, 0x64, 0x53, 0x24, 0xec, 0x29, 0x54, 0xc1, 0xd0, 0x53, 0x4e,

@ -27,7 +27,7 @@ type TestSuite struct {
func (m *TestSuite) Reset() { *m = TestSuite{} } func (m *TestSuite) Reset() { *m = TestSuite{} }
func (m *TestSuite) String() string { return proto.CompactTextString(m) } func (m *TestSuite) String() string { return proto.CompactTextString(m) }
func (*TestSuite) ProtoMessage() {} func (*TestSuite) ProtoMessage() {}
func (*TestSuite) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} } func (*TestSuite) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{0} }
func (m *TestSuite) GetStartedAt() *google_protobuf.Timestamp { func (m *TestSuite) GetStartedAt() *google_protobuf.Timestamp {
if m != nil { if m != nil {
@ -54,9 +54,9 @@ func init() {
proto.RegisterType((*TestSuite)(nil), "hapi.release.TestSuite") proto.RegisterType((*TestSuite)(nil), "hapi.release.TestSuite")
} }
func init() { proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor5) } func init() { proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor6) }
var fileDescriptor5 = []byte{ var fileDescriptor6 = []byte{
// 207 bytes of a gzipped FileDescriptorProto // 207 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4a, 0x86, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4a, 0x86, 0x40,
0x14, 0x85, 0x31, 0x21, 0x71, 0x74, 0x35, 0x10, 0x88, 0x11, 0x49, 0x2b, 0x57, 0x33, 0x60, 0xab, 0x14, 0x85, 0x31, 0x21, 0x71, 0x74, 0x35, 0x10, 0x88, 0x11, 0x49, 0x2b, 0x57, 0x33, 0x60, 0xab,

@ -0,0 +1,42 @@
/*
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"
"k8s.io/helm/pkg/proto/hapi/release"
)
// GrpcAddr is port number for accessing Rudder service
var GrpcAddr = 10001
// InstallRelease calls Rudder InstallRelease method which should create provided release
func InstallRelease(rel *release.InstallReleaseRequest) (*release.InstallReleaseResponse, error) {
//TODO(mkwiek): parametrize this
conn, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d", GrpcAddr), grpc.WithInsecure())
if err != nil {
return nil, err
}
defer conn.Close()
client := release.NewReleaseModuleServiceClient(conn)
return client.InstallRelease(context.Background(), rel)
}

@ -0,0 +1,50 @@
/*
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"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/proto/hapi/services"
"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
}
// LocalReleaseModule is a local implementation of ReleaseModule
type LocalReleaseModule struct{}
// 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)
}
// 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 := &release.InstallReleaseRequest{Release: r}
_, err := rudder.InstallRelease(request)
return err
}

@ -82,15 +82,24 @@ 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. // ReleaseServer implements the server-side gRPC endpoint for the HAPI services.
type ReleaseServer struct { type ReleaseServer struct {
ReleaseModule
env *environment.Environment env *environment.Environment
clientset internalclientset.Interface clientset internalclientset.Interface
} }
// NewReleaseServer creates a new release server. // 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{}
}
return &ReleaseServer{ return &ReleaseServer{
env: env, env: env,
clientset: clientset, clientset: clientset,
ReleaseModule: releaseModule,
} }
} }
@ -907,8 +916,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
default: default:
// nothing to replace, create as normal // nothing to replace, create as normal
// regular manifests // regular manifests
b := bytes.NewBufferString(r.Manifest) if err := s.ReleaseModule.Create(r, req, s.env); err != nil {
if err := s.env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait); err != nil {
msg := fmt.Sprintf("Release %q failed: %s", r.Name, err) msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
log.Printf("warning: %s", msg) log.Printf("warning: %s", msg)
r.Info.Status.Code = release.Status_FAILED r.Info.Status.Code = release.Status_FAILED

@ -99,8 +99,9 @@ data:
func rsFixture() *ReleaseServer { func rsFixture() *ReleaseServer {
return &ReleaseServer{ return &ReleaseServer{
env: MockEnvironment(), ReleaseModule: &LocalReleaseModule{},
clientset: fake.NewSimpleClientset(), env: MockEnvironment(),
clientset: fake.NewSimpleClientset(),
} }
} }

Loading…
Cancel
Save