github.com/wangchanggan/helm@v0.0.0-20211020154240-11b1b7d5406d/cmd/helm/status.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 "fmt" 21 "io" 22 "regexp" 23 "text/tabwriter" 24 25 "github.com/gosuri/uitable" 26 "github.com/gosuri/uitable/util/strutil" 27 "github.com/spf13/cobra" 28 29 "k8s.io/helm/pkg/helm" 30 "k8s.io/helm/pkg/proto/hapi/release" 31 "k8s.io/helm/pkg/proto/hapi/services" 32 "k8s.io/helm/pkg/timeconv" 33 ) 34 35 var statusHelp = ` 36 This command shows the status of a named release. 37 The status consists of: 38 - last deployment time 39 - k8s namespace in which the release lives 40 - state of the release (can be: UNKNOWN, DEPLOYED, DELETED, SUPERSEDED, FAILED or DELETING) 41 - list of resources that this release consists of, sorted by kind 42 - details on last test suite run, if applicable 43 - additional notes provided by the chart 44 ` 45 46 type statusCmd struct { 47 release string 48 out io.Writer 49 client helm.Interface 50 version int32 51 outfmt string 52 } 53 54 func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command { 55 status := &statusCmd{ 56 out: out, 57 client: client, 58 } 59 60 cmd := &cobra.Command{ 61 Use: "status [flags] RELEASE_NAME", 62 Short: "Displays the status of the named release", 63 Long: statusHelp, 64 PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, 65 RunE: func(cmd *cobra.Command, args []string) error { 66 if len(args) == 0 { 67 return errReleaseRequired 68 } 69 status.release = args[0] 70 if status.client == nil { 71 status.client = newClient() 72 } 73 return status.run() 74 }, 75 } 76 77 f := cmd.Flags() 78 settings.AddFlagsTLS(f) 79 f.Int32Var(&status.version, "revision", 0, "If set, display the status of the named release with revision") 80 bindOutputFlag(cmd, &status.outfmt) 81 82 // set defaults from environment 83 settings.InitTLS(f) 84 85 return cmd 86 } 87 88 func (s *statusCmd) run() error { 89 res, err := s.client.ReleaseStatus(s.release, helm.StatusReleaseVersion(s.version)) 90 if err != nil { 91 return prettyError(err) 92 } 93 94 return write(s.out, &statusWriter{res}, outputFormat(s.outfmt)) 95 } 96 97 type statusWriter struct { 98 status *services.GetReleaseStatusResponse 99 } 100 101 func (s *statusWriter) WriteTable(out io.Writer) error { 102 PrintStatus(out, s.status) 103 // There is no error handling here due to backwards compatibility with 104 // PrintStatus 105 return nil 106 } 107 108 func (s *statusWriter) WriteJSON(out io.Writer) error { 109 return encodeJSON(out, s.status) 110 } 111 112 func (s *statusWriter) WriteYAML(out io.Writer) error { 113 return encodeYAML(out, s.status) 114 } 115 116 // PrintStatus prints out the status of a release. Shared because also used by 117 // install / upgrade 118 func PrintStatus(out io.Writer, res *services.GetReleaseStatusResponse) { 119 if res.Info.LastDeployed != nil { 120 fmt.Fprintf(out, "LAST DEPLOYED: %s\n", timeconv.String(res.Info.LastDeployed)) 121 } 122 fmt.Fprintf(out, "NAMESPACE: %s\n", res.Namespace) 123 fmt.Fprintf(out, "STATUS: %s\n", res.Info.Status.Code) 124 fmt.Fprintf(out, "\n") 125 if len(res.Info.Status.Resources) > 0 { 126 re := regexp.MustCompile(" +") 127 128 w := tabwriter.NewWriter(out, 0, 0, 2, ' ', tabwriter.TabIndent) 129 fmt.Fprintf(w, "RESOURCES:\n%s\n", re.ReplaceAllString(res.Info.Status.Resources, "\t")) 130 w.Flush() 131 } 132 if res.Info.Status.LastTestSuiteRun != nil { 133 lastRun := res.Info.Status.LastTestSuiteRun 134 fmt.Fprintf(out, "TEST SUITE:\n%s\n%s\n\n%s\n", 135 fmt.Sprintf("Last Started: %s", timeconv.String(lastRun.StartedAt)), 136 fmt.Sprintf("Last Completed: %s", timeconv.String(lastRun.CompletedAt)), 137 formatTestResults(lastRun.Results)) 138 } 139 140 if len(res.Info.Status.Notes) > 0 { 141 fmt.Fprintf(out, "NOTES:\n%s\n", res.Info.Status.Notes) 142 } 143 } 144 145 func formatTestResults(results []*release.TestRun) string { 146 tbl := uitable.New() 147 tbl.MaxColWidth = 50 148 tbl.AddRow("TEST", "STATUS", "INFO", "STARTED", "COMPLETED") 149 for i := 0; i < len(results); i++ { 150 r := results[i] 151 n := r.Name 152 s := strutil.PadRight(r.Status.String(), 10, ' ') 153 i := r.Info 154 ts := timeconv.String(r.StartedAt) 155 tc := timeconv.String(r.CompletedAt) 156 tbl.AddRow(n, s, i, ts, tc) 157 } 158 return tbl.String() 159 }