github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/cmd/kcfi/list.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  	"os"
    23  	"strconv"
    24  
    25  	"github.com/gosuri/uitable"
    26  	"github.com/spf13/cobra"
    27  
    28  	"github.com/codefresh-io/kcfi/pkg/helm-internal/completion"
    29  	"helm.sh/helm/v3/cmd/helm/require"
    30  	"helm.sh/helm/v3/pkg/action"
    31  	"helm.sh/helm/v3/pkg/cli/output"
    32  	"helm.sh/helm/v3/pkg/release"
    33  )
    34  
    35  var listHelp = `
    36  This command lists all of the releases for a specified namespace (uses current namespace context if namespace not specified).
    37  
    38  By default, it lists only releases that are deployed or failed. Flags like
    39  '--uninstalled' and '--all' will alter this behavior. Such flags can be combined:
    40  '--uninstalled --failed'.
    41  
    42  By default, items are sorted alphabetically. Use the '-d' flag to sort by
    43  release date.
    44  
    45  If the --filter flag is provided, it will be treated as a filter. Filters are
    46  regular expressions (Perl compatible) that are applied to the list of releases.
    47  Only items that match the filter will be returned.
    48  
    49      $ helm list --filter 'ara[a-z]+'
    50      NAME                UPDATED                     CHART
    51      maudlin-arachnid    Mon May  9 16:07:08 2016    alpine-0.1.0
    52  
    53  If no results are found, 'helm list' will exit 0, but with no output (or in
    54  the case of no '-q' flag, only headers).
    55  
    56  By default, up to 256 items may be returned. To limit this, use the '--max' flag.
    57  Setting '--max' to 0 will not return all results. Rather, it will return the
    58  server's default, which may be much higher than 256. Pairing the '--max'
    59  flag with the '--offset' flag allows you to page through results.
    60  `
    61  
    62  func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
    63  	client := action.NewList(cfg)
    64  	var outfmt output.Format
    65  
    66  	cmd := &cobra.Command{
    67  		Use:     "list",
    68  		Short:   "list releases",
    69  		Long:    listHelp,
    70  		Aliases: []string{"ls"},
    71  		Args:    require.NoArgs,
    72  		RunE: func(cmd *cobra.Command, args []string) error {
    73  			if client.AllNamespaces {
    74  				if err := cfg.Init(settings.RESTClientGetter(), "", os.Getenv("HELM_DRIVER"), debug); err != nil {
    75  					return err
    76  				}
    77  			}
    78  			client.SetStateMask()
    79  
    80  			results, err := client.Run()
    81  			if err != nil {
    82  				return err
    83  			}
    84  
    85  			if client.Short {
    86  
    87  				names := make([]string, 0)
    88  				for _, res := range results {
    89  					names = append(names, res.Name)
    90  				}
    91  
    92  				outputFlag := cmd.Flag("output")
    93  
    94  				switch outputFlag.Value.String() {
    95  				case "json":
    96  					output.EncodeJSON(out, names)
    97  					return nil
    98  				case "yaml":
    99  					output.EncodeYAML(out, names)
   100  					return nil
   101  				case "table":
   102  					for _, res := range results {
   103  						fmt.Fprintln(out, res.Name)
   104  					}
   105  					return nil
   106  				default:
   107  					return outfmt.Write(out, newReleaseListWriter(results))
   108  				}
   109  			}
   110  
   111  			return outfmt.Write(out, newReleaseListWriter(results))
   112  		},
   113  	}
   114  
   115  	f := cmd.Flags()
   116  	f.BoolVarP(&client.Short, "short", "q", false, "output short (quiet) listing format")
   117  	f.BoolVarP(&client.ByDate, "date", "d", false, "sort by release date")
   118  	f.BoolVarP(&client.SortReverse, "reverse", "r", false, "reverse the sort order")
   119  	f.BoolVarP(&client.All, "all", "a", false, "show all releases without any filter applied")
   120  	f.BoolVar(&client.Uninstalled, "uninstalled", false, "show uninstalled releases (if 'helm uninstall --keep-history' was used)")
   121  	f.BoolVar(&client.Superseded, "superseded", false, "show superseded releases")
   122  	f.BoolVar(&client.Uninstalling, "uninstalling", false, "show releases that are currently being uninstalled")
   123  	f.BoolVar(&client.Deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled")
   124  	f.BoolVar(&client.Failed, "failed", false, "show failed releases")
   125  	f.BoolVar(&client.Pending, "pending", false, "show pending releases")
   126  	f.BoolVarP(&client.AllNamespaces, "all-namespaces", "A", false, "list releases across all namespaces")
   127  	f.IntVarP(&client.Limit, "max", "m", 256, "maximum number of releases to fetch")
   128  	f.IntVar(&client.Offset, "offset", 0, "next release name in the list, used to offset from start value")
   129  	f.StringVarP(&client.Filter, "filter", "f", "", "a regular expression (Perl compatible). Any releases that match the expression will be included in the results")
   130  	bindOutputFlag(cmd, &outfmt)
   131  
   132  	return cmd
   133  }
   134  
   135  type releaseElement struct {
   136  	Name       string `json:"name"`
   137  	Namespace  string `json:"namespace"`
   138  	Revision   string `json:"revision"`
   139  	Updated    string `json:"updated"`
   140  	Status     string `json:"status"`
   141  	Chart      string `json:"chart"`
   142  	AppVersion string `json:"app_version"`
   143  }
   144  
   145  type releaseListWriter struct {
   146  	releases []releaseElement
   147  }
   148  
   149  func newReleaseListWriter(releases []*release.Release) *releaseListWriter {
   150  	// Initialize the array so no results returns an empty array instead of null
   151  	elements := make([]releaseElement, 0, len(releases))
   152  	for _, r := range releases {
   153  		element := releaseElement{
   154  			Name:       r.Name,
   155  			Namespace:  r.Namespace,
   156  			Revision:   strconv.Itoa(r.Version),
   157  			Status:     r.Info.Status.String(),
   158  			Chart:      fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version),
   159  			AppVersion: r.Chart.Metadata.AppVersion,
   160  		}
   161  		t := "-"
   162  		if tspb := r.Info.LastDeployed; !tspb.IsZero() {
   163  			t = tspb.String()
   164  		}
   165  		element.Updated = t
   166  		elements = append(elements, element)
   167  	}
   168  	return &releaseListWriter{elements}
   169  }
   170  
   171  func (r *releaseListWriter) WriteTable(out io.Writer) error {
   172  	table := uitable.New()
   173  	table.AddRow("NAME", "NAMESPACE", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION")
   174  	for _, r := range r.releases {
   175  		table.AddRow(r.Name, r.Namespace, r.Revision, r.Updated, r.Status, r.Chart, r.AppVersion)
   176  	}
   177  	return output.EncodeTable(out, table)
   178  }
   179  
   180  func (r *releaseListWriter) WriteJSON(out io.Writer) error {
   181  	return output.EncodeJSON(out, r.releases)
   182  }
   183  
   184  func (r *releaseListWriter) WriteYAML(out io.Writer) error {
   185  	return output.EncodeYAML(out, r.releases)
   186  }
   187  
   188  // Provide dynamic auto-completion for release names
   189  func compListReleases(toComplete string, cfg *action.Configuration) ([]string, completion.BashCompDirective) {
   190  	completion.CompDebugln(fmt.Sprintf("compListReleases with toComplete %s", toComplete))
   191  
   192  	client := action.NewList(cfg)
   193  	client.All = true
   194  	client.Limit = 0
   195  	client.Filter = fmt.Sprintf("^%s", toComplete)
   196  
   197  	client.SetStateMask()
   198  	results, err := client.Run()
   199  	if err != nil {
   200  		return nil, completion.BashCompDirectiveDefault
   201  	}
   202  
   203  	var choices []string
   204  	for _, res := range results {
   205  		choices = append(choices, res.Name)
   206  	}
   207  
   208  	return choices, completion.BashCompDirectiveNoFileComp
   209  }