diff --git a/protokube/cmd/protokube/main.go b/protokube/cmd/protokube/main.go index 2ef1ca8f69..1dfb859189 100644 --- a/protokube/cmd/protokube/main.go +++ b/protokube/cmd/protokube/main.go @@ -64,6 +64,9 @@ func run() error { applyTaints := false flag.BoolVar(&applyTaints, "apply-taints", applyTaints, "Apply taints to nodes based on the role") + initializeRBAC := false + flag.BoolVar(&initializeRBAC, "initialize-rbac", initializeRBAC, "Set if we should initialize RBAC") + containerized := false flag.BoolVar(&containerized, "containerized", containerized, "Set if we are running containerized.") @@ -212,6 +215,8 @@ func run() error { //MasterID : fromVolume //EtcdClusters : fromVolume + InitializeRBAC: initializeRBAC, + ModelDir: modelDir, DNSScope: dnsScope, diff --git a/protokube/pkg/protokube/kube_boot.go b/protokube/pkg/protokube/kube_boot.go index 6e5a8d991b..68d1ffb941 100644 --- a/protokube/pkg/protokube/kube_boot.go +++ b/protokube/pkg/protokube/kube_boot.go @@ -26,7 +26,11 @@ import ( ) type KubeBoot struct { - Master bool + Master bool + + // InitializeRBAC should be set to true if we should create the core RBAC roles + InitializeRBAC bool + InternalDNSSuffix string InternalIP net.IP //MasterID int @@ -122,6 +126,13 @@ func (k *KubeBoot) syncOnce() error { } } + if k.InitializeRBAC { + // TODO: Idempotency + if err := InitializeRBAC(k.Kubernetes); err != nil { + glog.Warningf("error initializing RBAC: %v", err) + } + } + // Ensure kubelet is running. We avoid doing this automatically so // that when kubelet comes up the first time, all volume mounts // and DNS are available, avoiding the scenario where diff --git a/protokube/pkg/protokube/kube_context.go b/protokube/pkg/protokube/kube_context.go index a5a67a4f40..19813a49ef 100644 --- a/protokube/pkg/protokube/kube_context.go +++ b/protokube/pkg/protokube/kube_context.go @@ -24,8 +24,8 @@ import ( ) type KubernetesContext struct { - mutex sync.Mutex - client kubernetes.Interface + mutex sync.Mutex + k8sClient kubernetes.Interface } func NewKubernetesContext() *KubernetesContext { @@ -36,7 +36,7 @@ func (c *KubernetesContext) KubernetesClient() (kubernetes.Interface, error) { c.mutex.Lock() defer c.mutex.Unlock() - if c.client == nil { + if c.k8sClient == nil { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig @@ -54,7 +54,7 @@ func (c *KubernetesContext) KubernetesClient() (kubernetes.Interface, error) { if err != nil { return nil, fmt.Errorf("cannot build kube client: %v", err) } - c.client = k8sClient + c.k8sClient = k8sClient } - return c.client, nil + return c.k8sClient, nil } diff --git a/protokube/pkg/protokube/rbac.go b/protokube/pkg/protokube/rbac.go new file mode 100644 index 0000000000..37f02f4d52 --- /dev/null +++ b/protokube/pkg/protokube/rbac.go @@ -0,0 +1,51 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 protokube + +import ( + "fmt" + "github.com/golang/glog" + "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig" +) + +func InitializeRBAC(kubeContext *KubernetesContext) error { + k8sClient, err := kubeContext.KubernetesClient() + if err != nil { + return fmt.Errorf("error connecting to kubernetes: %v", err) + } + clientset := k8sClient.(*kubernetes.Clientset) + + var errors []error + if err := apiconfig.CreateServiceAccounts(clientset); err != nil { + errors = append(errors, fmt.Errorf("error creating service accounts: %v", err)) + } + if err := apiconfig.CreateClusterRoleBindings(clientset); err != nil { + errors = append(errors, fmt.Errorf("error creating cluster role bindings: %v", err)) + } + + if len(errors) != 0 { + if len(errors) != 1 { + for _, err := range errors { + glog.Warningf("Error configuring RBAC: %v", err) + } + } + return errors[0] + } + + return nil +}