Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experimental policy cli #853

Merged
merged 1 commit into from
Feb 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export OPENSHIFT_PROFILE="${CLI_PROFILE-}"
[ "$(openshift ex)" ]
[ "$(openshift ex config 2>&1)" ]
[ "$(openshift ex tokens)" ]
[ "$(openshift ex policy 2>&1)" ]
[ "$(openshift kubectl)" ]
[ "$(openshift kube 2>&1)" ]

Expand Down Expand Up @@ -168,3 +169,11 @@ osc cancel-build "${started}" --dump-logs --restart
echo "cancel-build: ok"

osc get minions,pods

openshift ex policy add-group cluster-admin system:unauthenticated
openshift ex policy remove-group cluster-admin system:unauthenticated
openshift ex policy remove-group-from-project system:unauthenticated
openshift ex policy add-user cluster-admin system:no-user
openshift ex policy remove-user cluster-admin system:no-user
openshift ex policy remove-user-from-project system:no-user
echo "ex policy: ok"
102 changes: 102 additions & 0 deletions pkg/cmd/experimental/policy/add_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package policy

import (
"fmt"

"github.com/spf13/cobra"

"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"

authorizationapi "github.com/openshift/origin/pkg/authorization/api"
"github.com/openshift/origin/pkg/client"
)

type addGroupOptions struct {
roleNamespace string
roleName string
clientConfig clientcmd.ClientConfig

groupNames []string
}

func NewCmdAddGroup(clientConfig clientcmd.ClientConfig) *cobra.Command {
options := &addGroupOptions{clientConfig: clientConfig}

cmd := &cobra.Command{
Use: "add-group <role> <group> [group]...",
Short: "add group to role",
Long: `add group to role`,
Run: func(cmd *cobra.Command, args []string) {
if !options.complete(cmd) {
return
}

err := options.run()
if err != nil {
fmt.Printf("%v\n", err)
}
},
}

cmd.Flags().StringVar(&options.roleNamespace, "role-namespace", "master", "namespace where the role is located.")

return cmd
}

func (o *addGroupOptions) complete(cmd *cobra.Command) bool {
args := cmd.Flags().Args()
if len(args) < 2 {
cmd.Help()
return false
}

o.roleName = args[0]
o.groupNames = args[1:]
return true
}

func (o *addGroupOptions) run() error {
clientConfig, err := o.clientConfig.ClientConfig()
if err != nil {
return err
}
client, err := client.New(clientConfig)
if err != nil {
return err
}
namespace, err := o.clientConfig.Namespace()
if err != nil {
return err
}

roleBinding, roleBindingNames, err := getExistingRoleBindingForRole(o.roleNamespace, o.roleName, namespace, client)
if err != nil {
return err
}
isUpdate := true
if roleBinding == nil {
roleBinding = &authorizationapi.RoleBinding{}
isUpdate = false
}

roleBinding.RoleRef.Namespace = o.roleNamespace
roleBinding.RoleRef.Name = o.roleName

groups := util.StringSet{}
groups.Insert(roleBinding.GroupNames...)
groups.Insert(o.groupNames...)
roleBinding.GroupNames = groups.List()

if isUpdate {
_, err = client.RoleBindings(namespace).Update(roleBinding)
} else {
roleBinding.Name = getUniqueName(o.roleName, roleBindingNames)
_, err = client.RoleBindings(namespace).Create(roleBinding)
}
if err != nil {
return err
}

return nil
}
102 changes: 102 additions & 0 deletions pkg/cmd/experimental/policy/add_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package policy

import (
"fmt"

"github.com/spf13/cobra"

"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"

authorizationapi "github.com/openshift/origin/pkg/authorization/api"
"github.com/openshift/origin/pkg/client"
)

type addUserOptions struct {
roleNamespace string
roleName string
clientConfig clientcmd.ClientConfig

userNames []string
}

func NewCmdAddUser(clientConfig clientcmd.ClientConfig) *cobra.Command {
options := &addUserOptions{clientConfig: clientConfig}

cmd := &cobra.Command{
Use: "add-user <role> <user> [user]...",
Short: "add user to role",
Long: `add user to role`,
Run: func(cmd *cobra.Command, args []string) {
if !options.complete(cmd) {
return
}

err := options.run()
if err != nil {
fmt.Printf("%v\n", err)
}
},
}

cmd.Flags().StringVar(&options.roleNamespace, "role-namespace", "master", "namespace where the role is located.")

return cmd
}

