Skip to content

Commit 222bff8

Browse files
committed
add oc create policybinding
1 parent 51e0b43 commit 222bff8

File tree

7 files changed

+251
-0
lines changed

7 files changed

+251
-0
lines changed

contrib/completions/bash/oc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6686,6 +6686,47 @@ _oc_create_route()
66866686
must_have_one_noun=()
66876687
}
66886688

6689+
_oc_create_policybinding()
6690+
{
6691+
last_command="oc_create_policybinding"
6692+
commands=()
6693+
6694+
flags=()
6695+
two_word_flags=()
6696+
flags_with_completion=()
6697+
flags_completion=()
6698+
6699+
flags+=("--output=")
6700+
two_word_flags+=("-o")
6701+
flags+=("--api-version=")
6702+
flags+=("--certificate-authority=")
6703+
flags_with_completion+=("--certificate-authority")
6704+
flags_completion+=("_filedir")
6705+
flags+=("--client-certificate=")
6706+
flags_with_completion+=("--client-certificate")
6707+
flags_completion+=("_filedir")
6708+
flags+=("--client-key=")
6709+
flags_with_completion+=("--client-key")
6710+
flags_completion+=("_filedir")
6711+
flags+=("--cluster=")
6712+
flags+=("--config=")
6713+
flags_with_completion+=("--config")
6714+
flags_completion+=("_filedir")
6715+
flags+=("--context=")
6716+
flags+=("--google-json-key=")
6717+
flags+=("--insecure-skip-tls-verify")
6718+
flags+=("--log-flush-frequency=")
6719+
flags+=("--match-server-version")
6720+
flags+=("--namespace=")
6721+
two_word_flags+=("-n")
6722+
flags+=("--server=")
6723+
flags+=("--token=")
6724+
flags+=("--user=")
6725+
6726+
must_have_one_flag=()
6727+
must_have_one_noun=()
6728+
}
6729+
66896730
_oc_create()
66906731
{
66916732
last_command="oc_create"
@@ -6695,6 +6736,7 @@ _oc_create()
66956736
commands+=("configmap")
66966737
commands+=("serviceaccount")
66976738
commands+=("route")
6739+
commands+=("policybinding")
66986740

66996741
flags=()
67006742
two_word_flags=()

contrib/completions/bash/openshift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10235,6 +10235,47 @@ _openshift_cli_create_route()
1023510235
must_have_one_noun=()
1023610236
}
1023710237

