func PolicyBindingNameValidator(policyRefNamespace string) validation.ValidateNameFunc { return func(name string, prefix bool) []string { if reasons := validation.ValidatePathSegmentName(name, prefix); len(reasons) != 0 { return reasons } if name != authorizationapi.GetPolicyBindingName(policyRefNamespace) { return []string{"name must be " + authorizationapi.GetPolicyBindingName(policyRefNamespace)} } return nil } }
func PolicyBindingNameValidator(policyRefNamespace string) validation.ValidateNameFunc { return func(name string, prefix bool) (bool, string) { if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { return ok, reason } if name != authorizationapi.GetPolicyBindingName(policyRefNamespace) { return false, "name must be " + authorizationapi.GetPolicyBindingName(policyRefNamespace) } return true, "" } }
func TestValidateClusterPolicyBinding(t *testing.T) { errorCases := map[string]struct { A authorizationapi.PolicyBinding T fielderrors.ValidationErrorType F string }{ "external namespace ref": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName("master")}, PolicyRef: kapi.ObjectReference{Namespace: "master"}, }, T: fielderrors.ValidationErrorTypeInvalid, F: "policyRef.namespace", }, } for k, v := range errorCases { errs := ValidatePolicyBinding(&v.A, false) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].(*fielderrors.ValidationError).Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].(*fielderrors.ValidationError).Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } }
func testNewLocalBindings() []authorizationapi.PolicyBinding { return []authorizationapi.PolicyBinding{ { ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName("unittest"), Namespace: "unittest"}, RoleBindings: map[string]*authorizationapi.RoleBinding{}, }, } }
// PrepareForCreate clears fields that are not allowed to be set by end users on creation. func (s strategy) PrepareForCreate(obj runtime.Object) { binding := obj.(*authorizationapi.PolicyBinding) s.scrubBindingRefs(binding) // force a delimited name, just in case we someday allow a reference to a global object that won't have a namespace. We'll end up with a name like ":default". // ":" is not in the value space of namespaces, so no escaping is necessary binding.Name = authorizationapi.GetPolicyBindingName(binding.PolicyRef.Namespace) }
// getPolicyBindingForPolicy returns a PolicyBinding that points to the specified policyNamespace. It will autocreate ONLY if policyNamespace equals the master namespace func (m *VirtualStorage) getPolicyBindingForPolicy(ctx kapi.Context, policyNamespace string, allowAutoProvision bool) (*authorizationapi.PolicyBinding, error) { // we can autocreate a PolicyBinding object if the RoleBinding is for the master namespace OR if we've been explicity told to create the policying binding. // the latter happens during priming if (policyNamespace == "") || allowAutoProvision { return m.ensurePolicyBindingToMaster(ctx, policyNamespace, authorizationapi.GetPolicyBindingName(policyNamespace)) } policyBinding, err := m.BindingRegistry.GetPolicyBinding(ctx, authorizationapi.GetPolicyBindingName(policyNamespace)) if err != nil { return nil, err } if policyBinding.RoleBindings == nil { policyBinding.RoleBindings = make(map[string]*authorizationapi.RoleBinding) } return policyBinding, nil }
func (a LocalRoleBindingAccessor) GetExistingRoleBindingsForRole(roleNamespace, role string) ([]*authorizationapi.RoleBinding, error) { existingBindings, err := a.Client.PolicyBindings(a.BindingNamespace).Get(authorizationapi.GetPolicyBindingName(roleNamespace)) if err != nil && !kapierrors.IsNotFound(err) { return nil, err } ret := make([]*authorizationapi.RoleBinding, 0) // see if we can find an existing binding that points to the role in question. for _, currBinding := range existingBindings.RoleBindings { if currBinding.RoleRef.Name == role { t := currBinding ret = append(ret, t) } } return ret, nil }
func (o *CreatePolicyBindingOptions) Run() error { binding := &authorizationapi.PolicyBinding{} binding.PolicyRef.Namespace = o.PolicyNamespace binding.PolicyRef.Name = authorizationapi.PolicyName binding.Name = authorizationapi.GetPolicyBindingName(binding.PolicyRef.Namespace) actualBinding, err := o.BindingClient.PolicyBindings(o.BindingNamespace).Create(binding) if err != nil { return err } if useShortOutput := o.OutputFormat == "name"; useShortOutput || len(o.OutputFormat) == 0 { cmdutil.PrintSuccess(o.Mapper, useShortOutput, o.Out, "policybinding", actualBinding.Name, false, "created") return nil } return o.Printer(actualBinding, o.Out) }
func newAdzeBindings() []authorizationapi.PolicyBinding { return []authorizationapi.PolicyBinding{ { ObjectMeta: kapi.ObjectMeta{ Name: authorizationapi.ClusterPolicyBindingName, Namespace: "adze", }, RoleBindings: map[string]*authorizationapi.RoleBinding{ "projectAdmins": { ObjectMeta: kapi.ObjectMeta{ Name: "projectAdmins", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.AdminRoleName, }, Users: util.NewStringSet("Anna"), }, "viewers": { ObjectMeta: kapi.ObjectMeta{ Name: "viewers", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.ViewRoleName, }, Users: util.NewStringSet("Valerie"), }, "editors": { ObjectMeta: kapi.ObjectMeta{ Name: "editors", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.EditRoleName, }, Users: util.NewStringSet("Ellen"), }, }, }, { ObjectMeta: kapi.ObjectMeta{ Name: authorizationapi.GetPolicyBindingName("adze"), Namespace: "adze", }, RoleBindings: map[string]*authorizationapi.RoleBinding{ "restrictedViewers": { ObjectMeta: kapi.ObjectMeta{ Name: "restrictedViewers", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: "restrictedViewer", Namespace: "adze", }, Users: util.NewStringSet("Rachel"), }, }, }, } }
func newAdzeBindings() []authorizationapi.PolicyBinding { return []authorizationapi.PolicyBinding{ { ObjectMeta: kapi.ObjectMeta{ Name: authorizationapi.ClusterPolicyBindingName, Namespace: "adze", }, RoleBindings: map[string]*authorizationapi.RoleBinding{ "projectAdmins": { ObjectMeta: kapi.ObjectMeta{ Name: "projectAdmins", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.AdminRoleName, }, Subjects: []kapi.ObjectReference{{Kind: authorizationapi.UserKind, Name: "Anna"}}, }, "viewers": { ObjectMeta: kapi.ObjectMeta{ Name: "viewers", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.ViewRoleName, }, Subjects: []kapi.ObjectReference{ {Kind: authorizationapi.UserKind, Name: "Valerie"}, {Name: "first", Namespace: "other", Kind: authorizationapi.ServiceAccountKind}, {Name: "second", Kind: authorizationapi.ServiceAccountKind}, }, }, "editors": { ObjectMeta: kapi.ObjectMeta{ Name: "editors", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: bootstrappolicy.EditRoleName, }, Subjects: []kapi.ObjectReference{{Kind: authorizationapi.UserKind, Name: "Ellen"}}, }, }, }, { ObjectMeta: kapi.ObjectMeta{ Name: authorizationapi.GetPolicyBindingName("adze"), Namespace: "adze", }, RoleBindings: map[string]*authorizationapi.RoleBinding{ "restrictedViewers": { ObjectMeta: kapi.ObjectMeta{ Name: "restrictedViewers", Namespace: "adze", }, RoleRef: kapi.ObjectReference{ Name: "restrictedViewer", Namespace: "adze", }, Subjects: []kapi.ObjectReference{{Kind: authorizationapi.UserKind, Name: "Rachel"}}, }, }, }, } }
func TestRestrictUsers(t *testing.T) { testutil.RequireEtcd(t) defer testutil.DumpEtcdOnFailure(t) masterConfig, err := testserver.DefaultMasterOptions() if err != nil { t.Fatalf("error creating config: %v", err) } masterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "openshift.io/RestrictSubjectBindings": { Configuration: &configapi.DefaultAdmissionConfig{}, }, } clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, "namespace", "carol"); err != nil { t.Fatalf("unexpected error: %v", err) } role := &authorizationapi.Role{ ObjectMeta: kapi.ObjectMeta{ Namespace: "namespace", Name: "role", }, } if _, err := clusterAdminClient.Roles("namespace").Create(role); err != nil { t.Fatalf("unexpected error: %v", err) } policyBinding := &authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{ Namespace: "namespace", Name: "policybinding", }, PolicyRef: kapi.ObjectReference{ Namespace: "namespace", Name: authorizationapi.GetPolicyBindingName("policy"), }, } if _, err := clusterAdminClient.PolicyBindings("namespace").Create(policyBinding); err != nil { t.Fatalf("unexpected error: %v", err) } rolebindingAlice := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{ Namespace: "namespace", Name: "rolebinding1", }, Subjects: []kapi.ObjectReference{ { Kind: authorizationapi.UserKind, Namespace: "namespace", Name: "alice", }, }, RoleRef: kapi.ObjectReference{Name: "role", Namespace: "namespace"}, } // Creating a rolebinding when no restrictions exist should succeed. if _, err := clusterAdminClient.RoleBindings("namespace").Create(rolebindingAlice); err != nil { t.Fatalf("unexpected error: %v", err) } allowAlice := &authorizationapi.RoleBindingRestriction{ ObjectMeta: kapi.ObjectMeta{ Name: "match-users-alice", Namespace: "namespace", }, Spec: authorizationapi.RoleBindingRestrictionSpec{ UserRestriction: &authorizationapi.UserRestriction{ Users: []string{"alice"}, }, }, } if _, err := clusterAdminClient.RoleBindingRestrictions("namespace").Create(allowAlice); err != nil { t.Fatalf("unexpected error: %v", err) } rolebindingAliceDup := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{ Namespace: "namespace", Name: "rolebinding2", }, Subjects: []kapi.ObjectReference{ { Kind: authorizationapi.UserKind, Namespace: "namespace", Name: "alice", }, }, RoleRef: kapi.ObjectReference{Name: "role", Namespace: "namespace"}, } // Creating a rolebinding when the subject is already bound should succeed. if _, err := clusterAdminClient.RoleBindings("namespace").Create(rolebindingAliceDup); err != nil { t.Fatalf("unexpected error: %v", err) } rolebindingBob := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{ Namespace: "namespace", Name: "rolebinding3", }, Subjects: []kapi.ObjectReference{ { Kind: authorizationapi.UserKind, Namespace: "namespace", Name: "bob", }, }, RoleRef: kapi.ObjectReference{Name: "role", Namespace: "namespace"}, } // Creating a rolebinding when the subject is not already bound and is not // permitted by any RoleBindingRestrictions should fail. if _, err := clusterAdminClient.RoleBindings("namespace").Create(rolebindingBob); !kapierrors.IsForbidden(err) { t.Fatalf("expected forbidden, got %v", err) } allowBob := &authorizationapi.RoleBindingRestriction{ ObjectMeta: kapi.ObjectMeta{ Name: "match-users-bob", Namespace: "namespace", }, Spec: authorizationapi.RoleBindingRestrictionSpec{ UserRestriction: &authorizationapi.UserRestriction{ Users: []string{"bob"}, }, }, } if _, err := clusterAdminClient.RoleBindingRestrictions("namespace").Create(allowBob); err != nil { t.Fatalf("unexpected error: %v", err) } // Creating a rolebinding when the subject is permitted by some // RoleBindingRestrictions should succeed. if _, err := clusterAdminClient.RoleBindings("namespace").Create(rolebindingBob); err != nil { t.Fatalf("unexpected error: %v", err) } }
func TestValidatePolicyBinding(t *testing.T) { errs := ValidatePolicyBinding( &authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName("master")}, PolicyRef: kapi.ObjectReference{Namespace: "master"}, }, true, ) if len(errs) != 0 { t.Errorf("expected success: %v", errs) } errorCases := map[string]struct { A authorizationapi.PolicyBinding T fielderrors.ValidationErrorType F string }{ "zero-length namespace": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: fielderrors.ValidationErrorTypeRequired, F: "metadata.namespace", }, "zero-length name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: fielderrors.ValidationErrorTypeRequired, F: "metadata.name", }, "invalid name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "name"}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, T: fielderrors.ValidationErrorTypeInvalid, F: "metadata.name", }, "bad role": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, RoleBindings: map[string]*authorizationapi.RoleBinding{ "any": { ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "any"}, RoleRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, }, }, }, T: fielderrors.ValidationErrorTypeRequired, F: "roleBindings.any.roleRef.name", }, "mismatched name": { A: authorizationapi.PolicyBinding{ ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName(authorizationapi.PolicyName)}, PolicyRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName}, RoleBindings: map[string]*authorizationapi.RoleBinding{ "any1": { ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "any"}, RoleRef: kapi.ObjectReference{Namespace: authorizationapi.PolicyName, Name: "valid"}, }, }, }, T: fielderrors.ValidationErrorTypeInvalid, F: "roleBindings.any1.metadata.name", }, } for k, v := range errorCases { errs := ValidatePolicyBinding(&v.A, true) if len(errs) == 0 { t.Errorf("expected failure %s for %v", k, v.A) continue } for i := range errs { if errs[i].(*fielderrors.ValidationError).Type != v.T { t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i]) } if errs[i].(*fielderrors.ValidationError).Field != v.F { t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i]) } } } }