Merge pull request #852 from adamreese/fix/namespace-tunnel

fix(tunnel): allow tunneling to non-default namespace
pull/855/head
Adam Reese 8 years ago committed by GitHub
commit c41ccddfa1

@ -17,8 +17,11 @@ const (
hostEnvVar = "HELM_HOST" hostEnvVar = "HELM_HOST"
) )
var helmHome string var (
var tillerHost string helmHome string
tillerHost string
tillerNamespace string
)
// flagDebug is a signal that the user wants additional output. // flagDebug is a signal that the user wants additional output.
var flagDebug bool var flagDebug bool
@ -61,6 +64,7 @@ func init() {
p := RootCommand.PersistentFlags() p := RootCommand.PersistentFlags()
p.StringVar(&helmHome, "home", home, "location of your Helm config. Overrides $HELM_HOME.") p.StringVar(&helmHome, "home", home, "location of your Helm config. Overrides $HELM_HOME.")
p.StringVar(&tillerHost, "host", thost, "address of tiller. Overrides $HELM_HOST.") p.StringVar(&tillerHost, "host", thost, "address of tiller. Overrides $HELM_HOST.")
p.StringVarP(&tillerNamespace, "namespace", "", "", "kubernetes namespace")
p.BoolVarP(&flagDebug, "debug", "", false, "enable verbose output") p.BoolVarP(&flagDebug, "debug", "", false, "enable verbose output")
} }
@ -72,8 +76,7 @@ func main() {
func setupConnection(c *cobra.Command, args []string) error { func setupConnection(c *cobra.Command, args []string) error {
if tillerHost == "" { if tillerHost == "" {
// Should failure fall back to default host? tunnel, err := newTillerPortForwarder(tillerNamespace)
tunnel, err := newTillerPortForwarder()
if err != nil { if err != nil {
return err return err
} }

@ -17,9 +17,7 @@ Kubernetes Cluster and sets up local configuration in $HELM_HOME (default: ~/.he
var ( var (
tillerImg string tillerImg string
tillerNamespace string
clientOnly bool clientOnly bool
initSkipNamespace bool
defaultRepository = "kubernetes-charts" defaultRepository = "kubernetes-charts"
defaultRepositoryURL = "http://storage.googleapis.com/kubernetes-charts" defaultRepositoryURL = "http://storage.googleapis.com/kubernetes-charts"
) )
@ -28,8 +26,6 @@ func init() {
f := initCmd.Flags() f := initCmd.Flags()
f.StringVarP(&tillerImg, "tiller-image", "i", "", "override tiller image") f.StringVarP(&tillerImg, "tiller-image", "i", "", "override tiller image")
f.BoolVarP(&clientOnly, "client-only", "c", false, "If set does not install tiller") f.BoolVarP(&clientOnly, "client-only", "c", false, "If set does not install tiller")
f.BoolVarP(&initSkipNamespace, "skip-namespace", "s", false, "Do not attempt to create a namespace. Assume the namespace is already there.")
f.StringVarP(&tillerNamespace, "namespace", "n", "helm", "set the tiller namespace")
RootCommand.AddCommand(initCmd) RootCommand.AddCommand(initCmd)
} }
@ -63,12 +59,7 @@ func runInit(cmd *cobra.Command, args []string) error {
} }
func installTiller() error { func installTiller() error {
i := client.NewInstaller() if err := client.Install(tillerNamespace, tillerImg, flagDebug); err != nil {
i.Tiller["Image"] = tillerImg
i.Tiller["Namespace"] = tillerNamespace
err := i.Install(flagDebug, !initSkipNamespace)
if err != nil {
return fmt.Errorf("error installing: %s", err) return fmt.Errorf("error installing: %s", err)
} }
fmt.Println("\nTiller (the helm server side component) has been installed into your Kubernetes Cluster.") fmt.Println("\nTiller (the helm server side component) has been installed into your Kubernetes Cluster.")

@ -12,14 +12,14 @@ import (
// TODO refactor out this global var // TODO refactor out this global var
var tunnel *kube.Tunnel var tunnel *kube.Tunnel
func newTillerPortForwarder() (*kube.Tunnel, error) { func newTillerPortForwarder(namespace string) (*kube.Tunnel, error) {
podName, err := getTillerPodName("helm") podName, err := getTillerPodName(namespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// FIXME use a constain that is accessible on init // FIXME use a constain that is accessible on init
const tillerPort = 44134 const tillerPort = 44134
return kube.New(nil).ForwardPort("helm", podName, tillerPort) return kube.New(nil).ForwardPort(namespace, podName, tillerPort)
} }
func getTillerPodName(namespace string) (string, error) { func getTillerPodName(namespace string) (string, error) {

@ -10,49 +10,33 @@ import (
"k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/kube"
) )
// Installer installs tiller into Kubernetes
//
// See InstallYAML.
type Installer struct {
// Metadata holds any global metadata attributes for the resources
Metadata map[string]interface{}
// Tiller specific metadata
Tiller map[string]interface{}
}
// NewInstaller creates a new Installer
func NewInstaller() *Installer {
return &Installer{
Metadata: map[string]interface{}{},
Tiller: map[string]interface{}{},
}
}
// Install uses kubernetes client to install tiller // Install uses kubernetes client to install tiller
// //
// Returns the string output received from the operation, and an error if the // Returns the string output received from the operation, and an error if the
// command failed. // command failed.
// //
// If verbose is true, this will print the manifest to stdout. // If verbose is true, this will print the manifest to stdout.
// func Install(namespace, image string, verbose bool) error {
// If createNS is true, this will also create the namespace. kc := kube.New(nil)
func (i *Installer) Install(verbose, createNS bool) error {
var b bytes.Buffer
// Add namespace if namespace == "" {
if createNS { ns, _, err := kc.DefaultNamespace()
nstpl := template.New("namespace").Funcs(sprig.TxtFuncMap()) if err != nil {
if err := template.Must(nstpl.Parse(NamespaceYAML)).Execute(&b, i); err != nil {
return err return err
} }
namespace = ns
} }
var b bytes.Buffer
// Add main install YAML // Add main install YAML
istpl := template.New("install").Funcs(sprig.TxtFuncMap()) istpl := template.New("install").Funcs(sprig.TxtFuncMap())
if err := template.Must(istpl.Parse(InstallYAML)).Execute(&b, i); err != nil {
cfg := struct {
Namespace, Image string
}{namespace, image}
if err := template.Must(istpl.Parse(InstallYAML)).Execute(&b, cfg); err != nil {
return err return err
} }
@ -60,24 +44,12 @@ func (i *Installer) Install(verbose, createNS bool) error {
fmt.Println(b.String()) fmt.Println(b.String())
} }
return kube.New(nil).Create(i.Tiller["Namespace"].(string), &b) return kc.Create(namespace, &b)
} }
// NamespaceYAML is the installation for a namespace.
const NamespaceYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}}
apiVersion: v1
kind: Namespace
metadata:
labels:
app: helm
name: helm-namespace
name: {{$namespace}}
`
// InstallYAML is the installation YAML for DM. // InstallYAML is the installation YAML for DM.
const InstallYAML = ` const InstallYAML = `
---{{$namespace := default "helm" .Tiller.Namespace}} ---
apiVersion: v1 apiVersion: v1
kind: ReplicationController kind: ReplicationController
metadata: metadata:
@ -85,7 +57,7 @@ metadata:
app: helm app: helm
name: tiller name: tiller
name: tiller-rc name: tiller-rc
namespace: {{$namespace}} namespace: {{ .Namespace }}
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@ -103,7 +75,7 @@ spec:
valueFrom: valueFrom:
fieldRef: fieldRef:
fieldPath: metadata.namespace fieldPath: metadata.namespace
image: {{default "gcr.io/kubernetes-helm/tiller:canary" .Tiller.Image}} image: {{default "gcr.io/kubernetes-helm/tiller:canary" .Image}}
name: tiller name: tiller
ports: ports:
- containerPort: 44134 - containerPort: 44134

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"io" "io"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
@ -28,6 +30,9 @@ type ResourceActorFunc func(*resource.Info) error
// //
// Namespace will set the namespace // Namespace will set the namespace
func (c *Client) Create(namespace string, reader io.Reader) error { func (c *Client) Create(namespace string, reader io.Reader) error {
if err := c.ensureNamespace(namespace); err != nil {
return err
}
return perform(c, namespace, reader, createResource) return perform(c, namespace, reader, createResource)
} }
@ -44,7 +49,7 @@ func perform(c *Client, namespace string, reader io.Reader, fn ResourceActorFunc
r := c.NewBuilder(includeThirdPartyAPIs). r := c.NewBuilder(includeThirdPartyAPIs).
ContinueOnError(). ContinueOnError().
NamespaceParam(namespace). NamespaceParam(namespace).
RequireNamespace(). DefaultNamespace().
Stream(reader, ""). Stream(reader, "").
Flatten(). Flatten().
Do() Do()
@ -83,3 +88,18 @@ func createResource(info *resource.Info) error {
func deleteResource(info *resource.Info) error { func deleteResource(info *resource.Info) error {
return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name) return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name)
} }
func (c *Client) ensureNamespace(namespace string) error {
client, err := c.Client()
if err != nil {
return err
}
ns := &api.Namespace{}
ns.Name = namespace
_, err = client.Namespaces().Create(ns)
if err != nil && !errors.IsAlreadyExists(err) {
return err
}
return nil
}

Loading…
Cancel
Save