github.com/latiif/helm@v2.15.0+incompatible/cmd/rudder/rudder.go (about)

     1  /*
     2  Copyright The Helm Authors.
     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  	"github.com/spf13/pflag"
    25  	"golang.org/x/net/context"
    26  	"google.golang.org/grpc"
    27  	"google.golang.org/grpc/grpclog"
    28  	"k8s.io/client-go/kubernetes"
    29  
    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 kubernetes.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.KubernetesClientSet()
    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.UpdateWithOptions(in.Target.Namespace, c, t, kube.UpdateOptions{
   135  		Force:         in.Force,
   136  		Recreate:      in.Recreate,
   137  		Timeout:       in.Timeout,
   138  		ShouldWait:    in.Wait,
   139  		CleanupOnFail: in.CleanupOnFail,
   140  	})
   141  	return &rudderAPI.RollbackReleaseResponse{}, err
   142  }
   143  
   144  // UpgradeRelease upgrades manifests using kubernetes client
   145  func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *rudderAPI.UpgradeReleaseRequest) (*rudderAPI.UpgradeReleaseResponse, error) {
   146  	grpclog.Print("upgrade")
   147  	c := bytes.NewBufferString(in.Current.Manifest)
   148  	t := bytes.NewBufferString(in.Target.Manifest)
   149  	err := kubeClient.UpdateWithOptions(in.Target.Namespace, c, t, kube.UpdateOptions{
   150  		Force:         in.Force,
   151  		Recreate:      in.Recreate,
   152  		Timeout:       in.Timeout,
   153  		ShouldWait:    in.Wait,
   154  		CleanupOnFail: in.CleanupOnFail,
   155  	})
   156  	// upgrade response object should be changed to include status
   157  	return &rudderAPI.UpgradeReleaseResponse{}, err
   158  }
   159  
   160  // ReleaseStatus retrieves release status
   161  func (r *ReleaseModuleServiceServer) ReleaseStatus(ctx context.Context, in *rudderAPI.ReleaseStatusRequest) (*rudderAPI.ReleaseStatusResponse, error) {
   162  	grpclog.Print("status")
   163  
   164  	resp, err := kubeClient.Get(in.Release.Namespace, bytes.NewBufferString(in.Release.Manifest))
   165  	in.Release.Info.Status.Resources = resp
   166  	return &rudderAPI.ReleaseStatusResponse{
   167  		Release: in.Release,
   168  		Info:    in.Release.Info,
   169  	}, err
   170  }