From b35e446447bd17afe994eadf9c0afa3065d2c3d1 Mon Sep 17 00:00:00 2001 From: jliao Date: Thu, 1 Nov 2018 18:07:26 +0800 Subject: [PATCH] fix: the namespac for release was not exist when wen install a chart, we can set the namespace what used to store the release, when the release is not exist, the other k8s resource will be created. but the release will be created failed. and a check before we install the chart. Signed-off-by: jliao --- pkg/tiller/release_install.go | 7 +++++++ pkg/tiller/release_install_test.go | 18 ++++++++++++++++++ pkg/tiller/release_server.go | 10 ++++++++++ pkg/tiller/release_server_test.go | 23 ++++++++++++++++++++--- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/pkg/tiller/release_install.go b/pkg/tiller/release_install.go index 973da3581..97cd1b86c 100644 --- a/pkg/tiller/release_install.go +++ b/pkg/tiller/release_install.go @@ -17,6 +17,7 @@ limitations under the License. package tiller import ( + "errors" "fmt" "strings" @@ -60,6 +61,12 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re return nil, errMissingChart } + err := s.isValidNamespace(req.Namespace) + if err != nil { + errString := fmt.Sprintf("invalid release namespace, err=%s", err.Error()) + return nil, errors.New(errString) + } + name, err := s.uniqName(req.Name, req.ReuseName) if err != nil { return nil, err diff --git a/pkg/tiller/release_install_test.go b/pkg/tiller/release_install_test.go index f5e84d870..ef7b36cf7 100644 --- a/pkg/tiller/release_install_test.go +++ b/pkg/tiller/release_install_test.go @@ -515,3 +515,21 @@ func TestInstallRelease_Description(t *testing.T) { t.Errorf("Expected description %q. Got %q", customDescription, desc) } } +func TestInstallRelease_ReleaseNamespaceNotExist(t *testing.T) { + c := helm.NewContext() + rs := rsFixtureConfigMapStorage() + + req := installRequest( + withNamespace("noSpaced"), + ) + + _, err := rs.InstallRelease(c, req) + if err == nil { + t.Fatalf("Expected to fail because of the namespace is not exist") + } + + expect := "invalid release namespace" + if !strings.Contains(err.Error(), expect) { + t.Errorf("Expected %q equal to %q", err.Error(), expect) + } +} diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index f5e96ed00..f2e4b555c 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -36,6 +36,7 @@ import ( "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" relutil "k8s.io/helm/pkg/releaseutil" + "k8s.io/helm/pkg/storage/driver" "k8s.io/helm/pkg/tiller/environment" "k8s.io/helm/pkg/timeconv" "k8s.io/helm/pkg/version" @@ -452,6 +453,15 @@ func (s *ReleaseServer) deleteHookByPolicy(h *release.Hook, policy string, name, return nil } +func (s *ReleaseServer) isValidNamespace(name string) error { + // if the storage is not configmap, do not check the namespace + if s.env.Releases.Name() != driver.ConfigMapsDriverName { + return nil + } + _, err := s.clientset.Core().Namespaces().Get(name, metav1.GetOptions{}) + return err +} + // hookShouldBeDeleted determines whether the defined hook deletion policy matches the hook deletion polices // supported by helm. If so, mark the hook as one should be deleted. func hookHasDeletePolicy(h *release.Hook, policy string) bool { diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 311f55b30..b58d4ea99 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -33,6 +33,7 @@ import ( "google.golang.org/grpc/metadata" "k8s.io/api/core/v1" "k8s.io/cli-runtime/pkg/genericclioptions/resource" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" "k8s.io/helm/pkg/helm" @@ -120,7 +121,13 @@ type chartOptions struct { type chartOption func(*chartOptions) func rsFixture() *ReleaseServer { - return NewReleaseServer(MockEnvironment(), fake.NewSimpleClientset(), false) + clientset := fake.NewSimpleClientset() + return NewReleaseServer(MockEnvironment(driver.MemoryDriverName, clientset), clientset, false) +} + +func rsFixtureConfigMapStorage() *ReleaseServer { + clientset := fake.NewSimpleClientset() + return NewReleaseServer(MockEnvironment(driver.ConfigMapsDriverName, clientset), clientset, false) } func buildChart(opts ...chartOption) *chart.Chart { @@ -221,6 +228,12 @@ func withChart(chartOpts ...chartOption) installOption { } } +func withNamespace(namepace string) installOption { + return func(opts *installOptions) { + opts.Namespace = namepace + } +} + func installRequest(opts ...installOption) *services.InstallReleaseRequest { reqOpts := &installOptions{ &services.InstallReleaseRequest{ @@ -462,9 +475,13 @@ func releaseWithKeepStub(rlsName string) *release.Release { } } -func MockEnvironment() *environment.Environment { +func MockEnvironment(storageType string, clientset kubernetes.Interface) *environment.Environment { e := environment.New() - e.Releases = storage.Init(driver.NewMemory()) + if storageType == driver.ConfigMapsDriverName { + e.Releases = storage.Init(driver.NewConfigMaps(clientset.CoreV1().ConfigMaps("default"))) + } else { + e.Releases = storage.Init(driver.NewMemory()) + } e.KubeClient = &environment.PrintingKubeClient{Out: ioutil.Discard} return e }