mirror of https://github.com/helm/helm
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.5 KiB
172 lines
4.5 KiB
/*
|
|
Copyright The Helm Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/ghodss/yaml"
|
|
"github.com/gosuri/uitable"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
|
|
"k8s.io/helm/cmd/helm/require"
|
|
"k8s.io/helm/pkg/chart"
|
|
"k8s.io/helm/pkg/hapi/release"
|
|
"k8s.io/helm/pkg/helm"
|
|
)
|
|
|
|
type releaseInfo struct {
|
|
Revision int `json:"revision"`
|
|
Updated string `json:"updated"`
|
|
Status string `json:"status"`
|
|
Chart string `json:"chart"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
type releaseHistory []releaseInfo
|
|
|
|
var historyHelp = `
|
|
History prints historical revisions for a given release.
|
|
|
|
A default maximum of 256 revisions will be returned. Setting '--max'
|
|
configures the maximum length of the revision list returned.
|
|
|
|
The historical release set is printed as a formatted table, e.g:
|
|
|
|
$ helm history angry-bird --max=4
|
|
REVISION UPDATED STATUS CHART DESCRIPTION
|
|
1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Initial install
|
|
2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Upgraded successfully
|
|
3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Rolled back to 2
|
|
4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 Upgraded successfully
|
|
`
|
|
|
|
type historyOptions struct {
|
|
colWidth uint // --col-width
|
|
max int // --max
|
|
outputFormat string // --output
|
|
|
|
release string
|
|
|
|
client helm.Interface
|
|
}
|
|
|
|
func newHistoryCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
|
o := &historyOptions{client: c}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "history RELEASE_NAME",
|
|
Long: historyHelp,
|
|
Short: "fetch release history",
|
|
Aliases: []string{"hist"},
|
|
Args: require.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
o.client = ensureHelmClient(o.client, false)
|
|
o.release = args[0]
|
|
return o.run(out)
|
|
},
|
|
}
|
|
|
|
f := cmd.Flags()
|
|
f.IntVar(&o.max, "max", 256, "maximum number of revision to include in history")
|
|
f.UintVar(&o.colWidth, "col-width", 60, "specifies the max column width of output")
|
|
f.StringVarP(&o.outputFormat, "output", "o", "table", "prints the output in the specified format (json|table|yaml)")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func (o *historyOptions) run(out io.Writer) error {
|
|
rels, err := o.client.ReleaseHistory(o.release, o.max)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(rels) == 0 {
|
|
return nil
|
|
}
|
|
|
|
releaseHistory := getReleaseHistory(rels)
|
|
|
|
var history []byte
|
|
var formattingError error
|
|
|
|
switch o.outputFormat {
|
|
case "yaml":
|
|
history, formattingError = yaml.Marshal(releaseHistory)
|
|
case "json":
|
|
history, formattingError = json.Marshal(releaseHistory)
|
|
case "table":
|
|
history = formatAsTable(releaseHistory, o.colWidth)
|
|
default:
|
|
return errors.Errorf("unknown output format %q", o.outputFormat)
|
|
}
|
|
|
|
if formattingError != nil {
|
|
return formattingError
|
|
}
|
|
|
|
fmt.Fprintln(out, string(history))
|
|
return nil
|
|
}
|
|
|
|
func getReleaseHistory(rls []*release.Release) (history releaseHistory) {
|
|
for i := len(rls) - 1; i >= 0; i-- {
|
|
r := rls[i]
|
|
c := formatChartname(r.Chart)
|
|
s := r.Info.Status.String()
|
|
v := r.Version
|
|
d := r.Info.Description
|
|
|
|
rInfo := releaseInfo{
|
|
Revision: v,
|
|
Status: s,
|
|
Chart: c,
|
|
Description: d,
|
|
}
|
|
if !r.Info.LastDeployed.IsZero() {
|
|
rInfo.Updated = r.Info.LastDeployed.String()
|
|
|
|
}
|
|
history = append(history, rInfo)
|
|
}
|
|
|
|
return history
|
|
}
|
|
|
|
func formatAsTable(releases releaseHistory, colWidth uint) []byte {
|
|
tbl := uitable.New()
|
|
|
|
tbl.MaxColWidth = colWidth
|
|
tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION")
|
|
for i := 0; i <= len(releases)-1; i++ {
|
|
r := releases[i]
|
|
tbl.AddRow(r.Revision, r.Updated, r.Status, r.Chart, r.Description)
|
|
}
|
|
return tbl.Bytes()
|
|
}
|
|
|
|
func formatChartname(c *chart.Chart) string {
|
|
if c == nil || c.Metadata == nil {
|
|
// This is an edge case that has happened in prod, though we don't
|
|
// know how: https://github.com/kubernetes/helm/issues/1347
|
|
return "MISSING"
|
|
}
|
|
return fmt.Sprintf("%s-%s", c.Name(), c.Metadata.Version)
|
|
}
|