Skip to content
1 change: 1 addition & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ Users can only change RoleTemplates with rights less than or equal to those they
The `roletemplates.context` field must be one of the following values [`"cluster"`, `"project"`, `""`].
If the `roletemplates.administrative` is set to true the context must equal `"cluster"`.

If the `roletemplate.ProjectCreatorDefault` is true, context must equal `"project"`
#### Builtin Validation

The `roletemplates.builtin` field is immutable, and new builtIn RoleTemplates cannot be created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Users can only change RoleTemplates with rights less than or equal to those they
The `roletemplates.context` field must be one of the following values [`"cluster"`, `"project"`, `""`].
If the `roletemplates.administrative` is set to true the context must equal `"cluster"`.

If the `roletemplate.ProjectCreatorDefault` is true, context must equal `"project"`
### Builtin Validation

The `roletemplates.builtin` field is immutable, and new builtIn RoleTemplates cannot be created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ func validateCreateFields(newRole *v3.RoleTemplate, fldPath *field.Path) *field.
}

func validateContextValue(newRole *v3.RoleTemplate, fldPath *field.Path) *field.Error {
if newRole.Context != projectContext && newRole.ProjectCreatorDefault {
return field.Forbidden(fldPath.Child("context"), "RoleTemplate context must be project when projectCreatorDefault=true")
}
if newRole.Administrative && newRole.Context != clusterContext {
return field.Forbidden(fldPath.Child("administrative"), "only cluster roles can be administrative")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,23 @@ func (r *RoleTemplateSuite) Test_Create() {
},
allowed: true,
},
{
name: "cluster context with projectCreatorDefault=true",
args: args{
username: adminUser,
oldRT: func() *v3.RoleTemplate {
return nil
},
newRT: func() *v3.RoleTemplate {
baseRT := newDefaultRT()
baseRT.Rules = r.manageNodeRole.Rules
baseRT.Context = "cluster"
baseRT.ProjectCreatorDefault = true
return baseRT
},
},
allowed: false,
},
}

for i := range tests {
Expand Down
1 change: 1 addition & 0 deletions tests/integration/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func (m *IntegrationSuite) TestMutateProject() {
GenerateName: "test-project-creator-",
},
ProjectCreatorDefault: true,
Context: "project",
}
err = rtClient.Create(ctx, "", rt, rt, metav1.CreateOptions{})
m.Require().NoError(err)
Expand Down
32 changes: 32 additions & 0 deletions tests/integration/roleTemplate_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package integration_test

import (
"context"
"time"

v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
rbacv1 "k8s.io/api/rbac/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -118,3 +121,32 @@ func (m *IntegrationSuite) TestRoleTemplateNoAPIGroups() {
}
validateEndpoints(m.T(), endPoints, m.clientFactory)
}

// ProjectCreatorDefault=true should not have other than Project context
func (m *IntegrationSuite) TestRoleTemplateWithProjectCreatorDefault() {
invalidRoleTemplate := &v3.RoleTemplate{
ObjectMeta: v1.ObjectMeta{
Name: "test-roletemplate-invalid-context",
},
Rules: []rbacv1.PolicyRule{
{
Verbs: []string{"GET", "WATCH"},
APIGroups: []string{"v1"},
Resources: []string{"pods"},
},
},
Context: "cluster",
ProjectCreatorDefault: true,
}
gvk, err := m.clientFactory.GVKForObject(invalidRoleTemplate)
m.Require().NoError(err, "Failed to get gvk")
client, err := m.clientFactory.ForKind(gvk)
m.Require().NoError(err, "Failed to create client")

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

err = client.Create(ctx, invalidRoleTemplate.GetNamespace(), invalidRoleTemplate, nil, v1.CreateOptions{})
m.Assert().NotNil(err)
m.Assert().Contains(err.Error(), "RoleTemplate context must be project when projectCreatorDefault=true")
}