github.com/darkowlzz/helm@v2.5.1-0.20171213183701-6707fe0468d4+incompatible/cmd/rudder/rudder.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"net"
    23  
    24  	"golang.org/x/net/context"
    25  	"google.golang.org/grpc"
    26  	"google.golang.org/grpc/grpclog"
    27  	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
    28  
    29  	"github.com/spf13/pflag"
    30  	"k8s.io/helm/pkg/kube"
    31  	rudderAPI "k8s.io/helm/pkg/proto/hapi/rudder"
    32  	"k8s.io/helm/pkg/tiller"
    33  	"k8s.io/helm/pkg/version"
    34  )
    35  
    36  var kubeClient *kube.Client
    37  var clientset internalclientset.Interface
    38  
    39  type options struct {
    40  	listen string
    41  }
    42  
    43  func (opts *options) registerFlags() {
    44  	pflag.StringVarP(&opts.listen, "listen", "l", "127.0.0.1:10001",
    45  		"Socket for rudder grpc server (default: 127.0.0.1:10001).")
    46  }
    47  
    48  func (opts *options) parseFlags() {
    49  	pflag.Parse()
    50  }
    51  
    52  func (opts *options) regAndParseFlags() {
    53  	opts.registerFlags()
    54  	opts.parseFlags()
    55  }
    56  
    57  func main() {
    58  	opts := new(options)
    59  	opts.regAndParseFlags()
    60  	var err error
    61  	kubeClient = kube.New(nil)
    62  	clientset, err = kubeClient.ClientSet()
    63  	if err != nil {
    64  		grpclog.Fatalf("Cannot initialize Kubernetes connection: %s", err)
    65  	}
    66  	grpclog.Printf("Creating tcp socket on %s\n", opts.listen)
    67  	lis, err := net.Listen("tcp", opts.listen)
    68  	if err != nil {
    69  		grpclog.Fatalf("failed to listen: %v", err)
    70  	}
    71  	grpcServer := grpc.NewServer()
    72  	rudderAPI.RegisterReleaseModuleServiceServer(grpcServer, &ReleaseModuleServiceServer{})
    73  
    74  	grpclog.Printf("Starting server on %s\n", opts.listen)
    75  	grpcServer.Serve(lis)
    76  }
    77  
    78  // ReleaseModuleServiceServer provides implementation for rudderAPI.ReleaseModuleServiceServer
    79  type ReleaseModuleServiceServer struct{}
    80  
    81  // Version returns Rudder version based on helm version
    82  func (r *ReleaseModuleServiceServer) Version(ctx context.Context, in *rudderAPI.VersionReleaseRequest) (*rudderAPI.VersionReleaseResponse, error) {
    83  	grpclog.Print("version")
    84  	return &rudderAPI.VersionReleaseResponse{
    85  		Name:    "helm-rudder-native",
    86  		Version: version.Version,
    87  	}, nil
    88  }
    89  
    90  // InstallRelease creates a release using kubeClient.Create
    91  func (r *ReleaseModuleServiceServer) InstallRelease(ctx context.Context, in *rudderAPI.InstallReleaseRequest) (*rudderAPI.InstallReleaseResponse, error) {
    92  	grpclog.Print("install")
    93  	b := bytes.NewBufferString(in.Release.Manifest)
    94  	err := kubeClient.Create(in.Release.Namespace, b, 500, false)
    95  	if err != nil {
    96  		grpclog.Printf("error when creating release: %v", err)
    97  	}
    98  	return &rudderAPI.InstallReleaseResponse{}, err
    99  }
   100  
   101  // DeleteRelease deletes a provided release
   102  func (r *ReleaseModuleServiceServer) DeleteRelease(ctx context.Context, in *rudderAPI.DeleteReleaseRequest) (*rudderAPI.DeleteReleaseResponse, error) {
   103  	grpclog.Print("delete")
   104  
   105  	resp := &rudderAPI.DeleteReleaseResponse{}
   106  	rel := in.Release
   107  	vs, err := tiller.GetVersionSet(clientset.Discovery())
   108  	if err != nil {
   109  		return resp, fmt.Errorf("Could not get apiVersions from Kubernetes: %v", err)
   110  	}
   111  
   112  	kept, errs := tiller.DeleteRelease(rel, vs, kubeClient)
   113  	rel.Manifest = kept
   114  
   115  	allErrors := ""
   116  	for _, e := range errs {
   117  		allErrors = allErrors + "\n" + e.Error()
   118  	}
   119  
   120  	if len(allErrors) > 0 {
   121  		err = fmt.Errorf(allErrors)
   122  	}
   123  
   124  	return &rudderAPI.DeleteReleaseResponse{
   125  		Release: rel,
   126  	}, err
   127  }
   128  
   129  // RollbackRelease rolls back the release
   130  func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *rudderAPI.RollbackReleaseRequest) (*rudderAPI.RollbackReleaseResponse, error) {
   131  	grpclog.Print("rollback")
   132  	c := bytes.NewBufferString(in.Current.Manifest)
   133  	t := bytes.NewBufferString(in.Target.Manifest)
   134  	err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait)
   135  	return &rudderAPI.RollbackReleaseResponse{}, err
   136  }
   137  
   138  // UpgradeRelease upgrades manifests using kubernetes client
   139  func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) {
   140  	grpclog.Print("upgrade")
   141  	c := bytes.NewBufferString(in.Current.Manifest)
   142  	t := bytes.NewBufferString(in.Target.Manifest)
   143  	err := kubeClient.Update(in.Target.Namespace, c, t, in.Force, in.Recreate, in.Timeout, in.Wait)
   144  	// upgrade response object should be changed to include status
   145  	return &rudderAPI.UpgradeReleaseResponse{}, err
   146  }
   147  
   148  // ReleaseStatus retrieves release status
   149  func (r *ReleaseModuleServiceServer) ReleaseStatus(ctx context.Context, in *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) {
   150  	grpclog.Print("status")
   151  
   152  	resp, err := kubeClient.Get(in.Release.Namespace, bytes.NewBufferString(in.Release.Manifest))
   153  	in.Release.Info.Status.Resources = resp
   154  	return &rudderAPI.ReleaseStatusResponse{
   155  		Release: in.Release,
   156  		Info:    in.Release.Info,
   157  	}, err
   158  }