diff --git a/pkg/kubectl/clusterrolebinding.go b/pkg/kubectl/clusterrolebinding.go index cf2708f3214..04d58ab070e 100644 --- a/pkg/kubectl/clusterrolebinding.go +++ b/pkg/kubectl/clusterrolebinding.go @@ -19,6 +19,8 @@ package kubectl import ( "fmt" + "strings" + "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/runtime" ) @@ -33,6 +35,8 @@ type ClusterRoleBindingGeneratorV1 struct { Users []string // Groups to derive the clusterRoleBinding from (optional) Groups []string + // ServiceAccounts to derive the clusterRoleBinding from in namespace:name format(optional) + ServiceAccounts []string } // Ensure it supports the generator pattern that uses parameter injection. @@ -66,6 +70,15 @@ func (s ClusterRoleBindingGeneratorV1) Generate(genericParams map[string]interfa delegate.Groups = fromLiteralArray delete(genericParams, "group") } + fromSAStrings, found := genericParams["serviceaccount"] + if found { + fromLiteralArray, isArray := fromSAStrings.([]string) + if !isArray { + return nil, fmt.Errorf("expected []string, found :%v", fromFileStrings) + } + delegate.ServiceAccounts = fromLiteralArray + delete(genericParams, "serviceaccounts") + } params := map[string]string{} for key, value := range genericParams { strVal, isString := value.(string) @@ -86,6 +99,7 @@ func (s ClusterRoleBindingGeneratorV1) ParamNames() []GeneratorParam { {"clusterrole", false}, {"user", false}, {"group", false}, + {"serviceaccount", false}, {"force", false}, } } @@ -109,11 +123,15 @@ func (s ClusterRoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, err Name: user, }) } - for _, group := range s.Groups { + for _, sa := range s.ServiceAccounts { + tokens := strings.Split(sa, ":") + if len(tokens) != 2 { + return nil, fmt.Errorf("serviceaccount must be :") + } clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{ - Kind: rbac.GroupKind, - APIVersion: "rbac/v1alpha1", - Name: group, + Kind: rbac.ServiceAccountKind, + Namespace: tokens[0], + Name: tokens[1], }) } diff --git a/pkg/kubectl/cmd/create_clusterrolebinding.go b/pkg/kubectl/cmd/create_clusterrolebinding.go index 21e1dc70515..e6832ec8fff 100644 --- a/pkg/kubectl/cmd/create_clusterrolebinding.go +++ b/pkg/kubectl/cmd/create_clusterrolebinding.go @@ -55,6 +55,7 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, cmdOut io.Writer) *cobra. cmd.Flags().String("clusterrole", "", "ClusterRole this ClusterRoleBinding should reference") cmd.Flags().StringSlice("user", []string{}, "usernames to bind to the role") cmd.Flags().StringSlice("group", []string{}, "groups to bind to the role") + cmd.Flags().StringSlice("serviceaccount", []string{}, "service accounts to bind to the role") return cmd } @@ -68,10 +69,11 @@ func CreateClusterRoleBinding(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Co switch generatorName := cmdutil.GetFlagString(cmd, "generator"); generatorName { case cmdutil.ClusterRoleBindingV1GeneratorName: generator = &kubectl.ClusterRoleBindingGeneratorV1{ - Name: name, - ClusterRole: cmdutil.GetFlagString(cmd, "clusterrole"), - Users: cmdutil.GetFlagStringSlice(cmd, "user"), - Groups: cmdutil.GetFlagStringSlice(cmd, "group"), + Name: name, + ClusterRole: cmdutil.GetFlagString(cmd, "clusterrole"), + Users: cmdutil.GetFlagStringSlice(cmd, "user"), + Groups: cmdutil.GetFlagStringSlice(cmd, "group"), + ServiceAccounts: cmdutil.GetFlagStringSlice(cmd, "serviceaccount"), } default: return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName))