github.com/latiif/helm@v2.15.0+incompatible/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  }