Exemple #1
0
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{},
		},
	}
}
Exemple #5
0
// 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)
}
Exemple #6
0
// 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
}
Exemple #7
0
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
}
Exemple #8
0
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)
}
Exemple #9
0
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])
			}
		}
	}
}