Fix helm install --create-namespace flag RBAC issue

Allow case when namespace already exists in the cluster and user does not have a permission to create namespaces. `helm install --create-namespace` would not try to create namespace in such case.

This change makes `--create-namespace` flag behaviour more idempotent.
pull/9775/head
Timofey Kirillov 4 years ago
parent bf486a25cd
commit 37747bb92b

@ -309,7 +309,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
if err != nil {
return nil, err
}
if _, err := i.cfg.KubeClient.Create(resourceList); err != nil && !apierrors.IsAlreadyExists(err) {
if _, err := i.cfg.KubeClient.CreateIfNotExists(resourceList); err != nil {
return nil, err
}
}

@ -117,6 +117,14 @@ func (c *Client) IsReachable() error {
return nil
}
func (c *Client) CreateIfNotExists(resources ResourceList) (*Result, error) {
c.Log("creating %d resource(s)", len(resources))
if err := perform(resources, createResourceIfNotExists); err != nil {
return nil, err
}
return &Result{Created: resources}, nil
}
// Create creates Kubernetes resources specified in the resource list.
func (c *Client) Create(resources ResourceList) (*Result, error) {
c.Log("creating %d resource(s)", len(resources))
@ -384,6 +392,17 @@ func createResource(info *resource.Info) error {
return info.Refresh(obj, true)
}
func createResourceIfNotExists(info *resource.Info) error {
_, err := resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name)
if apierrors.IsNotFound(err) {
return createResource(info)
} else if err != nil {
return err
}
return nil
}
func deleteResource(info *resource.Info) error {
policy := metav1.DeletePropagationBackground
opts := &metav1.DeleteOptions{PropagationPolicy: &policy}

@ -47,6 +47,11 @@ func (p *PrintingKubeClient) Create(resources kube.ResourceList) (*kube.Result,
return &kube.Result{Created: resources}, nil
}
// Create prints the values of what would be created with a real KubeClient.
func (p *PrintingKubeClient) CreateIfNotExists(resources kube.ResourceList) (*kube.Result, error) {
return p.Create(resources)
}
func (p *PrintingKubeClient) Wait(resources kube.ResourceList, _ time.Duration) error {
_, err := io.Copy(p.Out, bufferize(resources))
return err

@ -29,6 +29,8 @@ import (
type Interface interface {
// Create creates one or more resources.
Create(resources ResourceList) (*Result, error)
// Create creates one or more resources with resource existance check.
CreateIfNotExists(resources ResourceList) (*Result, error)
Wait(resources ResourceList, timeout time.Duration) error

Loading…
Cancel
Save