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 }