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