Adam Reese 6 years ago
parent 8cdebdb2d5
commit 19398a2ef1
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

@ -18,13 +18,14 @@ package main // import "k8s.io/helm/cmd/helm"
import (
"fmt"
"log"
"os"
"strings"
"github.com/spf13/cobra"
// Import to initialize client auth plugins.
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/helm/pkg/helm"
helm_env "k8s.io/helm/pkg/helm/environment"
@ -32,7 +33,10 @@ import (
"k8s.io/helm/pkg/storage/driver"
)
var settings helm_env.EnvSettings
var (
settings helm_env.EnvSettings
config clientcmd.ClientConfig
)
var globalUsage = `The Kubernetes package manager
@ -52,7 +56,6 @@ Common actions from this point include:
Environment:
$HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm
$HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
$TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system")
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config")
`
@ -67,6 +70,8 @@ func newRootCmd(args []string) *cobra.Command {
settings.AddFlags(flags)
config = kube.GetConfig(flags)
out := cmd.OutOrStdout()
cmd.AddCommand(
@ -115,6 +120,17 @@ func newRootCmd(args []string) *cobra.Command {
return cmd
}
func init() {
log.SetFlags(log.Lshortfile)
}
func logf(format string, v ...interface{}) {
if settings.Debug {
format = fmt.Sprintf("[debug] %s\n", format)
log.Output(2, fmt.Sprintf(format, v...))
}
}
func main() {
cmd := newRootCmd(os.Args[1:])
if err := cmd.Execute(); err != nil {
@ -143,15 +159,17 @@ func ensureHelmClient(h helm.Interface) helm.Interface {
}
func newClient() helm.Interface {
cfg := kube.GetConfig(settings.KubeContext)
kc := kube.New(cfg)
kc := kube.New(config)
kc.Log = logf
clientset, err := kc.KubernetesClientSet()
if err != nil {
// TODO return error
panic(err)
log.Fatal(err)
}
// TODO add other backends
cfgmaps := driver.NewConfigMaps(clientset.CoreV1().ConfigMaps(settings.TillerNamespace))
cfgmaps := driver.NewSecrets(clientset.CoreV1().Secrets(getNamespace()))
cfgmaps.Log = logf
return helm.NewClient(
helm.KubeClient(kc),
@ -159,3 +177,10 @@ func newClient() helm.Interface {
helm.Discovery(clientset.Discovery()),
)
}
func getNamespace() string {
if ns, _, err := config.Namespace(); err == nil {
return ns
}
return "default"
}

@ -38,7 +38,6 @@ import (
"k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/strvals"
)
@ -107,7 +106,6 @@ charts in a repository, use 'helm search'.
type installCmd struct {
name string
namespace string
valueFiles valueFiles
chartPath string
dryRun bool
@ -186,7 +184,6 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f := cmd.Flags()
f.VarP(&inst.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.StringVarP(&inst.name, "name", "", "", "release name. If unspecified, it will autogenerate one for you")
f.StringVar(&inst.namespace, "namespace", "n", "namespace to install the release into. Defaults to the current kube config namespace.")
f.BoolVar(&inst.dryRun, "dry-run", false, "simulate an install")
f.BoolVar(&inst.disableHooks, "no-hooks", false, "prevent hooks from running during install")
f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production")
@ -213,10 +210,6 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
func (i *installCmd) run() error {
debug("CHART PATH: %s\n", i.chartPath)
if i.namespace == "" {
i.namespace = defaultNamespace()
}
rawVals, err := vals(i.valueFiles, i.values, i.stringValues)
if err != nil {
return err
@ -266,7 +259,7 @@ func (i *installCmd) run() error {
rel, err := i.client.InstallReleaseFromChart(
chartRequested,
i.namespace,
getNamespace(),
helm.ValueOverrides(rawVals),
helm.ReleaseName(i.name),
helm.InstallDryRun(i.dryRun),
@ -472,13 +465,6 @@ func generateName(nameTemplate string) (string, error) {
return b.String(), nil
}
func defaultNamespace() string {
if ns, _, err := kube.GetConfig(settings.KubeContext).Namespace(); err == nil {
return ns
}
return "default"
}
func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements) error {
missing := []string{}

@ -47,7 +47,6 @@ type lintCmd struct {
valueFiles valueFiles
values []string
sValues []string
namespace string
strict bool
paths []string
out io.Writer
@ -73,7 +72,6 @@ func newLintCmd(out io.Writer) *cobra.Command {
cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)")
cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings")
return cmd
@ -98,7 +96,7 @@ func (l *lintCmd) run() error {
var total int
var failures int
for _, path := range l.paths {
if linter, err := lintChart(path, rvals, l.namespace, l.strict); err != nil {
if linter, err := lintChart(path, rvals, getNamespace(), l.strict); err != nil {
fmt.Println("==> Skipping", path)
fmt.Println(err)
if err == errLintNoChart {

@ -69,7 +69,6 @@ type listCmd struct {
deleting bool
deployed bool
failed bool
namespace string
superseded bool
pending bool
client helm.Interface
@ -110,7 +109,6 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled")
f.BoolVar(&list.failed, "failed", false, "show failed releases")
f.BoolVar(&list.pending, "pending", false, "show pending releases")
f.StringVar(&list.namespace, "namespace", "n", "show releases within a specific namespace")
f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output")
// TODO: Do we want this as a feature of 'helm list'?
@ -139,7 +137,6 @@ func (l *listCmd) run() error {
helm.ReleaseListSort(int(sortBy)),
helm.ReleaseListOrder(int(sortOrder)),
helm.ReleaseListStatuses(stats),
helm.ReleaseListNamespace(l.namespace),
)
if err != nil {

@ -108,7 +108,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
func manuallyProcessArgs(args []string) ([]string, []string) {
known := []string{}
unknown := []string{}
kvargs := []string{"--kube-context", "--home", "--tiller-namespace"}
kvargs := []string{"--context", "--home", "--namespace"}
knownArg := func(a string) bool {
for _, pre := range kvargs {
if strings.HasPrefix(a, pre+"=") {
@ -121,7 +121,7 @@ func manuallyProcessArgs(args []string) ([]string, []string) {
switch a := args[i]; a {
case "--debug":
known = append(known, a)
case "--kube-context", "--home":
case "--context", "--home", "--namespace":
known = append(known, a, args[i+1])
i++
default:

@ -33,14 +33,13 @@ func TestManuallyProcessArgs(t *testing.T) {
input := []string{
"--debug",
"--foo", "bar",
"--kube-context", "test1",
"--context", "test1",
"--home=/tmp",
"--tiller-namespace=hello",
"command",
}
expectKnown := []string{
"--debug", "--kube-context", "test1", "--home=/tmp", "--tiller-namespace=hello",
"--debug", "--context", "test1", "--home=/tmp",
}
expectUnknown := []string{
@ -176,7 +175,6 @@ func TestSetupEnv(t *testing.T) {
{"HELM_PATH_CACHE", settings.Home.Cache()},
{"HELM_PATH_LOCAL_REPOSITORY", settings.Home.LocalRepository()},
{"HELM_PATH_STARTER", settings.Home.Starters()},
{"TILLER_NAMESPACE", settings.TillerNamespace},
} {
if got := os.Getenv(tt.name); got != tt.expect {
t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got)

@ -17,7 +17,6 @@ limitations under the License.
package main
import (
"fmt"
"io"
"text/template"
"time"
@ -75,8 +74,5 @@ func tpl(t string, vals map[string]interface{}, out io.Writer) error {
}
func debug(format string, args ...interface{}) {
if settings.Debug {
format = fmt.Sprintf("[debug] %s\n", format)
fmt.Printf(format, args...)
}
logf(format, args...)
}

@ -61,7 +61,6 @@ To render just one template in a chart, use '-x':
`
type templateCmd struct {
namespace string
valueFiles valueFiles
chartPath string
out io.Writer
@ -93,7 +92,6 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
f.StringVarP(&t.releaseName, "name", "", "RELEASE-NAME", "release name")
f.StringArrayVarP(&t.renderFiles, "execute", "x", []string{}, "only execute the given templates")
f.VarP(&t.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
f.StringVar(&t.namespace, "namespace", "n", "namespace to install the release into")
f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release")
@ -145,9 +143,6 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
}
}
if t.namespace == "" {
t.namespace = defaultNamespace()
}
// get combined values and create config
config, err := vals(t.valueFiles, t.values, t.stringValues)
if err != nil {
@ -178,7 +173,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
options := chartutil.ReleaseOptions{
Name: t.releaseName,
Time: time.Now(),
Namespace: t.namespace,
Namespace: getNamespace(),
}
err = chartutil.ProcessRequirementsEnabled(c, config)
@ -244,12 +239,11 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
}
if settings.Debug {
rel := &release.Release{
Name: t.releaseName,
Chart: c,
Config: config,
Version: 1,
Namespace: t.namespace,
Info: &release.Info{LastDeployed: time.Now()},
Name: t.releaseName,
Chart: c,
Config: config,
Version: 1,
Info: &release.Info{LastDeployed: time.Now()},
}
printRelease(os.Stdout, rel)
}

@ -69,13 +69,6 @@ func TestTemplateCmd(t *testing.T) {
expectKey: "subchart1/templates/service.yaml",
expectValue: "protocol: TCP\n name: apache",
},
{
name: "check_namespace",
desc: "verify --namespace",
args: []string{chartPath, "--namespace", "test"},
expectKey: "subchart1/templates/service.yaml",
expectValue: "namespace: \"test\"",
},
{
name: "check_release_name",
desc: "verify --release exists",

@ -68,7 +68,6 @@ type upgradeCmd struct {
verify bool
keyring string
install bool
namespace string
version string
timeout int64
resetValues bool
@ -125,7 +124,6 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading")
f.StringVar(&upgrade.keyring, "keyring", defaultKeyring(), "path to the keyring that contains public signing keys")
f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install")
f.StringVar(&upgrade.namespace, "namespace", "n", "namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace")
f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
f.Int64Var(&upgrade.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&upgrade.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
@ -153,20 +151,7 @@ func (u *upgradeCmd) run() error {
if u.install {
// If a release does not exist, install it. If another error occurs during
// the check, ignore the error and continue with the upgrade.
releaseHistory, err := u.client.ReleaseHistory(u.release, 1)
if err == nil {
if u.namespace == "" {
u.namespace = defaultNamespace()
}
previousReleaseNamespace := releaseHistory[0].Namespace
if previousReleaseNamespace != u.namespace {
fmt.Fprintf(u.out,
"WARNING: Namespace %q doesn't match with previous. Release will be deployed to %s\n",
u.namespace, previousReleaseNamespace,
)
}
}
_, err := u.client.ReleaseHistory(u.release, 1)
if err != nil && strings.Contains(err.Error(), driver.ErrReleaseNotFound(u.release).Error()) {
fmt.Fprintf(u.out, "Release %q does not exist. Installing it now.\n", u.release)
@ -182,7 +167,6 @@ func (u *upgradeCmd) run() error {
keyring: u.keyring,
values: u.values,
stringValues: u.stringValues,
namespace: u.namespace,
timeout: u.timeout,
wait: u.wait,
}

@ -75,8 +75,6 @@ type ListReleasesRequest struct {
// SortOrder is the ordering directive used for sorting.
SortOrder ListSortOrder `json:"sort_order,omityempty"`
StatusCodes []release.StatusCode `json:"status_codes,omityempty"`
// Namespace is the filter to select releases only from a specific namespace.
Namespace string `json:"namespace,omityempty"`
}
// ListReleasesResponse is a list of releases.

@ -37,22 +37,16 @@ var DefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm")
// EnvSettings describes all of the environment settings.
type EnvSettings struct {
// TillerNamespace is the namespace in which Tiller runs.
TillerNamespace string
// Home is the local path to the Helm home directory.
Home helmpath.Home
// Debug indicates whether or not Helm is running in Debug mode.
Debug bool
// KubeContext is the name of the kubeconfig context.
KubeContext string
}
// AddFlags binds flags to the given flagset.
func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar((*string)(&s.Home), "home", DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME")
fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use")
fs.BoolVar(&s.Debug, "debug", false, "enable verbose output")
fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller")
}
// Init sets values from the environment.
@ -72,9 +66,8 @@ func (s EnvSettings) PluginDirs() string {
// envMap maps flag names to envvars
var envMap = map[string]string{
"debug": "HELM_DEBUG",
"home": "HELM_HOME",
"tiller-namespace": "TILLER_NAMESPACE",
"debug": "HELM_DEBUG",
"home": "HELM_HOME",
}
func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) {
@ -85,11 +78,3 @@ func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) {
fs.Set(name, v)
}
}
// Deprecated
const (
HomeEnvVar = "HELM_HOME"
PluginEnvVar = "HELM_PLUGIN"
PluginDisableEnvVar = "HELM_NO_PLUGINS"
DebugEnvVar = "HELM_DEBUG"
)

@ -35,8 +35,8 @@ func TestEnvSettings(t *testing.T) {
envars map[string]string
// expected values
home, ns, kcontext, plugins string
debug bool
home, ns, plugins string
debug bool
}{
{
name: "defaults",
@ -47,7 +47,7 @@ func TestEnvSettings(t *testing.T) {
},
{
name: "with flags set",
args: []string{"--home", "/foo", "--debug", "--tiller-namespace=myns"},
args: []string{"--home", "/foo", "--debug"},
home: "/foo",
plugins: helmpath.Home("/foo").Plugins(),
ns: "myns",
@ -56,7 +56,7 @@ func TestEnvSettings(t *testing.T) {
{
name: "with envvars set",
args: []string{},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_DEBUG": "1", "TILLER_NAMESPACE": "yourns"},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_DEBUG": "1"},
home: "/bar",
plugins: helmpath.Home("/bar").Plugins(),
ns: "yourns",
@ -64,8 +64,8 @@ func TestEnvSettings(t *testing.T) {
},
{
name: "with flags and envvars set",
args: []string{"--home", "/foo", "--debug", "--tiller-namespace=myns"},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_DEBUG": "1", "TILLER_NAMESPACE": "yourns", "HELM_PLUGIN": "glade"},
args: []string{"--home", "/foo", "--debug"},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_DEBUG": "1", "HELM_PLUGIN": "glade"},
home: "/foo",
plugins: "glade",
ns: "myns",
@ -99,12 +99,6 @@ func TestEnvSettings(t *testing.T) {
if settings.Debug != tt.debug {
t.Errorf("expected debug %t, got %t", tt.debug, settings.Debug)
}
if settings.TillerNamespace != tt.ns {
t.Errorf("expected tiller-namespace %q, got %q", tt.ns, settings.TillerNamespace)
}
if settings.KubeContext != tt.kcontext {
t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
}
cleanup()
})

@ -48,7 +48,6 @@ func TestListReleases_VerifyOptions(t *testing.T) {
rls.Status_DEPLOYED,
rls.Status_SUPERSEDED,
}
var namespace = "namespace"
// Expected ListReleasesRequest message
exp := &hapi.ListReleasesRequest{
@ -58,7 +57,6 @@ func TestListReleases_VerifyOptions(t *testing.T) {
SortBy: hapi.ListSortBy(sortBy),
SortOrder: hapi.ListSortOrder(sortOrd),
StatusCodes: codes,
Namespace: namespace,
}
// Options used in ListReleases
@ -69,7 +67,6 @@ func TestListReleases_VerifyOptions(t *testing.T) {
ReleaseListOffset(offset),
ReleaseListFilter(filter),
ReleaseListStatuses(codes),
ReleaseListNamespace(namespace),
}
// BeforeCall option to intercept Helm client ListReleasesRequest
@ -99,7 +96,6 @@ func TestInstallRelease_VerifyOptions(t *testing.T) {
// Options testdata
var disableHooks = true
var releaseName = "test"
var namespace = "default"
var reuseName = true
var dryRun = true
var chartName = "alpine"
@ -113,7 +109,6 @@ func TestInstallRelease_VerifyOptions(t *testing.T) {
DryRun: dryRun,
Name: releaseName,
DisableHooks: disableHooks,
Namespace: namespace,
ReuseName: reuseName,
}
@ -139,7 +134,7 @@ func TestInstallRelease_VerifyOptions(t *testing.T) {
})
client := NewClient(b4c)
if _, err := client.InstallRelease(chartPath, namespace, ops...); err != errSkip {
if _, err := client.InstallRelease(chartPath, "", ops...); err != errSkip {
t.Fatalf("did not expect error but got (%v)\n``", err)
}

@ -138,13 +138,6 @@ func ReleaseListStatuses(statuses []release.StatusCode) ReleaseListOption {
}
}
// ReleaseListNamespace specifies the namespace to list releases from
func ReleaseListNamespace(namespace string) ReleaseListOption {
return func(opts *options) {
opts.listReq.Namespace = namespace
}
}
// InstallOption allows specifying various settings
// configurable by the helm client user for overriding
// the defaults used when running the `helm install` command.

@ -35,7 +35,6 @@ import (
extv1beta1 "k8s.io/api/extensions/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
@ -65,18 +64,14 @@ var ErrNoObjectsVisited = goerrors.New("no objects visited")
// Client represents a client capable of communicating with the Kubernetes API.
type Client struct {
cmdutil.Factory
// SchemaCacheDir is the path for loading cached schema.
SchemaCacheDir string
Log func(string, ...interface{})
}
// New creates a new Client.
func New(config clientcmd.ClientConfig) *Client {
return &Client{
Factory: cmdutil.NewFactory(config),
SchemaCacheDir: clientcmd.RecommendedSchemaFile,
Log: nopLogger,
Factory: cmdutil.NewFactory(config),
Log: nopLogger,
}
}
@ -89,18 +84,11 @@ type ResourceActorFunc func(*resource.Info) error
//
// Namespace will set the namespace.
func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shouldWait bool) error {
client, err := c.ClientSet()
c.Log("building resources from manifest")
infos, err := c.BuildUnstructured(namespace, reader)
if err != nil {
return err
}
if err := ensureNamespace(client, namespace); err != nil {
return err
}
c.Log("building resources from manifest")
infos, buildErr := c.BuildUnstructured(namespace, reader)
if buildErr != nil {
return buildErr
}
c.Log("creating %d resource(s)", len(infos))
if err := perform(infos, createResource); err != nil {
return err
@ -111,13 +99,21 @@ func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shoul
return nil
}
func (c *Client) namespace() string {
if ns, _, err := c.DefaultNamespace(); err == nil {
return ns
}
return v1.NamespaceDefault
}
func (c *Client) newBuilder(namespace string, reader io.Reader) *resource.Result {
return c.NewBuilder().
Internal().
ContinueOnError().
Schema(c.validator()).
NamespaceParam(namespace).
NamespaceParam(c.namespace()).
DefaultNamespace().
RequireNamespace().
Stream(reader, "").
Flatten().
Do()
@ -138,8 +134,9 @@ func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result,
result, err := c.NewBuilder().
Unstructured().
ContinueOnError().
NamespaceParam(namespace).
NamespaceParam(c.namespace()).
DefaultNamespace().
RequireNamespace().
Stream(reader, "").
Flatten().
Do().Infos()
@ -393,12 +390,12 @@ func deleteResource(c *Client, info *resource.Info) error {
return reaper.Stop(info.Namespace, info.Name, 0, nil)
}
func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]byte, types.PatchType, error) {
func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.PatchType, error) {
oldData, err := json.Marshal(current)
if err != nil {
return nil, types.StrategicMergePatchType, fmt.Errorf("serializing current configuration: %s", err)
}
newData, err := json.Marshal(target)
newData, err := json.Marshal(target.Object)
if err != nil {
return nil, types.StrategicMergePatchType, fmt.Errorf("serializing target configuration: %s", err)
}
@ -412,7 +409,7 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b
}
// Get a versioned object
versionedObject, err := mapping.ConvertToVersion(target, mapping.GroupVersionKind.GroupVersion())
versionedObject, err := target.Versioned()
// Unstructured objects, such as CRDs, may not have an not registered error
// returned from ConvertToVersion. Anything that's unstructured should
@ -434,7 +431,7 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b
}
func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, force bool, recreate bool) error {
patch, patchType, err := createPatch(target.Mapping, target.Object, currentObj)
patch, patchType, err := createPatch(target, currentObj)
if err != nil {
return fmt.Errorf("failed to create patch: %s", err)
}

@ -123,14 +123,10 @@ type testClient struct {
func newTestClient() *testClient {
tf := cmdtesting.NewTestFactory()
c := &Client{
Factory: tf,
Log: nopLogger,
}
return &testClient{
Client: c,
TestFactory: tf,
}
tf.Namespace = core.NamespaceDefault
c := &Client{Factory: tf, Log: nopLogger}
return &testClient{Client: c, TestFactory: tf}
}
func TestUpdate(t *testing.T) {
@ -181,6 +177,7 @@ func TestUpdate(t *testing.T) {
}
c := newTestClient()
tf.Namespace = core.NamespaceDefault
reaper := &fakeReaper{}
rf := &fakeReaperFactory{Factory: tf, reaper: reaper}
c.Client.Factory = rf
@ -309,20 +306,17 @@ func TestGet(t *testing.T) {
func TestPerform(t *testing.T) {
tests := []struct {
name string
namespace string
reader io.Reader
count int
err bool
errMessage string
}{
{
name: "Valid input",
namespace: "test",
reader: strings.NewReader(guestbookManifest),
count: 6,
name: "Valid input",
reader: strings.NewReader(guestbookManifest),
count: 6,
}, {
name: "Empty manifests",
namespace: "test",
reader: strings.NewReader(""),
err: true,
errMessage: "no objects visited",
@ -335,16 +329,12 @@ func TestPerform(t *testing.T) {
fn := func(info *resource.Info) error {
results = append(results, info)
if info.Namespace != tt.namespace {
t.Errorf("expected namespace to be '%s', got %s", tt.namespace, info.Namespace)
}
return nil
}
c := newTestClient()
defer c.Cleanup()
infos, err := c.Build(tt.namespace, tt.reader)
infos, err := c.Build("default", tt.reader)
if err != nil && err.Error() != tt.errMessage {
t.Errorf("Error while building manifests: %v", err)
}

@ -16,17 +16,21 @@ limitations under the License.
package kube // import "k8s.io/helm/pkg/kube"
import "k8s.io/client-go/tools/clientcmd"
import (
"github.com/spf13/pflag"
"k8s.io/client-go/tools/clientcmd"
)
// GetConfig returns a Kubernetes client config for a given context.
func GetConfig(context string) clientcmd.ClientConfig {
func GetConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
rules := clientcmd.NewDefaultClientConfigLoadingRules()
rules.DefaultClientConfig = &clientcmd.DefaultClientConfig
flags.StringVar(&rules.ExplicitPath, "kubeconfig", "", "path to the kubeconfig file to use for CLI requests")
overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmd.ClusterDefaults}
flags.StringVarP(&overrides.Context.Namespace, "namespace", "n", "", "if present, the namespace scope for this CLI request")
flags.StringVar(&overrides.CurrentContext, "context", "", "the name of the kubeconfig context to use")
if context != "" {
overrides.CurrentContext = context
}
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides)
}

@ -1,46 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 kube // import "k8s.io/helm/pkg/kube"
import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
)
func createNamespace(client internalclientset.Interface, namespace string) error {
ns := &core.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
}
_, err := client.Core().Namespaces().Create(ns)
return err
}
func getNamespace(client internalclientset.Interface, namespace string) (*core.Namespace, error) {
return client.Core().Namespaces().Get(namespace, metav1.GetOptions{})
}
func ensureNamespace(client internalclientset.Interface, namespace string) error {
_, err := getNamespace(client, namespace)
if err != nil && errors.IsNotFound(err) {
return createNamespace(client, namespace)
}
return err
}

@ -1,37 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 kube // import "k8s.io/helm/pkg/kube"
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
)
func TestEnsureNamespace(t *testing.T) {
client := fake.NewSimpleClientset()
if err := ensureNamespace(client, "foo"); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if err := ensureNamespace(client, "foo"); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if _, err := client.Core().Namespaces().Get("foo", metav1.GetOptions{}); err != nil {
t.Fatalf("unexpected error: %s", err)
}
}

@ -182,8 +182,6 @@ func SetupPluginEnv(settings helm_env.EnvSettings,
"HELM_PATH_CACHE": settings.Home.Cache(),
"HELM_PATH_LOCAL_REPOSITORY": settings.Home.LocalRepository(),
"HELM_PATH_STARTER": settings.Home.Starters(),
"TILLER_NAMESPACE": settings.TillerNamespace,
} {
os.Setenv(key, val)
}

@ -253,6 +253,7 @@ func newSecretsObject(key string, rls *rspb.Release, lbs labels) (*v1.Secret, er
Name: key,
Labels: lbs.toMap(),
},
Type: "helm.sh/release",
Data: map[string][]byte{"release": []byte(s)},
}, nil
}

@ -37,9 +37,6 @@ import (
"k8s.io/helm/pkg/storage/driver"
)
// DefaultTillerNamespace is the default namespace for Tiller.
const DefaultTillerNamespace = "kube-system"
// GoTplEngine is the name of the Go template engine, as registered in the EngineYard.
const GoTplEngine = "gotpl"

@ -42,10 +42,6 @@ func (s *ReleaseServer) ListReleases(req *hapi.ListReleasesRequest) ([]*release.
return nil, err
}
if req.Namespace != "" {
rels = filterByNamespace(req.Namespace, rels)
}
if len(req.Filter) != 0 {
rels, err = filterReleases(req.Filter, rels)
if err != nil {
@ -72,16 +68,6 @@ func (s *ReleaseServer) ListReleases(req *hapi.ListReleasesRequest) ([]*release.
return rels, nil
}
func filterByNamespace(namespace string, rels []*release.Release) []*release.Release {
matches := []*release.Release{}
for _, r := range rels {
if namespace == r.Namespace {
matches = append(matches, r)
}
}
return matches
}
func filterReleases(filter string, rels []*release.Release) ([]*release.Release, error) {
preg, err := regexp.Compile(filter)
if err != nil {

@ -189,45 +189,3 @@ func TestListReleasesFilter(t *testing.T) {
t.Errorf("Unexpected sort order: %v.", rels)
}
}
func TestReleasesNamespace(t *testing.T) {
rs := rsFixture()
names := []string{
"axon",
"dendrite",
"neuron",
"ribosome",
}
namespaces := []string{
"default",
"test123",
"test123",
"cerebellum",
}
num := 4
for i := 0; i < num; i++ {
rel := releaseStub()
rel.Name = names[i]
rel.Namespace = namespaces[i]
if err := rs.env.Releases.Create(rel); err != nil {
t.Fatalf("Could not store mock release: %s", err)
}
}
req := &hapi.ListReleasesRequest{
Offset: "",
Limit: 64,
Namespace: "test123",
}
rels, err := rs.ListReleases(req)
if err != nil {
t.Fatalf("Failed listing: %s", err)
}
if len(rels) != 2 {
t.Errorf("Expected 2 releases, got %d", len(rels))
}
}

Loading…
Cancel
Save