10238+
_openshift_cli_create_policybinding()
10239+
{
10240+
last_command="openshift_cli_create_policybinding"
10241+
commands=()
10242+
10243+
flags=()
10244+
two_word_flags=()
10245+
flags_with_completion=()
10246+
flags_completion=()
10247+
10248+
flags+=("--output=")
10249+
two_word_flags+=("-o")
10250+
flags+=("--api-version=")
10251+
flags+=("--certificate-authority=")
10252+
flags_with_completion+=("--certificate-authority")
10253+
flags_completion+=("_filedir")
10254+
flags+=("--client-certificate=")
10255+
flags_with_completion+=("--client-certificate")
10256+
flags_completion+=("_filedir")
10257+
flags+=("--client-key=")
10258+
flags_with_completion+=("--client-key")
10259+
flags_completion+=("_filedir")
10260+
flags+=("--cluster=")
10261+
flags+=("--config=")
10262+
flags_with_completion+=("--config")
10263+
flags_completion+=("_filedir")
10264+
flags+=("--context=")
10265+
flags+=("--google-json-key=")
10266+
flags+=("--insecure-skip-tls-verify")
10267+
flags+=("--log-flush-frequency=")
10268+
flags+=("--match-server-version")
10269+
flags+=("--namespace=")
10270+
two_word_flags+=("-n")
10271+
flags+=("--server=")
10272+
flags+=("--token=")
10273+
flags+=("--user=")
10274+
10275+
must_have_one_flag=()
10276+
must_have_one_noun=()
10277+
}
10278+
1023810279
_openshift_cli_create()
1023910280
{
1024010281
last_command="openshift_cli_create"
@@ -10244,6 +10285,7 @@ _openshift_cli_create()
1024410285
commands+=("configmap")
1024510286
commands+=("serviceaccount")
1024610287
commands+=("route")
10288+
commands+=("policybinding")
1024710289

1024810290
flags=()
1024910291
two_word_flags=()

docs/generated/oc_by_example_content.adoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,19 @@ Create a namespace with the specified name.
811811
====
812812

813813

814+
== oc create policybinding
815+
Create a policy binding that references the policy in the targetted namespace.
816+
817+
====
818+
819+
[options="nowrap"]
820+
----
821+
# Create a policy binding in namespace "foo" that references the policy in namespace "bar"
822+
$ oc create policybinding bar -n foo
823+
----
824+
====
825+
826+
814827
== oc create route edge
815828
Create a route that uses edge TLS termination
816829

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package create
2+
3+
import (
4+
"fmt"
5+
"io"
6+
7+
"github.com/spf13/cobra"
8+
9+
"k8s.io/kubernetes/pkg/api/meta"
10+
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
11+
"k8s.io/kubernetes/pkg/runtime"
12+
13+
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
14+
"github.com/openshift/origin/pkg/client"
15+
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
16+
)
17+
18+
const (
19+
PolicyBindingRecommendedName = "policybinding"
20+
21+
policyBindingLong = `
22+
Create a policy binding that references the policy in the targetted namespace.`
23+
24+
policyBindingExample = ` # Create a policy binding in namespace "foo" that references the policy in namespace "bar"
25+
$ %[1]s bar -n foo`
26+
)
27+
28+
type CreatePolicyBindingOptions struct {
29+
BindingNamespace string
30+
PolicyNamespace string
31+
32+
BindingClient client.PolicyBindingsNamespacer
33+
34+
Mapper meta.RESTMapper
35+
OutputFormat string
36+
Out io.Writer
37+
Printer ObjectPrinter
38+
}
39+
40+
type ObjectPrinter func(runtime.Object, io.Writer) error
41+
42+
// NewCmdCreateServiceAccount is a macro command to create a new service account
43+
func NewCmdCreatePolicyBinding(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command {
44+
o := &CreatePolicyBindingOptions{Out: out}
45+
46+
cmd := &cobra.Command{
47+
Use: name + " TARGET_POLICY_NAMESPACE",
48+
Short: "Create a policy binding that references the policy in the targetted namespace.",
49+
Long: policyBindingLong,
50+
Example: fmt.Sprintf(policyBindingExample, fullName),
51+
Run: func(cmd *cobra.Command, args []string) {
52+
cmdutil.CheckErr(o.Complete(cmd, f, args))
53+
cmdutil.CheckErr(o.Validate())
54+
cmdutil.CheckErr(o.Run())
55+
},
56+
}
57+
cmdutil.AddOutputFlagsForMutation(cmd)
58+
return cmd
59+
}
60+
61+
func (o *CreatePolicyBindingOptions) Complete(cmd *cobra.Command, f *clientcmd.Factory, args []string) error {
62+
if len(args) != 1 {
63+
return fmt.Errorf("exactly one argument (policy namespace) is supported, not: %v", args)
64+
}
65+
o.PolicyNamespace = args[0]
66+
67+
namespace, _, err := f.DefaultNamespace()
68+
if err != nil {
69+
return err
70+
}
71+
o.BindingNamespace = namespace
72+
73+
client, _, err := f.Clients()
74+
if err != nil {
75+
return err
76+
}
77+
o.BindingClient = client
78+
79+
o.Mapper, _ = f.Object(false)
80+
o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
81+
82+
o.Printer = func(obj runtime.Object, out io.Writer) error {
83+
return f.PrintObject(cmd, o.Mapper, obj, out)
84+
}
85+
86+
return nil
87+
}
88+
89+
func (o *CreatePolicyBindingOptions) Validate() error {
90+
if len(o.BindingNamespace) == 0 {
91+
return fmt.Errorf("destination namespace is required")
92+
}
93+
if len(o.PolicyNamespace) == 0 {
94+
return fmt.Errorf("referenced policy namespace is required")
95+
}
96+
if o.BindingClient == nil {
97+
return fmt.Errorf("BindingClient is required")
98+
}
99+
if o.Mapper == nil {
100+
return fmt.Errorf("Mapper is required")
101+
}
102+
if o.Out == nil {
103+
return fmt.Errorf("Out is required")
104+
}
105+
if o.Printer == nil {
106+
return fmt.Errorf("Printer is required")
107+
}
108+
109+
return nil
110+
}
111+
112+
func (o *CreatePolicyBindingOptions) Run() error {
113+
binding := &authorizationapi.PolicyBinding{}
114+
binding.PolicyRef.Namespace = o.PolicyNamespace
115+
binding.PolicyRef.Name = authorizationapi.PolicyName
116+
binding.Name = authorizationapi.GetPolicyBindingName(binding.PolicyRef.Namespace)
117+
118+
actualBinding, err := o.BindingClient.PolicyBindings(o.BindingNamespace).Create(binding)
119+
if err != nil {
120+
return err
121+
}
122+
123+
if useShortOutput := o.OutputFormat == "name"; useShortOutput || len(o.OutputFormat) == 0 {
124+
cmdutil.PrintSuccess(o.Mapper, useShortOutput, o.Out, "policybinding", actualBinding.Name, "created")
125+
return nil
126+
}
127+
128+
return o.Printer(actualBinding, o.Out)
129+
}

pkg/cmd/cli/cmd/wrappers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1414
kvalidation "k8s.io/kubernetes/pkg/util/validation"
1515

16+
"github.com/openshift/origin/pkg/cmd/cli/cmd/create"
1617
cmdconfig "github.com/openshift/origin/pkg/cmd/cli/config"
1718
"github.com/openshift/origin/pkg/cmd/cli/describe"
1819
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
@@ -157,6 +158,7 @@ func NewCmdCreate(parentName string, f *clientcmd.Factory, out io.Writer) *cobra
157158

158159
// create subcommands
159160
cmd.AddCommand(NewCmdCreateRoute(parentName, f, out))
161+
cmd.AddCommand(create.NewCmdCreatePolicyBinding(create.PolicyBindingRecommendedName, parentName+" create "+create.PolicyBindingRecommendedName, f, out))
160162

161163
adjustCmdExamples(cmd, parentName, "create")
162164

test/cmd/admin.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,25 @@ os::cmd::expect_success_and_not_text 'oc get scc/restricted -o yaml' 'topic: my-
353353
echo "reconcile-scc: ok"
354354
os::test::junit::declare_suite_end
355355

356+
357+
os::test::junit::declare_suite_start "cmd/admin/policybinding-required"
358+
# Admin can't bind local roles without cluster-admin permissions
359+
os::cmd::expect_success "oc create -f test/extended/fixtures/roles/empty-role.yaml -n cmd-admin"
360+
os::cmd::expect_success "oc delete policybinding/cmd-admin:default -n cmd-admin"
361+
os::cmd::expect_success 'oadm policy add-role-to-user admin local-admin -n cmd-admin'
362+
os::cmd::try_until_text "oc policy who-can get policybindings -n cmd-admin" "local-admin"
363+
os::cmd::expect_success 'oc login -u local-admin -p pw'
364+
os::cmd::expect_failure 'oc policy add-role-to-user empty-role other --role-namespace=cmd-admin'
365+
os::cmd::expect_success 'oc login -u system:admin'
366+
os::cmd::expect_success "oc create policybinding cmd-admin -n cmd-admin"
367+
os::cmd::expect_success 'oc login -u local-admin -p pw'
368+
os::cmd::expect_success 'oc policy add-role-to-user empty-role other --role-namespace=cmd-admin -n cmd-admin'
369+
os::cmd::expect_success 'oc login -u system:admin'
370+
os::cmd::expect_success "oc delete role/empty-role -n cmd-admin"
371+
echo "policybinding-required: ok"
372+
os::test::junit::declare_suite_end
373+
374+
356375
os::test::junit::declare_suite_start "cmd/admin/user-group-cascade"
357376
# Create test users/identities and groups
358377
os::cmd::expect_success 'oc login -u cascaded-user -p pw'
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
kind: Role
3+
metadata:
4+
name: empty-role

0 commit comments

Comments
 (0)