Skip to content

Commit 71becb7

Browse files
authored
CLOUDP-136889: Project Custom Roles (#745)
Add Custom Roles feature
1 parent 4d508ba commit 71becb7

16 files changed

+1034
-1
lines changed

.github/workflows/test-e2e.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ jobs:
9191
"privatelink",
9292
"project-settings",
9393
"x509auth",
94+
"custom-roles",
9495
]
9596

9697
steps:

config/crd/bases/atlas.mongodb.com_atlasprojects.yaml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,75 @@ spec:
277277
required:
278278
- name
279279
type: object
280+
customRoles:
281+
description: The customRoles lets you create, and change custom roles
282+
in your cluster. Use custom roles to specify custom sets of actions
283+
that the Atlas built-in roles can't describe.
284+
items:
285+
properties:
286+
actions:
287+
description: List of the individual privilege actions that the
288+
role grants.
289+
items:
290+
properties:
291+
name:
292+
description: Human-readable label that identifies the
293+
privilege action.
294+
type: string
295+
resources:
296+
description: List of resources on which you grant the
297+
action.
298+
items:
299+
properties:
300+
cluster:
301+
description: Flag that indicates whether to grant
302+
the action on the cluster resource. If true, MongoDB
303+
Cloud ignores Database and Collection parameters.
304+
type: boolean
305+
collection:
306+
description: Human-readable label that identifies
307+
the collection on which you grant the action to
308+
one MongoDB user.
309+
type: string
310+
database:
311+
description: Human-readable label that identifies
312+
the database on which you grant the action to
313+
one MongoDB user.
314+
type: string
315+
type: object
316+
type: array
317+
required:
318+
- name
319+
- resources
320+
type: object
321+
type: array
322+
inheritedRoles:
323+
description: List of the built-in roles that this custom role
324+
inherits.
325+
items:
326+
properties:
327+
database:
328+
description: Human-readable label that identifies the
329+
database on which someone grants the action to one MongoDB
330+
user.
331+
type: string
332+
name:
333+
description: Human-readable label that identifies the
334+
role inherited.
335+
type: string
336+
required:
337+
- database
338+
- name
339+
type: object
340+
type: array
341+
name:
342+
description: Human-readable label that identifies the role.
343+
This name must be unique for this custom role in this project.
344+
type: string
345+
required:
346+
- name
347+
type: object
348+
type: array
280349
encryptionAtRest:
281350
description: EncryptionAtRest allows to set encryption for AWS, Azure
282351
and GCP providers
@@ -1077,6 +1146,25 @@ spec:
10771146
- type
10781147
type: object
10791148
type: array
1149+
customRoles:
1150+
description: CustomRoles contains a list of custom roles statuses
1151+
items:
1152+
properties:
1153+
error:
1154+
description: The message when the custom role is in the FAILED
1155+
status
1156+
type: string
1157+
name:
1158+
description: Role name which is unique
1159+
type: string
1160+
status:
1161+
description: The status of the given custom role (OK or FAILED)
1162+
type: string
1163+
required:
1164+
- name
1165+
- status
1166+
type: object
1167+
type: array
10801168
expiredIpAccessList:
10811169
description: The list of IP Access List entries that are expired due
10821170
to 'deleteAfterDate' being less than the current date. Note, that

pkg/api/v1/atlasproject_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ type AtlasProjectSpec struct {
101101
// Settings allow to set Project Settings for the project
102102
// +optional
103103
Settings *ProjectSettings `json:"settings,omitempty"`
104+
105+
// The customRoles lets you create, and change custom roles in your cluster. Use custom roles to specify custom sets of actions that the Atlas built-in roles can't describe.
106+
// +optional
107+
CustomRoles []CustomRole `json:"customRoles,omitempty"`
104108
}
105109

106110
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

