github.com/migueleliasweb/helm@v2.6.1+incompatible/cmd/helm/list.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 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 "strings" 23 24 "github.com/gosuri/uitable" 25 "github.com/spf13/cobra" 26 27 "k8s.io/helm/pkg/helm" 28 "k8s.io/helm/pkg/proto/hapi/release" 29 "k8s.io/helm/pkg/proto/hapi/services" 30 "k8s.io/helm/pkg/timeconv" 31 ) 32 33 var listHelp = ` 34 This command lists all of the releases. 35 36 By default, it lists only releases that are deployed or failed. Flags like 37 '--deleted' and '--all' will alter this behavior. Such flags can be combined: 38 '--deleted --failed'. 39 40 By default, items are sorted alphabetically. Use the '-d' flag to sort by 41 release date. 42 43 If an argument is provided, it will be treated as a filter. Filters are 44 regular expressions (Perl compatible) that are applied to the list of releases. 45 Only items that match the filter will be returned. 46 47 $ helm list 'ara[a-z]+' 48 NAME UPDATED CHART 49 maudlin-arachnid Mon May 9 16:07:08 2016 alpine-0.1.0 50 51 If no results are found, 'helm list' will exit 0, but with no output (or in 52 the case of no '-q' flag, only headers). 53 54 By default, up to 256 items may be returned. To limit this, use the '--max' flag. 55 Setting '--max' to 0 will not return all results. Rather, it will return the 56 server's default, which may be much higher than 256. Pairing the '--max' 57 flag with the '--offset' flag allows you to page through results. 58 ` 59 60 type listCmd struct { 61 filter string 62 short bool 63 limit int 64 offset string 65 byDate bool 66 sortDesc bool 67 out io.Writer 68 all bool 69 deleted bool 70 deleting bool 71 deployed bool 72 failed bool 73 namespace string 74 superseded bool 75 pending bool 76 client helm.Interface 77 } 78 79 func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { 80 list := &listCmd{ 81 out: out, 82 client: client, 83 } 84 85 cmd := &cobra.Command{ 86 Use: "list [flags] [FILTER]", 87 Short: "list releases", 88 Long: listHelp, 89 Aliases: []string{"ls"}, 90 PreRunE: setupConnection, 91 RunE: func(cmd *cobra.Command, args []string) error { 92 if len(args) > 0 { 93 list.filter = strings.Join(args, " ") 94 } 95 if list.client == nil { 96 list.client = helm.NewClient(helm.Host(settings.TillerHost)) 97 } 98 return list.run() 99 }, 100 } 101 102 f := cmd.Flags() 103 f.BoolVarP(&list.short, "short", "q", false, "output short (quiet) listing format") 104 f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date") 105 f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order") 106 f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch") 107 f.StringVarP(&list.offset, "offset", "o", "", "next release name in the list, used to offset from start value") 108 f.BoolVarP(&list.all, "all", "a", false, "show all releases, not just the ones marked DEPLOYED") 109 f.BoolVar(&list.deleted, "deleted", false, "show deleted releases") 110 f.BoolVar(&list.deleting, "deleting", false, "show releases that are currently being deleted") 111 f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled") 112 f.BoolVar(&list.failed, "failed", false, "show failed releases") 113 f.BoolVar(&list.pending, "pending", false, "show pending releases") 114 f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace") 115 116 // TODO: Do we want this as a feature of 'helm list'? 117 //f.BoolVar(&list.superseded, "history", true, "show historical releases") 118 119 return cmd 120 } 121 122 func (l *listCmd) run() error { 123 sortBy := services.ListSort_NAME 124 if l.byDate { 125 sortBy = services.ListSort_LAST_RELEASED 126 } 127 128 sortOrder := services.ListSort_ASC 129 if l.sortDesc { 130 sortOrder = services.ListSort_DESC 131 } 132 133 stats := l.statusCodes() 134 135 res, err := l.client.ListReleases( 136 helm.ReleaseListLimit(l.limit), 137 helm.ReleaseListOffset(l.offset), 138 helm.ReleaseListFilter(l.filter), 139 helm.ReleaseListSort(int32(sortBy)), 140 helm.ReleaseListOrder(int32(sortOrder)), 141 helm.ReleaseListStatuses(stats), 142 helm.ReleaseListNamespace(l.namespace), 143 ) 144 145 if err != nil { 146 return prettyError(err) 147 } 148 149 if len(res.Releases) == 0 { 150 return nil 151 } 152 153 if res.Next != "" && !l.short { 154 fmt.Fprintf(l.out, "\tnext: %s\n", res.Next) 155 } 156 157 rels := res.Releases 158 159 if l.short { 160 for _, r := range rels { 161 fmt.Fprintln(l.out, r.Name) 162 } 163 return nil 164 } 165 fmt.Fprintln(l.out, formatList(rels)) 166 return nil 167 } 168 169 // statusCodes gets the list of status codes that are to be included in the results. 170 func (l *listCmd) statusCodes() []release.Status_Code { 171 if l.all { 172 return []release.Status_Code{ 173 release.Status_UNKNOWN, 174 release.Status_DEPLOYED, 175 release.Status_DELETED, 176 release.Status_DELETING, 177 release.Status_FAILED, 178 release.Status_PENDING_INSTALL, 179 release.Status_PENDING_UPGRADE, 180 release.Status_PENDING_ROLLBACK, 181 } 182 } 183 status := []release.Status_Code{} 184 if l.deployed { 185 status = append(status, release.Status_DEPLOYED) 186 } 187 if l.deleted { 188 status = append(status, release.Status_DELETED) 189 } 190 if l.deleting { 191 status = append(status, release.Status_DELETING) 192 } 193 if l.failed { 194 status = append(status, release.Status_FAILED) 195 } 196 if l.superseded { 197 status = append(status, release.Status_SUPERSEDED) 198 } 199 if l.pending { 200 status = append(status, release.Status_PENDING_INSTALL, release.Status_PENDING_UPGRADE, release.Status_PENDING_ROLLBACK) 201 } 202 203 // Default case. 204 if len(status) == 0 { 205 status = append(status, release.Status_DEPLOYED, release.Status_FAILED) 206 } 207 return status 208 } 209 210 func formatList(rels []*release.Release) string { 211 table := uitable.New() 212 table.MaxColWidth = 60 213 table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "NAMESPACE") 214 for _, r := range rels { 215 c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version) 216 t := timeconv.String(r.Info.LastDeployed) 217 s := r.Info.Status.Code.String() 218 v := r.Version 219 n := r.Namespace 220 table.AddRow(r.Name, v, t, s, c, n) 221 } 222 return table.String() 223 }