func (o *addUserOptions) complete(cmd *cobra.Command) bool {
args := cmd.Flags().Args()
if len(args) < 2 {
cmd.Help()
return false
}

o.roleName = args[0]
o.userNames = args[1:]
return true
}

func (o *addUserOptions) run() error {
clientConfig, err := o.clientConfig.ClientConfig()
if err != nil {
return err
}
client, err := client.New(clientConfig)
if err != nil {
return err
}
namespace, err := o.clientConfig.Namespace()
if err != nil {
return err
}

roleBinding, roleBindingNames, err := getExistingRoleBindingForRole(o.roleNamespace, o.roleName, namespace, client)
if err != nil {
return err
}
isUpdate := true
if roleBinding == nil {
roleBinding = &authorizationapi.RoleBinding{}
isUpdate = false
}

roleBinding.RoleRef.Namespace = o.roleNamespace
roleBinding.RoleRef.Name = o.roleName

users := util.StringSet{}
users.Insert(roleBinding.UserNames...)
users.Insert(o.userNames...)
roleBinding.UserNames = users.List()

if isUpdate {
_, err = client.RoleBindings(namespace).Update(roleBinding)
} else {
roleBinding.Name = getUniqueName(o.roleName, roleBindingNames)
_, err = client.RoleBindings(namespace).Create(roleBinding)
}
if err != nil {
return err
}

return nil
}
101 changes: 101 additions & 0 deletions pkg/cmd/experimental/policy/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package policy

import (
"fmt"
"os"
"strings"

"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"

authorizationapi "github.com/openshift/origin/pkg/authorization/api"
"github.com/openshift/origin/pkg/client"
)

func NewCommandPolicy(name string) *cobra.Command {
// Parent command to which all subcommands are added.
cmds := &cobra.Command{
Use: name,
Short: "manage authorization policy",
Long: `manage authorization policy`,
Run: runHelp,
}

// Override global default to https and port 8443
clientcmd.DefaultCluster.Server = "https://localhost:8443"
clientConfig := defaultClientConfig(cmds.PersistentFlags())

cmds.AddCommand(NewCmdAddUser(clientConfig))
cmds.AddCommand(NewCmdRemoveUser(clientConfig))
cmds.AddCommand(NewCmdRemoveUserFromProject(clientConfig))
cmds.AddCommand(NewCmdAddGroup(clientConfig))
cmds.AddCommand(NewCmdRemoveGroup(clientConfig))
cmds.AddCommand(NewCmdRemoveGroupFromProject(clientConfig))

return cmds
}

func runHelp(cmd *cobra.Command, args []string) {
cmd.Help()
}

func getFlagString(cmd *cobra.Command, flag string) string {
f := cmd.Flags().Lookup(flag)
if f == nil {
glog.Fatalf("Flag accessed but not defined for command %s: %s", cmd.Name(), flag)
}
return f.Value.String()
}

// Copy of kubectl/cmd/DefaultClientConfig, using NewNonInteractiveDeferredLoadingClientConfig
func defaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
loadingRules := clientcmd.NewClientConfigLoadingRules()
loadingRules.EnvVarPath = os.Getenv(clientcmd.RecommendedConfigPathEnvVar)
flags.StringVar(&loadingRules.CommandLinePath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests.")

overrides := &clientcmd.ConfigOverrides{}
clientcmd.BindOverrideFlags(overrides, flags, clientcmd.RecommendedConfigOverrideFlags(""))
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)

return clientConfig
}

func getUniqueName(basename string, existingNames *util.StringSet) string {
if !existingNames.Has(basename) {
return basename
}

for i := 0; i < 100; i++ {
trialName := fmt.Sprintf("%v-%d", basename, i)
if !existingNames.Has(trialName) {
return trialName
}
}

return string(util.NewUUID())
}

func getExistingRoleBindingForRole(roleNamespace, role, bindingNamespace string, client *client.Client) (*authorizationapi.RoleBinding, *util.StringSet, error) {
existingBindings, err := client.PolicyBindings(bindingNamespace).Get(roleNamespace)
if err != nil && !strings.Contains(err.Error(), " not found") {
return nil, &util.StringSet{}, err
}

roleBindingNames := &util.StringSet{}
roleBinding := (*authorizationapi.RoleBinding)(nil)
// see if we can find an existing binding that points to the role in question.
for _, currBinding := range existingBindings.RoleBindings {
roleBindingNames.Insert(currBinding.Name)

if currBinding.RoleRef.Name == role {
t := currBinding
roleBinding = &t
}
}

return roleBinding, roleBindingNames, nil
}
Loading