pkg/api/v1/custom_roles.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package v1
2+
3+
import "go.mongodb.org/atlas/mongodbatlas"
4+
5+
type CustomRole struct {
6+
// Human-readable label that identifies the role. This name must be unique for this custom role in this project.
7+
Name string `json:"name"`
8+
// List of the built-in roles that this custom role inherits.
9+
// +optional
10+
InheritedRoles []Role `json:"inheritedRoles,omitempty"`
11+
// List of the individual privilege actions that the role grants.
12+
// +optional
13+
Actions []Action `json:"actions,omitempty"`
14+
}
15+
16+
type Role struct {
17+
// Human-readable label that identifies the role inherited.
18+
Name string `json:"name"`
19+
// Human-readable label that identifies the database on which someone grants the action to one MongoDB user.
20+
Database string `json:"database"`
21+
}
22+
23+
type Action struct {
24+
// Human-readable label that identifies the privilege action.
25+
Name string `json:"name"`
26+
// List of resources on which you grant the action.
27+
Resources []Resource `json:"resources"`
28+
}
29+
30+
type Resource struct {
31+
// Flag that indicates whether to grant the action on the cluster resource. If true, MongoDB Cloud ignores Database and Collection parameters.
32+
Cluster *bool `json:"cluster,omitempty"`
33+
// Human-readable label that identifies the database on which you grant the action to one MongoDB user.
34+
Database *string `json:"database,omitempty"`
35+
// Human-readable label that identifies the collection on which you grant the action to one MongoDB user.
36+
Collection *string `json:"collection,omitempty"`
37+
}
38+
39+
func (in *CustomRole) ToAtlas() *mongodbatlas.CustomDBRole {
40+
actions := make([]mongodbatlas.Action, 0, len(in.Actions))
41+
42+
for _, action := range in.Actions {
43+
resources := make([]mongodbatlas.Resource, 0, len(action.Resources))
44+
45+
for _, resource := range action.Resources {
46+
resources = append(resources, mongodbatlas.Resource{
47+
Collection: resource.Collection,
48+
DB: resource.Database,
49+
Cluster: resource.Cluster,
50+
})
51+
}
52+
53+
actions = append(actions, mongodbatlas.Action{
54+
Action: action.Name,
55+
Resources: resources,
56+
})
57+
}
58+
59+
inheritedRoles := make([]mongodbatlas.InheritedRole, 0, len(in.InheritedRoles))
60+
61+
for _, inheritedRole := range in.InheritedRoles {
62+
inheritedRoles = append(inheritedRoles, mongodbatlas.InheritedRole{
63+
Db: inheritedRole.Database,
64+
Role: inheritedRole.Name,
65+
})
66+
}
67+
68+
return &mongodbatlas.CustomDBRole{
69+
Actions: actions,
70+
InheritedRoles: inheritedRoles,
71+
RoleName: in.Name,
72+
}
73+
}

pkg/api/v1/status/atlasproject.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ func AtlasProjectCloudAccessRolesOption(cloudAccessRoles []CloudProviderAccessRo
5858
}
5959
}
6060

61+
func AtlasProjectSetCustomRolesOption(customRoles *[]CustomRole) AtlasProjectStatusOption {
62+
return func(s *AtlasProjectStatus) {
63+
s.CustomRoles = *customRoles
64+
}
65+
}
66+
6167
func AtlasProjectPrometheusOption(prometheus *Prometheus) AtlasProjectStatusOption {
6268
return func(s *AtlasProjectStatus) {
6369
s.Prometheus = prometheus
@@ -93,6 +99,9 @@ type AtlasProjectStatus struct {
9399
// CloudProviderAccessRoles contains a list of configured cloud provider access roles. AWS support only
94100
CloudProviderAccessRoles []CloudProviderAccessRole `json:"cloudProviderAccessRoles,omitempty"`
95101

102+
// CustomRoles contains a list of custom roles statuses
103+
CustomRoles []CustomRole `json:"customRoles,omitempty"`
104+
96105
// Prometheus contains the status for Prometheus integration
97106
// including the prometheusDiscoveryURL
98107
// +optional

pkg/api/v1/status/condition.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const (
4646
EncryptionAtRestReadyType ConditionType = "EncryptionAtRestReady"
4747
AuditingReadyType ConditionType = "AuditingReady"
4848
ProjectSettingsReadyType ConditionType = "ProjectSettingsReady"
49+
ProjectCustomRolesReadyType ConditionType = "ProjectCustomRolesReady"
4950
)
5051

5152
// AtlasDeployment condition types

pkg/api/v1/status/custom_roles.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package status
2+
3+
type CustomRoleStatus string
4+
5+
const (
6+
CustomRoleStatusOK CustomRoleStatus = "OK"
7+
CustomRoleStatusFailed CustomRoleStatus = "FAILED"
8+
)
9+
10+
type CustomRole struct {
11+
// Role name which is unique
12+
Name string `json:"name"`
13+
// The status of the given custom role (OK or FAILED)
14+
Status CustomRoleStatus `json:"status"`
15+
// The message when the custom role is in the FAILED status
16+
Error string `json:"error,omitempty"`
17+
}

pkg/api/v1/status/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)