ref(pkg/helm): package helm refactor

includes:
 - (#825) comptability interface between
          old/pkg/helm and new/pkg/helm

 - (#827) helm client scaffolding and
          rpc / release options
pull/829/head
fibonacci1729 9 years ago
parent 54f0ffe0cb
commit ea2e8e80fc

@ -0,0 +1,128 @@
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...)
}

@ -0,0 +1,84 @@
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)
}
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)
}

@ -0,0 +1,180 @@
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"
)
// # Options
//
// 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
}
}
// # Release List Options
//
// 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)
}
}
// # Install Options
//
// 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.
// TODO: Executes tiller.ListReleases RPC. See issue #828
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()
}
// TODO: Executes tiller.InstallRelease RPC. See issue #828
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
return rlc.InstallRelease(context.TODO(), &o.instReq)
}
// TODO: Executes tiller.UninstallRelease RPC. See issue #828
func (o *options) rpcDeleteRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) {
return nil, fmt.Errorf("helm: rpcDeleteRelease: not implemented")
}
// TODO: Executes tiller.UpdateRelease RPC. See issue #828
func (o *options) rpcUpdateRelease(rlsName string, rlc rls.ReleaseServiceClient, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) {
return nil, fmt.Errorf("helm: rpcUpdateRelease: not implemented")
}
// TODO: Executes tiller.GetReleaseStatus RPC. See issue #828
func (o *options) rpcGetReleaseStatus(rlsName string, rlc rls.ReleaseServiceClient, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) {
return nil, fmt.Errorf("helm: rpcGetReleaseStatus: not implemented")
}
// TODO: Executes tiller.GetReleaseConent. See issue #828
func (o *options) rpcGetReleaseContent(rlsName string, rlc rls.ReleaseServiceClient, opts ...ContentOption) (*rls.GetReleaseContentResponse, error) {
return nil, fmt.Errorf("helm: getReleaseContent: not implemented")
}
Loading…
Cancel
Save