From 91c3521b184f4337bec5e2e31ccf93cabadf8e3c Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Wed, 15 Jun 2016 16:09:49 -0600 Subject: [PATCH 1/3] ref(pkg/helm): package helm refactor includes: - (#826) removal old pkg/helm --- pkg/helm/client.go | 43 ------ pkg/helm/config.go | 28 ---- pkg/helm/convert.go | 132 ------------------ pkg/helm/convert_test.go | 65 --------- pkg/helm/error.go | 22 --- pkg/helm/helm.go | 107 -------------- pkg/helm/testdata/albatross-overrides.toml | 1 - pkg/helm/testdata/albatross/Chart.yaml | 4 - .../albatross/templates/albatross.yaml | 3 - pkg/helm/testdata/albatross/values.toml | 2 - pkg/helm/traverse.go | 115 --------------- 11 files changed, 522 deletions(-) delete mode 100644 pkg/helm/client.go delete mode 100644 pkg/helm/config.go delete mode 100644 pkg/helm/convert.go delete mode 100644 pkg/helm/convert_test.go delete mode 100644 pkg/helm/error.go delete mode 100644 pkg/helm/helm.go delete mode 100644 pkg/helm/testdata/albatross-overrides.toml delete mode 100644 pkg/helm/testdata/albatross/Chart.yaml delete mode 100644 pkg/helm/testdata/albatross/templates/albatross.yaml delete mode 100644 pkg/helm/testdata/albatross/values.toml delete mode 100644 pkg/helm/traverse.go diff --git a/pkg/helm/client.go b/pkg/helm/client.go deleted file mode 100644 index afbb5a1ff..000000000 --- a/pkg/helm/client.go +++ /dev/null @@ -1,43 +0,0 @@ -package helm - -import ( - "golang.org/x/net/context" - "google.golang.org/grpc" - - "k8s.io/helm/pkg/proto/hapi/services" -) - -type client struct { - cfg *config - conn *grpc.ClientConn - impl services.ReleaseServiceClient -} - -func (c *client) dial() (err error) { - c.conn, err = grpc.Dial(c.cfg.ServAddr, c.cfg.DialOpts()...) - c.impl = services.NewReleaseServiceClient(c.conn) - return -} - -func (c *client) install(req *services.InstallReleaseRequest) (res *services.InstallReleaseResponse, err error) { - if err = c.dial(); err != nil { - return - } - - defer c.Close() - - return c.impl.InstallRelease(context.TODO(), req, c.cfg.CallOpts()...) -} - -func (c *client) uninstall(req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) { - if err := c.dial(); err != nil { - return nil, err - } - defer c.Close() - - return c.impl.UninstallRelease(context.TODO(), req, c.cfg.CallOpts()...) -} - -func (c *client) Close() error { - return c.conn.Close() -} diff --git a/pkg/helm/config.go b/pkg/helm/config.go deleted file mode 100644 index 0e515a112..000000000 --- a/pkg/helm/config.go +++ /dev/null @@ -1,28 +0,0 @@ -package helm - -import ( - "google.golang.org/grpc" -) - -type config struct { - ServAddr string - Insecure bool -} - -func (cfg *config) DialOpts() (opts []grpc.DialOption) { - if cfg.Insecure { - opts = append(opts, grpc.WithInsecure()) - } else { - // TODO: handle transport credentials - } - - return -} - -func (cfg *config) CallOpts() (opts []grpc.CallOption) { - return -} - -func (cfg *config) client() *client { - return &client{cfg: cfg} -} diff --git a/pkg/helm/convert.go b/pkg/helm/convert.go deleted file mode 100644 index 7060593a6..000000000 --- a/pkg/helm/convert.go +++ /dev/null @@ -1,132 +0,0 @@ -package helm - -import ( - "bytes" - - chartutil "k8s.io/helm/pkg/chart" - chartpbs "k8s.io/helm/pkg/proto/hapi/chart" -) - -// ChartToProto converts a chart to its Protobuf struct representation. -func ChartToProto(ch *chartutil.Chart) (chpb *chartpbs.Chart, err error) { - chpb = new(chartpbs.Chart) - - chpb.Metadata, err = MetadataToProto(ch) - if err != nil { - return - } - - chpb.Templates, err = TemplatesToProto(ch) - if err != nil { - return - } - - chpb.Values, err = ValuesToProto(ch) - if err != nil { - return - } - - chs, err := WalkChartFile(ch) - if err != nil { - return - } - - for _, dep := range chs.deps { - chdep, err := ChartToProto(dep.File()) - if err != nil { - return nil, err - } - - chpb.Dependencies = append(chpb.Dependencies, chdep) - } - - return -} - -// MetadataToProto converts Chart.yaml data into protocol buffere Metadata. -func MetadataToProto(ch *chartutil.Chart) (*chartpbs.Metadata, error) { - if ch == nil { - return nil, ErrMissingChart - } - - chfi := ch.Chartfile() - - md := &chartpbs.Metadata{ - Name: chfi.Name, - Home: chfi.Home, - Version: chfi.Version, - Description: chfi.Description, - } - - md.Sources = make([]string, len(chfi.Source)) - copy(md.Sources, chfi.Source) - - md.Keywords = make([]string, len(chfi.Keywords)) - copy(md.Keywords, chfi.Keywords) - - for _, maintainer := range chfi.Maintainers { - md.Maintainers = append(md.Maintainers, &chartpbs.Maintainer{ - Name: maintainer.Name, - Email: maintainer.Email, - }) - } - - return md, nil -} - -// TemplatesToProto converts chart templates to their protobuf representation. -func TemplatesToProto(ch *chartutil.Chart) (tpls []*chartpbs.Template, err error) { - if ch == nil { - return nil, ErrMissingChart - } - - members, err := ch.LoadTemplates() - if err != nil { - return - } - - var tpl *chartpbs.Template - - for _, member := range members { - tpl = &chartpbs.Template{ - Name: member.Path, - Data: make([]byte, len(member.Content)), - } - - copy(tpl.Data, member.Content) - - tpls = append(tpls, tpl) - } - - return -} - -// OverridesToProto converts arbitrary TOML override data to Config data. -func OverridesToProto(values []byte) *chartpbs.Config { - return &chartpbs.Config{ - Raw: string(values), - } -} - -// ValuesToProto converts a chart's values.toml data to protobuf. -func ValuesToProto(ch *chartutil.Chart) (*chartpbs.Config, error) { - if ch == nil { - return nil, ErrMissingChart - } - - vals, err := ch.LoadValues() - if err != nil { - //return nil, ErrMissingValues - vals = map[string]interface{}{} - } - - var buf bytes.Buffer - if err = vals.Encode(&buf); err != nil { - return nil, err - } - - cfgVals := new(chartpbs.Config) - cfgVals.Raw = buf.String() - - return cfgVals, nil -} diff --git a/pkg/helm/convert_test.go b/pkg/helm/convert_test.go deleted file mode 100644 index 6fcb024d6..000000000 --- a/pkg/helm/convert_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package helm - -import ( - "testing" - - "gopkg.in/yaml.v2" - - chartutil "k8s.io/helm/pkg/chart" -) - -func TestInstallReleaseOverrides(t *testing.T) { - // FIXME: This can't currently run unless a Tiller server is running, simply - // because --dry-run still uses the server. There's already a WIP for a - // testing harness, so this can be ported when that is done. - t.Skip() - - vals := `name = "mariner"` - ch := "./testdata/albatross" - ir, err := InstallRelease([]byte(vals), "foo", ch, true) - if err != nil { - t.Fatalf("Failed to release: %s", err) - } - - if len(ir.Release.Manifest) == 0 { - t.Fatalf("Expected a manifest.") - } - - // Parse the result and see if the override worked - d := map[string]interface{}{} - if err := yaml.Unmarshal([]byte(ir.Release.Manifest), d); err != nil { - t.Fatalf("Failed to unmarshal manifest: %s", err) - } - - if d["name"] != "mariner" { - t.Errorf("Unexpected name %q", d["name"]) - } - - if d["home"] != "nest" { - t.Errorf("Unexpected home %q", d["home"]) - } -} - -func TestOverridesToProto(t *testing.T) { - override := []byte(`test = "foo"`) - c := OverridesToProto(override) - if c.Raw != string(override) { - t.Errorf("Expected %q to match %q", c.Raw, override) - } -} - -func TestChartToProto(t *testing.T) { - c, err := chartutil.LoadDir("./testdata/albatross") - if err != nil { - t.Fatalf("failed to load testdata chart: %s", err) - } - - p, err := ChartToProto(c) - if err != nil { - t.Fatalf("failed to conver chart to proto: %s", err) - } - - if p.Metadata.Name != c.Chartfile().Name { - t.Errorf("Expected names to match.") - } -} diff --git a/pkg/helm/error.go b/pkg/helm/error.go deleted file mode 100644 index 450999246..000000000 --- a/pkg/helm/error.go +++ /dev/null @@ -1,22 +0,0 @@ -package helm - -const ( - // ErrNotImplemented indicates that this API is not implemented. - ErrNotImplemented = Error("helm api not implemented") - // ErrInvalidSrvAddr indicates an invalid address to the Tiller server. - ErrInvalidSrvAddr = Error("invalid tiller address") - // ErrMissingTpls indicates that the templates are missing from a chart. - ErrMissingTpls = Error("missing chart templates") - // ErrMissingChart indicates that the Chart.yaml data is missing. - ErrMissingChart = Error("missing chart metadata") - // ErrMissingValues indicates that the config values.yaml data is missing. - ErrMissingValues = Error("missing chart values") -) - -// Error represents a Helm client error. -type Error string - -// Error returns a string representation of this error. -func (e Error) Error() string { - return string(e) -} diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go deleted file mode 100644 index 24a87aa8d..000000000 --- a/pkg/helm/helm.go +++ /dev/null @@ -1,107 +0,0 @@ -package helm - -import ( - "golang.org/x/net/context" - - chartutil "k8s.io/helm/pkg/chart" - "k8s.io/helm/pkg/proto/hapi/services" -) - -// Config defines a gRPC client's configuration. -var Config = &config{ - ServAddr: ":44134", - Insecure: true, -} - -// ListReleases lists the current releases. -func ListReleases(limit int, offset string, sort services.ListSort_SortBy, order services.ListSort_SortOrder, filter string) (*services.ListReleasesResponse, error) { - c := Config.client() - if err := c.dial(); err != nil { - return nil, err - } - defer c.Close() - - req := &services.ListReleasesRequest{ - Limit: int64(limit), - Offset: offset, - SortBy: sort, - SortOrder: order, - Filter: filter, - } - cli, err := c.impl.ListReleases(context.TODO(), req, c.cfg.CallOpts()...) - if err != nil { - return nil, err - } - - return cli.Recv() -} - -// GetReleaseStatus returns the given release's status. -func GetReleaseStatus(name string) (*services.GetReleaseStatusResponse, error) { - c := Config.client() - if err := c.dial(); err != nil { - return nil, err - } - defer c.Close() - - req := &services.GetReleaseStatusRequest{Name: name} - return c.impl.GetReleaseStatus(context.TODO(), req, c.cfg.CallOpts()...) -} - -// GetReleaseContent returns the configuration for a given release. -func GetReleaseContent(name string) (*services.GetReleaseContentResponse, error) { - c := Config.client() - if err := c.dial(); err != nil { - return nil, err - } - defer c.Close() - - req := &services.GetReleaseContentRequest{Name: name} - return c.impl.GetReleaseContent(context.TODO(), req, c.cfg.CallOpts()...) -} - -// UpdateRelease updates a release to a new/different chart. -// TODO: This must take more than just name for an arg. -func UpdateRelease(name string) (*services.UpdateReleaseResponse, error) { - return nil, ErrNotImplemented -} - -// UninstallRelease uninstalls a named release and returns the response. -func UninstallRelease(name string, dryRun bool) (*services.UninstallReleaseResponse, error) { - - if dryRun { - // In the dry run case, just see if the release exists. - res, err := GetReleaseContent(name) - if err != nil { - return &services.UninstallReleaseResponse{}, err - } - return &services.UninstallReleaseResponse{Release: res.Release}, nil - } - - u := &services.UninstallReleaseRequest{ - Name: name, - } - return Config.client().uninstall(u) -} - -// InstallRelease installs a new chart and returns the release response. -func InstallRelease(rawVals []byte, name string, chStr string, dryRun bool) (*services.InstallReleaseResponse, error) { - chfi, err := chartutil.LoadChart(chStr) - if err != nil { - return nil, err - } - - chpb, err := ChartToProto(chfi) - if err != nil { - return nil, err - } - - vals := OverridesToProto(rawVals) - - return Config.client().install(&services.InstallReleaseRequest{ - Chart: chpb, - Values: vals, - DryRun: dryRun, - Name: name, - }) -} diff --git a/pkg/helm/testdata/albatross-overrides.toml b/pkg/helm/testdata/albatross-overrides.toml deleted file mode 100644 index 1a7136d8b..000000000 --- a/pkg/helm/testdata/albatross-overrides.toml +++ /dev/null @@ -1 +0,0 @@ -name = "foo" diff --git a/pkg/helm/testdata/albatross/Chart.yaml b/pkg/helm/testdata/albatross/Chart.yaml deleted file mode 100644 index e01790950..000000000 --- a/pkg/helm/testdata/albatross/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: albatross -description: testing chart -version: 0.1.0 -home: "https://k8s.io/helm" diff --git a/pkg/helm/testdata/albatross/templates/albatross.yaml b/pkg/helm/testdata/albatross/templates/albatross.yaml deleted file mode 100644 index 84ac83201..000000000 --- a/pkg/helm/testdata/albatross/templates/albatross.yaml +++ /dev/null @@ -1,3 +0,0 @@ -# Test data. Not a valid Kubernetes manifest -name: {{.name}} -home: {{.home}} diff --git a/pkg/helm/testdata/albatross/values.toml b/pkg/helm/testdata/albatross/values.toml deleted file mode 100644 index d13308e99..000000000 --- a/pkg/helm/testdata/albatross/values.toml +++ /dev/null @@ -1,2 +0,0 @@ -name = "albatross" -home = "nest" diff --git a/pkg/helm/traverse.go b/pkg/helm/traverse.go deleted file mode 100644 index d9c7d1b8e..000000000 --- a/pkg/helm/traverse.go +++ /dev/null @@ -1,115 +0,0 @@ -package helm - -import ( - chartutil "k8s.io/helm/pkg/chart" -) - -// -// TODO - we should probably consolidate -// most of the code in this package, that -// is specific to charts, into chartutil. -// - -// Walk a chart's dependency tree, returning -// a pointer to the root chart. -// -// The following is an example chart dependency -// hierarchy and the structure of a chartObj -// post traversal. (note some chart files are -// omitted for brevity), -// -// mychart/ -// charts/ -// chart_A/ -// charts/ -// chart_B/ -// chart_C/ -// charts/ -// chart_F/ -// chart_D/ -// charts/ -// chart_E/ -// chart_F/ -// -// -// chart: mychart (deps = 2) -// | -// |----> chart_A (deps = 2) -// | -// |--------> chart_B (deps = 0) -// | -// |--------> chart_C (deps = 1) -// | -// |------------> chart_F (deps = 0) -// | -// |----> chart_D (deps = 2) -// | -// |--------> chart_E (deps = 0) -// | -// |--------> chart_F (deps = 0) -// -// - -// WalkChartFile walks a chart and returns a *chartObj. -// -// FIXME: Why does an exported function return an unexported struct whose only -// exported method is to return the object passed into this method? -func WalkChartFile(chfi *chartutil.Chart) (*chartObj, error) { - root := &chartObj{file: chfi} - err := root.walkChartDeps(chfi) - - return root, err -} - -type chartObj struct { - file *chartutil.Chart - deps []*chartObj -} - -// File returns the *chartutil.Chart associated with this *chartObj. -func (chd *chartObj) File() *chartutil.Chart { - return chd.file -} - -func (chs *chartObj) walkChartDeps(chfi *chartutil.Chart) error { - if hasDeps(chfi) { - names, err := chfi.ChartDepNames() - if err != nil { - return err - } - - if len(names) > 0 { - chs.deps = append(chs.deps, resolveChartDeps(names)...) - } - } - - return nil -} - -func resolveChartDeps(names []string) (deps []*chartObj) { - for _, name := range names { - chfi, err := chartutil.LoadDir(name) - if err != nil { - return - } - - chs := &chartObj{file: chfi} - err = chs.walkChartDeps(chfi) - if err != nil { - return - } - - deps = append(deps, chs) - } - - return -} - -func hasDeps(chfi *chartutil.Chart) bool { - names, err := chfi.ChartDepNames() - if err != nil { - return false - } - - return chfi.ChartsDir() != "" && len(names) > 0 -} From 56f519ab3880e9a64c939c2cbfad1f7a5fbb4ad6 Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Wed, 15 Jun 2016 16:46:10 -0600 Subject: [PATCH 2/3] ref(pkg/helm): move pkg/helmx to pkg/helm & remove feature toggle --- pkg/helm/client.go | 128 +++++++++++++++++++++++++++++++ pkg/helm/compat.go | 57 ++++++++++++++ pkg/helm/option.go | 183 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 368 insertions(+) create mode 100644 pkg/helm/client.go create mode 100644 pkg/helm/compat.go create mode 100644 pkg/helm/option.go diff --git a/pkg/helm/client.go b/pkg/helm/client.go new file mode 100644 index 000000000..fae1d6a31 --- /dev/null +++ b/pkg/helm/client.go @@ -0,0 +1,128 @@ +package helm + +import ( + "google.golang.org/grpc" + "k8s.io/helm/pkg/chartutil" + rls "k8s.io/helm/pkg/proto/hapi/services" + "os" +) + +const ( + // $HELM_HOST envvar + HelmHostEnvVar = "HELM_HOST" + + // $HELM_HOME envvar + HelmHomeEnvVar = "HELM_HOME" + + // Default tiller server host address. + DefaultHelmHost = ":44134" + + // Default $HELM_HOME envvar value + DefaultHelmHome = "$HOME/.helm" +) + +// Helm client manages client side of the helm-tiller protocol +type Client struct { + opts options +} + +func NewClient(opts ...Option) *Client { + return new(Client).Init().Option(opts...) +} + +// Configure the helm client with the provided options +func (h *Client) Option(opts ...Option) *Client { + for _, opt := range opts { + opt(&h.opts) + } + return h +} + +// Initializes the helm client with default options +func (h *Client) Init() *Client { + return h.Option(HelmHost(DefaultHelmHost)). + Option(HelmHome(os.ExpandEnv(DefaultHelmHome))) +} + +// ListReleases lists the current releases. +func (h *Client) ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + return h.opts.rpcListReleases(rls.NewReleaseServiceClient(c), opts...) +} + +// InstallRelease installs a new chart and returns the release response. +func (h *Client) InstallRelease(chStr string, opts ...InstallOption) (*rls.InstallReleaseResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + chart, err := chartutil.Load(chStr) + if err != nil { + return nil, err + } + + return h.opts.rpcInstallRelease(chart, rls.NewReleaseServiceClient(c), opts...) +} + +// UninstallRelease uninstalls a named release and returns the response. +// +// Note: there aren't currently any supported DeleteOptions, but they are +// kept in the API signature as a placeholder for future additions. +func (h *Client) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + return h.opts.rpcDeleteRelease(rlsName, rls.NewReleaseServiceClient(c), opts...) +} + +// UpdateRelease updates a release to a new/different chart. +// +// Note: there aren't currently any supported UpdateOptions, but they +// are kept in the API signature as a placeholder for future additions. +func (h *Client) UpdateRelease(rlsName string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + return h.opts.rpcUpdateRelease(rlsName, rls.NewReleaseServiceClient(c), opts...) +} + +// ReleaseStatus returns the given release's status. +// +// Note: there aren't currently any supported StatusOptions, +// but they are kept in the API signature as a placeholder for future additions. +func (h *Client) ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + return h.opts.rpcGetReleaseStatus(rlsName, rls.NewReleaseServiceClient(c), opts...) +} + +// ReleaseContent returns the configuration for a given release. +// +// Note: there aren't currently any supported ContentOptions, but +// they are kept in the API signature as a placeholder for future additions. +func (h *Client) ReleaseContent(rlsName string, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) { + c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) + if err != nil { + return nil, err + } + defer c.Close() + + return h.opts.rpcGetReleaseContent(rlsName, rls.NewReleaseServiceClient(c), opts...) +} diff --git a/pkg/helm/compat.go b/pkg/helm/compat.go new file mode 100644 index 000000000..c33214c30 --- /dev/null +++ b/pkg/helm/compat.go @@ -0,0 +1,57 @@ +package helm + +import ( + rls "k8s.io/helm/pkg/proto/hapi/services" +) + +// These APIs are a temporary abstraction layer that captures the interaction between the current cmd/helm and old +// pkg/helm implementations. Post refactor the cmd/helm package will use the APIs exposed on helm.Client directly. + +var Config struct { + ServAddr string +} + +// Soon to be deprecated helm ListReleases API. +func ListReleases(limit int, offset string, sort rls.ListSort_SortBy, order rls.ListSort_SortOrder, filter string) (*rls.ListReleasesResponse, error) { + opts := []ReleaseListOption{ + ReleaseListLimit(limit), + ReleaseListOffset(offset), + ReleaseListFilter(filter), + ReleaseListSort(int32(sort)), + ReleaseListOrder(int32(order)), + } + return NewClient(HelmHost(Config.ServAddr)).ListReleases(opts...) +} + +// Soon to be deprecated helm GetReleaseStatus API. +func GetReleaseStatus(rlsName string) (*rls.GetReleaseStatusResponse, error) { + return NewClient(HelmHost(Config.ServAddr)).ReleaseStatus(rlsName) +} + +// Soon to be deprecated helm GetReleaseContent API. +func GetReleaseContent(rlsName string) (*rls.GetReleaseContentResponse, error) { + return NewClient(HelmHost(Config.ServAddr)).ReleaseContent(rlsName) +} + +// Soon to be deprecated helm UpdateRelease API. +func UpdateRelease(rlsName string) (*rls.UpdateReleaseResponse, error) { + return NewClient(HelmHost(Config.ServAddr)).UpdateRelease(rlsName) +} + +// Soon to be deprecated helm InstallRelease API. +func InstallRelease(vals []byte, rlsName, chStr string, dryRun bool) (*rls.InstallReleaseResponse, error) { + client := NewClient(HelmHost(Config.ServAddr)) + if dryRun { + client.Option(DryRun()) + } + return client.InstallRelease(chStr, ValueOverrides(vals), ReleaseName(rlsName)) +} + +// Soon to be deprecated helm UninstallRelease API. +func UninstallRelease(rlsName string, dryRun bool) (*rls.UninstallReleaseResponse, error) { + client := NewClient(HelmHost(Config.ServAddr)) + if dryRun { + client.Option(DryRun()) + } + return client.DeleteRelease(rlsName) +} diff --git a/pkg/helm/option.go b/pkg/helm/option.go new file mode 100644 index 000000000..906b27c93 --- /dev/null +++ b/pkg/helm/option.go @@ -0,0 +1,183 @@ +package helm + +import ( + "fmt" + "golang.org/x/net/context" + cpb "k8s.io/helm/pkg/proto/hapi/chart" + rls "k8s.io/helm/pkg/proto/hapi/services" +) + +// Option allows specifying various settings configurable by +// the helm client user for overriding the defaults used when +// issuing rpc's to the Tiller release server. +type Option func(*options) + +// options specify optional settings used by the helm client. +type options struct { + // value of helm host override + home string + // value of helm home override + host string + // name of chart + chart string + // if set dry-run helm client calls + dryRun bool + // release list options are applied directly to the list releases request + listReq rls.ListReleasesRequest + // release install options are applied directly to the install release request + instReq rls.InstallReleaseRequest +} + +// DryRun returns an Option which instructs the helm client to dry-run tiller rpcs. +func DryRun() Option { + return func(opts *options) { + opts.dryRun = true + } +} + +// HelmHome specifies the location of helm home, (default = "$HOME/.helm"). +func HelmHome(home string) Option { + return func(opts *options) { + opts.home = home + } +} + +// HelmHost specifies the host address of the Tiller release server, (default = ":44134"). +func HelmHost(host string) Option { + return func(opts *options) { + opts.host = host + } +} + +// ReleaseListOption allows specifying various settings +// configurable by the helm client user for overriding +// the defaults used when running the `helm list` command. +type ReleaseListOption func(*options) + +// ReleaseListOffset specifies the offset into a list of releases. +func ReleaseListOffset(offset string) ReleaseListOption { + return func(opts *options) { + opts.listReq.Offset = offset + } +} + +// ReleaseListFilter specifies a filter to apply a list of releases. +func ReleaseListFilter(filter string) ReleaseListOption { + return func(opts *options) { + opts.listReq.Filter = filter + } +} + +// ReleaseListLimit set an upper bound on the number of releases returned. +func ReleaseListLimit(limit int) ReleaseListOption { + return func(opts *options) { + opts.listReq.Limit = int64(limit) + } +} + +// ReleaseListOrder specifies how to order a list of releases. +func ReleaseListOrder(order int32) ReleaseListOption { + return func(opts *options) { + opts.listReq.SortOrder = rls.ListSort_SortOrder(order) + } +} + +// ReleaseListSort specifies how to sort a release list. +func ReleaseListSort(sort int32) ReleaseListOption { + return func(opts *options) { + opts.listReq.SortBy = rls.ListSort_SortBy(sort) + } +} + +// InstallOption allows specifying various settings +// configurable by the helm client user for overriding +// the defaults used when running the `helm install` command. +type InstallOption func(*options) + +// ValueOverrides specifies a list of values to include when installing. +func ValueOverrides(raw []byte) InstallOption { + return func(opts *options) { + opts.instReq.Values = &cpb.Config{Raw: string(raw)} + } +} + +// ReleaseName specifies the name of the release when installing. +func ReleaseName(name string) InstallOption { + return func(opts *options) { + opts.instReq.Name = name + } +} + +// ContentOption -- TODO +type ContentOption func(*options) + +// StatusOption -- TODO +type StatusOption func(*options) + +// DeleteOption -- TODO +type DeleteOption func(*options) + +// UpdateOption -- TODO +type UpdateOption func(*options) + +// RPC helpers defined on `options` type. Note: These actually execute the +// the corresponding tiller RPC. There is no particular reason why these +// are APIs are hung off `options`, they are internal to pkg/helm to remain +// malleable. + +// Executes tiller.ListReleases RPC. +func (o *options) rpcListReleases(rlc rls.ReleaseServiceClient, opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) { + // apply release list options + for _, opt := range opts { + opt(o) + } + s, err := rlc.ListReleases(context.TODO(), &o.listReq) + if err != nil { + return nil, err + } + + return s.Recv() +} + +// Executes tiller.InstallRelease RPC. +func (o *options) rpcInstallRelease(chr *cpb.Chart, rlc rls.ReleaseServiceClient, opts ...InstallOption) (*rls.InstallReleaseResponse, error) { + // apply the install options + for _, opt := range opts { + opt(o) + } + o.instReq.Chart = chr + o.instReq.DryRun = o.dryRun + + return rlc.InstallRelease(context.TODO(), &o.instReq) +} + +// Executes tiller.UninstallRelease RPC. +func (o *options) rpcDeleteRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) { + if o.dryRun { + // In the dry run case, just see if the release exists + r, err := o.rpcGetReleaseContent(rlsName, rlc) + if err != nil { + return &rls.UninstallReleaseResponse{}, err + } + return &rls.UninstallReleaseResponse{Release: r.Release}, nil + } + + return rlc.UninstallRelease(context.TODO(), &rls.UninstallReleaseRequest{Name: rlsName}) +} + +// Executes tiller.UpdateRelease RPC. +func (o *options) rpcUpdateRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) { + return nil, fmt.Errorf("helm: UpdateRelease: not implemented") +} + +// Executes tiller.GetReleaseStatus RPC. +func (o *options) rpcGetReleaseStatus(rlsName string, rlc rls.ReleaseServiceClient, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) { + req := &rls.GetReleaseStatusRequest{Name: rlsName} + return rlc.GetReleaseStatus(context.TODO(), req) +} + +// Executes tiller.GetReleaseContent. +func (o *options) rpcGetReleaseContent(rlsName string, rlc rls.ReleaseServiceClient, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) { + req := &rls.GetReleaseContentRequest{Name: rlsName} + return rlc.GetReleaseContent(context.TODO(), req) +} From 5a1c54298f4c8ab8b381d5bb0daf0061f62bd588 Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Wed, 15 Jun 2016 16:47:17 -0600 Subject: [PATCH 3/3] ref(pkg/helm): remove pkg/helmx --- pkg/helmx/client.go | 128 ------------------------------- pkg/helmx/compat.go | 85 -------------------- pkg/helmx/option.go | 183 -------------------------------------------- 3 files changed, 396 deletions(-) delete mode 100644 pkg/helmx/client.go delete mode 100644 pkg/helmx/compat.go delete mode 100644 pkg/helmx/option.go diff --git a/pkg/helmx/client.go b/pkg/helmx/client.go deleted file mode 100644 index 8186c7e89..000000000 --- a/pkg/helmx/client.go +++ /dev/null @@ -1,128 +0,0 @@ -package helmx - -import ( - "google.golang.org/grpc" - "k8s.io/helm/pkg/chartutil" - rls "k8s.io/helm/pkg/proto/hapi/services" - "os" -) - -const ( - // $HELM_HOST envvar - HelmHostEnvVar = "HELM_HOST" - - // $HELM_HOME envvar - HelmHomeEnvVar = "HELM_HOME" - - // Default tiller server host address. - DefaultHelmHost = ":44134" - - // Default $HELM_HOME envvar value - DefaultHelmHome = "$HOME/.helm" -) - -// Helm client manages client side of the helm-tiller protocol -type Client struct { - opts options -} - -func NewClient(opts ...Option) *Client { - return new(Client).Init().Option(opts...) -} - -// Configure the helm client with the provided options -func (h *Client) Option(opts ...Option) *Client { - for _, opt := range opts { - opt(&h.opts) - } - return h -} - -// Initializes the helm client with default options -func (h *Client) Init() *Client { - return h.Option(HelmHost(DefaultHelmHost)). - Option(HelmHome(os.ExpandEnv(DefaultHelmHome))) -} - -// ListReleases lists the current releases. -func (h *Client) ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - return h.opts.rpcListReleases(rls.NewReleaseServiceClient(c), opts...) -} - -// InstallRelease installs a new chart and returns the release response. -func (h *Client) InstallRelease(chStr string, opts ...InstallOption) (*rls.InstallReleaseResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - chart, err := chartutil.Load(chStr) - if err != nil { - return nil, err - } - - return h.opts.rpcInstallRelease(chart, rls.NewReleaseServiceClient(c), opts...) -} - -// UninstallRelease uninstalls a named release and returns the response. -// -// Note: there aren't currently any supported DeleteOptions, but they are -// kept in the API signature as a placeholder for future additions. -func (h *Client) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - return h.opts.rpcDeleteRelease(rlsName, rls.NewReleaseServiceClient(c), opts...) -} - -// UpdateRelease updates a release to a new/different chart. -// -// Note: there aren't currently any supported UpdateOptions, but they -// are kept in the API signature as a placeholder for future additions. -func (h *Client) UpdateRelease(rlsName string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - return h.opts.rpcUpdateRelease(rlsName, rls.NewReleaseServiceClient(c), opts...) -} - -// ReleaseStatus returns the given release's status. -// -// Note: there aren't currently any supported StatusOptions, -// but they are kept in the API signature as a placeholder for future additions. -func (h *Client) ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - return h.opts.rpcGetReleaseStatus(rlsName, rls.NewReleaseServiceClient(c), opts...) -} - -// ReleaseContent returns the configuration for a given release. -// -// Note: there aren't currently any supported ContentOptions, but -// they are kept in the API signature as a placeholder for future additions. -func (h *Client) ReleaseContent(rlsName string, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) { - c, err := grpc.Dial(h.opts.host, grpc.WithInsecure()) - if err != nil { - return nil, err - } - defer c.Close() - - return h.opts.rpcGetReleaseContent(rlsName, rls.NewReleaseServiceClient(c), opts...) -} diff --git a/pkg/helmx/compat.go b/pkg/helmx/compat.go deleted file mode 100644 index 2f22386b3..000000000 --- a/pkg/helmx/compat.go +++ /dev/null @@ -1,85 +0,0 @@ -package helmx - -import ( - "k8s.io/helm/pkg/helm" - rls "k8s.io/helm/pkg/proto/hapi/services" -) - -// feature toggle helmx APIs while WIP -const EnableNewHelm = false - -// These APIs are a temporary abstraction layer that captures the interaction between the current cmd/helm and old -// pkg/helm implementations. Post refactor the cmd/helm package will use the APIs exposed on helm.Client directly. - -var Config struct { - ServAddr string -} - -// Soon to be deprecated helm ListReleases API. See pkg/helmx. -func ListReleases(limit int, offset string, sort rls.ListSort_SortBy, order rls.ListSort_SortOrder, filter string) (*rls.ListReleasesResponse, error) { - if !EnableNewHelm { - return helm.ListReleases(limit, offset, sort, order, filter) - } - - opts := []ReleaseListOption{ - ReleaseListLimit(limit), - ReleaseListOffset(offset), - ReleaseListFilter(filter), - ReleaseListSort(int32(sort)), - ReleaseListOrder(int32(order)), - } - return NewClient(HelmHost(Config.ServAddr)).ListReleases(opts...) -} - -// Soon to be deprecated helm GetReleaseStatus API. See pkg/helmx. -func GetReleaseStatus(rlsName string) (*rls.GetReleaseStatusResponse, error) { - if !EnableNewHelm { - return helm.GetReleaseStatus(rlsName) - } - - return NewClient(HelmHost(Config.ServAddr)).ReleaseStatus(rlsName) -} - -// Soon to be deprecated helm GetReleaseContent API. See pkg/helmx. -func GetReleaseContent(rlsName string) (*rls.GetReleaseContentResponse, error) { - if !EnableNewHelm { - return helm.GetReleaseContent(rlsName) - } - - return NewClient(HelmHost(Config.ServAddr)).ReleaseContent(rlsName) -} - -// Soon to be deprecated helm UpdateRelease API. See pkg/helmx. -func UpdateRelease(rlsName string) (*rls.UpdateReleaseResponse, error) { - if !EnableNewHelm { - return helm.UpdateRelease(rlsName) - } - - return NewClient(HelmHost(Config.ServAddr)).UpdateRelease(rlsName) -} - -// Soon to be deprecated helm InstallRelease API. See pkg/helmx. -func InstallRelease(vals []byte, rlsName, chStr string, dryRun bool) (*rls.InstallReleaseResponse, error) { - if !EnableNewHelm { - return helm.InstallRelease(vals, rlsName, chStr, dryRun) - } - - client := NewClient(HelmHost(Config.ServAddr)) - if dryRun { - client.Option(DryRun()) - } - return client.InstallRelease(chStr, ValueOverrides(vals), ReleaseName(rlsName)) -} - -// Soon to be deprecated helm UninstallRelease API. See pkg/helmx. -func UninstallRelease(rlsName string, dryRun bool) (*rls.UninstallReleaseResponse, error) { - if !EnableNewHelm { - return helm.UninstallRelease(rlsName, dryRun) - } - - client := NewClient(HelmHost(Config.ServAddr)) - if dryRun { - client.Option(DryRun()) - } - return client.DeleteRelease(rlsName) -} diff --git a/pkg/helmx/option.go b/pkg/helmx/option.go deleted file mode 100644 index 4ae7dfa58..000000000 --- a/pkg/helmx/option.go +++ /dev/null @@ -1,183 +0,0 @@ -package helmx - -import ( - "fmt" - "golang.org/x/net/context" - cpb "k8s.io/helm/pkg/proto/hapi/chart" - rls "k8s.io/helm/pkg/proto/hapi/services" -) - -// Option allows specifying various settings configurable by -// the helm client user for overriding the defaults used when -// issuing rpc's to the Tiller release server. -type Option func(*options) - -// options specify optional settings used by the helm client. -type options struct { - // value of helm host override - home string - // value of helm home override - host string - // name of chart - chart string - // if set dry-run helm client calls - dryRun bool - // release list options are applied directly to the list releases request - listReq rls.ListReleasesRequest - // release install options are applied directly to the install release request - instReq rls.InstallReleaseRequest -} - -// DryRun returns an Option which instructs the helm client to dry-run tiller rpcs. -func DryRun() Option { - return func(opts *options) { - opts.dryRun = true - } -} - -// HelmHome specifies the location of helm home, (default = "$HOME/.helm"). -func HelmHome(home string) Option { - return func(opts *options) { - opts.home = home - } -} - -// HelmHost specifies the host address of the Tiller release server, (default = ":44134"). -func HelmHost(host string) Option { - return func(opts *options) { - opts.host = host - } -} - -// ReleaseListOption allows specifying various settings -// configurable by the helm client user for overriding -// the defaults used when running the `helm list` command. -type ReleaseListOption func(*options) - -// ReleaseListOffset specifies the offset into a list of releases. -func ReleaseListOffset(offset string) ReleaseListOption { - return func(opts *options) { - opts.listReq.Offset = offset - } -} - -// ReleaseListFilter specifies a filter to apply a list of releases. -func ReleaseListFilter(filter string) ReleaseListOption { - return func(opts *options) { - opts.listReq.Filter = filter - } -} - -// ReleaseListLimit set an upper bound on the number of releases returned. -func ReleaseListLimit(limit int) ReleaseListOption { - return func(opts *options) { - opts.listReq.Limit = int64(limit) - } -} - -// ReleaseListOrder specifies how to order a list of releases. -func ReleaseListOrder(order int32) ReleaseListOption { - return func(opts *options) { - opts.listReq.SortOrder = rls.ListSort_SortOrder(order) - } -} - -// ReleaseListSort specifies how to sort a release list. -func ReleaseListSort(sort int32) ReleaseListOption { - return func(opts *options) { - opts.listReq.SortBy = rls.ListSort_SortBy(sort) - } -} - -// InstallOption allows specifying various settings -// configurable by the helm client user for overriding -// the defaults used when running the `helm install` command. -type InstallOption func(*options) - -// ValueOverrides specifies a list of values to include when installing. -func ValueOverrides(raw []byte) InstallOption { - return func(opts *options) { - opts.instReq.Values = &cpb.Config{Raw: string(raw)} - } -} - -// ReleaseName specifies the name of the release when installing. -func ReleaseName(name string) InstallOption { - return func(opts *options) { - opts.instReq.Name = name - } -} - -// ContentOption -- TODO -type ContentOption func(*options) - -// StatusOption -- TODO -type StatusOption func(*options) - -// DeleteOption -- TODO -type DeleteOption func(*options) - -// UpdateOption -- TODO -type UpdateOption func(*options) - -// RPC helpers defined on `options` type. Note: These actually execute the -// the corresponding tiller RPC. There is no particular reason why these -// are APIs are hung off `options`, they are internal to pkg/helm to remain -// malleable. - -// Executes tiller.ListReleases RPC. -func (o *options) rpcListReleases(rlc rls.ReleaseServiceClient, opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) { - // apply release list options - for _, opt := range opts { - opt(o) - } - s, err := rlc.ListReleases(context.TODO(), &o.listReq) - if err != nil { - return nil, err - } - - return s.Recv() -} - -// Executes tiller.InstallRelease RPC. -func (o *options) rpcInstallRelease(chr *cpb.Chart, rlc rls.ReleaseServiceClient, opts ...InstallOption) (*rls.InstallReleaseResponse, error) { - // apply the install options - for _, opt := range opts { - opt(o) - } - o.instReq.Chart = chr - o.instReq.DryRun = o.dryRun - - return rlc.InstallRelease(context.TODO(), &o.instReq) -} - -// Executes tiller.UninstallRelease RPC. -func (o *options) rpcDeleteRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) { - if o.dryRun { - // In the dry run case, just see if the release exists - r, err := o.rpcGetReleaseContent(rlsName, rlc) - if err != nil { - return &rls.UninstallReleaseResponse{}, err - } - return &rls.UninstallReleaseResponse{Release: r.Release}, nil - } - - return rlc.UninstallRelease(context.TODO(), &rls.UninstallReleaseRequest{Name: rlsName}) -} - -// Executes tiller.UpdateRelease RPC. -func (o *options) rpcUpdateRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) { - return nil, fmt.Errorf("helm: UpdateRelease: not implemented") -} - -// Executes tiller.GetReleaseStatus RPC. -func (o *options) rpcGetReleaseStatus(rlsName string, rlc rls.ReleaseServiceClient, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) { - req := &rls.GetReleaseStatusRequest{Name: rlsName} - return rlc.GetReleaseStatus(context.TODO(), req) -} - -// Executes tiller.GetReleaseContent. -func (o *options) rpcGetReleaseContent(rlsName string, rlc rls.ReleaseServiceClient, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) { - req := &rls.GetReleaseContentRequest{Name: rlsName} - return rlc.GetReleaseContent(context.TODO(), req) -}