api: remove deprecated grant_scope_id field (#4886)

* api: remove deprecated grant_scope_id field

The grant_scope_id field was deprecated in 0.15.0, so we can remove
it for 0.17.0.

* Fix tests

* Fix more tests

* Remove an option and some related code that stuck around

* Fix bats tests

---------

Co-authored-by: Jeff Mitchell <jeffrey.mitchell@gmail.com>
This commit is contained in:
Johan Brandhorst-SatzkornandJeff Mitchell authored and GitHub committed 2024-06-17 12:09:33 -07:00
1 parent d547e0d459
commit c6f3c375f3
21 files changed
+107 -297

No files matched your search

+5
View File
@@ -9,6 +9,11 @@ Canonical reference for changes, improvements, and bugfixes for Boundary.
* Allow descriptions to contain newlines and other whitespace
([PR](https://github.com/hashicorp/boundary/pull/2599))
### Deprecations/Changes
* The `grant_scope_id` field on roles, which was deprecated in 0.15.0, has been removed.
([PR](https://github.com/hashicorp/boundary/pull/4886))
## 0.16.1 (2024/05/30)
### New and Improved
-12
View File
@@ -115,18 +115,6 @@ func DefaultDescription() Option {
}
}
func WithGrantScopeId(inGrantScopeId string) Option {
return func(o *options) {
o.postMap["grant_scope_id"] = inGrantScopeId
}
}
func DefaultGrantScopeId() Option {
return func(o *options) {
o.postMap["grant_scope_id"] = nil
}
}
func WithName(inName string) Option {
return func(o *options) {
o.postMap["name"] = inName
-1
View File
@@ -26,7 +26,6 @@ type Role struct {
CreatedTime time.Time `json:"created_time,omitempty"`
UpdatedTime time.Time `json:"updated_time,omitempty"`
Version uint32 `json:"version,omitempty"`
GrantScopeId string `json:"grant_scope_id,omitempty"`
GrantScopeIds []string `json:"grant_scope_ids,omitempty"`
PrincipalIds []string `json:"principal_ids,omitempty"`
Principals []*Principal `json:"principals,omitempty"`
-1
View File
@@ -31,7 +31,6 @@ const (
HostIdsField = "host_ids"
PrincipalIdsField = "principal_ids"
PrincipalsField = "principals"
GrantScopeIdField = "grant_scope_id"
GrantScopeIdsField = "grant_scope_ids"
GrantsField = "grants"
GrantStringsField = "grant_strings"
-19
View File
@@ -32,8 +32,6 @@ type extraCmdVars struct {
func extraActionsFlagsMapFuncImpl() map[string][]string {
return map[string][]string{
"create": {"grant-scope-id"},
"update": {"grant-scope-id"},
"add-principals": {"id", "principal", "version"},
"set-principals": {"id", "principal", "version"},
"remove-principals": {"id", "principal", "version"},
@@ -207,20 +205,6 @@ func extraFlagsFuncImpl(c *Command, _ *base.FlagSets, f *base.FlagSet) {
func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]roles.Option) bool {
switch c.Func {
case "create", "update":
switch len(c.flagGrantScopeIds) {
case 0:
case 1:
if c.flagGrantScopeIds[0] == "null" {
*opts = append(*opts, roles.DefaultGrantScopeId())
} else {
*opts = append(*opts, roles.WithGrantScopeId(c.flagGrantScopeIds[0]))
}
default:
c.UI.Error("-grant-scope-id cannot be specified multiple times when using the deprecated create/update grant_scope_id mechanism")
return false
}
case "add-principals", "remove-principals":
if len(c.flagPrincipals) == 0 {
c.UI.Error("No principals supplied via -principal")
@@ -427,9 +411,6 @@ func printItemTable(item *roles.Role, resp *api.Response) string {
if item.Description != "" {
nonAttributeMap["Description"] = item.Description
}
if item.GrantScopeId != "" {
nonAttributeMap["Grant Scope ID"] = item.GrantScopeId
}
maxLength := base.MaxAttributesLength(nonAttributeMap, nil, nil)
@@ -739,9 +739,6 @@ func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role
if item.GetDescription() != nil {
opts = append(opts, iam.WithDescription(item.GetDescription().GetValue()))
}
if item.GetGrantScopeId() != nil {
opts = append(opts, iam.WithGrantScopeId(item.GetGrantScopeId().GetValue()))
}
u, err := iam.NewRole(ctx, scopeId, opts...)
if err != nil {
return nil, nil, nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build role for creation: %v.", err)
@@ -782,27 +779,8 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st
return nil, nil, nil, nil, err
}
// This has to be separate from Translate since the field only exists on the
// API side now.
var hasGrantScopeIdMask bool
if grantScopeId := item.GetGrantScopeId(); grantScopeId != nil {
// Have to manually check the masks, which could be concatenated strings or slices
for _, v := range mask {
if strutil.StrListContains(strings.Split(v, ","), "grant_scope_id") {
opts = append(opts, iam.WithGrantScopeId(grantScopeId.GetValue()))
hasGrantScopeIdMask = true
break
}
}
if hasGrantScopeIdMask {
if err := validateRoleGrantScopesHierarchy(ctx, repo, id, []string{item.GetGrantScopeId().GetValue()}); err != nil {
return nil, nil, nil, nil, err
}
}
}
dbMask := maskManager.Translate(mask)
if len(dbMask) == 0 && !hasGrantScopeIdMask {
if len(dbMask) == 0 {
return nil, nil, nil, nil, handlers.InvalidArgumentErrorf("No valid fields provided in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
}
@@ -813,7 +791,7 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st
// This is slightly problematic but it's a very unlikely error case and when
// we remove the ability to update grant scope ID via here in 0.17 it will
// go away.
if rowsUpdated == 0 && !hasGrantScopeIdMask {
if rowsUpdated == 0 {
return nil, nil, nil, nil, handlers.NotFoundErrorf("Role %q doesn't exist or incorrect version provided.", id)
}
return out, pr, gr, grantScopes, nil
@@ -1128,9 +1106,6 @@ func toProto(ctx context.Context, in *iam.Role, principals []*iam.PrincipalRole,
}
sort.Strings(out.GrantScopeIds)
}
if outputFields.Has(globals.GrantScopeIdField) && len(grantScopes) == 1 {
out.GrantScopeId = &wrapperspb.StringValue{Value: grantScopes[0].ScopeIdOrSpecial}
}
if outputFields.Has(globals.PrincipalsField) {
for _, p := range principals {
principal := &pb.Principal{
@@ -1194,17 +1169,6 @@ func validateCreateRequest(req *pbs.CreateRoleRequest) error {
scope.Global.String() != item.GetScopeId() {
badFields["scope_id"] = "This field is missing or improperly formatted."
}
if item.GetGrantScopeId() != nil {
switch {
case handlers.ValidId(handlers.Id(item.GetScopeId()), scope.Project.Prefix()):
switch item.GetGrantScopeId().GetValue() {
case item.GetScopeId(),
globals.GrantScopeThis:
default:
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID or \"this\"."
}
}
}
if item.GetPrincipals() != nil {
badFields["principals"] = "This is a read only field."
}
@@ -1230,17 +1194,6 @@ func validateUpdateRequest(req *pbs.UpdateRoleRequest) error {
if req.GetItem().GetGrantStrings() != nil {
badFields["grant_strings"] = "This is a read only field and cannot be specified in an update request."
}
if item := req.GetItem(); item != nil {
switch {
case handlers.ValidId(handlers.Id(item.GetScopeId()), scope.Project.Prefix()):
switch item.GetGrantScopeId().GetValue() {
case item.GetScopeId(),
globals.GrantScopeThis:
default:
badFields["grant_scope_id"] = "When the role is in a project scope this value must be that project's scope ID or \"this\"."
}
}
}
return badFields
}, globals.RolePrefix)
}
@@ -1531,7 +1484,7 @@ func validateRoleGrantScopesHierarchy(ctx context.Context, repo *iam.Repository,
return handlers.InvalidArgumentErrorf(
"Invalid grant scope.",
map[string]string{
"grant_scope_id": `Project scopes can only have their own scope ID or "this" as a grant scope ID.`,
"grant_scope_ids": `Project scopes can only have their own scope ID or "this" as a grant scope ID.`,
})
}
}
@@ -1547,7 +1500,7 @@ func validateRoleGrantScopesHierarchy(ctx context.Context, repo *iam.Repository,
return handlers.InvalidArgumentErrorf(
"Invalid grant scope.",
map[string]string{
"grant_scope_id": fmt.Sprintf("Grant scope ID %q is not valid to set on an organization role.", grantScope),
"grant_scope_ids": fmt.Sprintf("Grant scope ID %q is not valid to set on an organization role.", grantScope),
})
}
}
@@ -1556,7 +1509,7 @@ func validateRoleGrantScopesHierarchy(ctx context.Context, repo *iam.Repository,
return handlers.InvalidArgumentErrorf(
"Improperly formatted identifier.",
map[string]string{
"grant_scope_id": `Unknown scope prefix type.`,
"grant_scope_ids": `Unknown scope prefix type.`,
})
}
return nil
@@ -59,7 +59,7 @@ func createDefaultRolesAndRepo(t *testing.T) (*iam.Role, *iam.Role, func() (*iam
}
o, p := iam.TestScopes(t, iamRepo)
or := iam.TestRole(t, conn, o.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"), iam.WithGrantScopeId(p.GetPublicId()))
or := iam.TestRole(t, conn, o.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"), iam.WithGrantScopeIds([]string{p.GetPublicId()}))
pr := iam.TestRole(t, conn, p.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"))
return or, pr, repoFn
}
@@ -101,7 +101,6 @@ func TestGet(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: or.GetScopeId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()},
Name: &wrapperspb.StringValue{Value: or.GetName()},
Description: &wrapperspb.StringValue{Value: or.GetDescription()},
GrantScopeId: &wrapperspb.StringValue{Value: pr.GetScopeId()},
GrantScopeIds: []string{pr.GetScopeId()},
CreatedTime: or.CreateTime.GetTimestamp(),
UpdatedTime: or.UpdateTime.GetTimestamp(),
@@ -115,7 +114,6 @@ func TestGet(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: pr.GetScopeId(), Type: scope.Project.String(), ParentScopeId: or.GetScopeId()},
Name: &wrapperspb.StringValue{Value: pr.GetName()},
Description: &wrapperspb.StringValue{Value: pr.GetDescription()},
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
CreatedTime: pr.CreateTime.GetTimestamp(),
UpdatedTime: pr.UpdateTime.GetTimestamp(),
@@ -891,10 +889,9 @@ func TestCreate(t *testing.T) {
{
name: "Create a valid Role",
req: &pbs.CreateRoleRequest{Item: &pb.Role{
ScopeId: defaultOrgRole.GetScopeId(),
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId},
ScopeId: defaultOrgRole.GetScopeId(),
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
}},
res: &pbs.CreateRoleResponse{
Uri: fmt.Sprintf("roles/%s_", globals.RolePrefix),
@@ -903,8 +900,7 @@ func TestCreate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: defaultOrgRole.GetScopeId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId},
GrantScopeIds: []string{defaultProjRole.ScopeId},
GrantScopeIds: []string{globals.GrantScopeThis},
Version: 2,
AuthorizedActions: testAuthorizedActions,
},
@@ -913,10 +909,9 @@ func TestCreate(t *testing.T) {
{
name: "Create a valid Global Role",
req: &pbs.CreateRoleRequest{Item: &pb.Role{
ScopeId: scope.Global.String(),
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId},
ScopeId: scope.Global.String(),
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
}},
res: &pbs.CreateRoleResponse{
Uri: fmt.Sprintf("roles/%s_", globals.RolePrefix),
@@ -925,8 +920,7 @@ func TestCreate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: scope.Global.String(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId},
GrantScopeIds: []string{defaultProjRole.ScopeId},
GrantScopeIds: []string{globals.GrantScopeThis},
Version: 2,
AuthorizedActions: testAuthorizedActions,
},
@@ -948,26 +942,12 @@ func TestCreate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: defaultProjRole.GetScopeId(), Type: scope.Project.String(), ParentScopeId: defaultOrgRole.GetScopeId()},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
Version: 2,
AuthorizedActions: testAuthorizedActions,
},
},
},
{
name: "Invalid grant scope ID",
req: &pbs.CreateRoleRequest{
Item: &pb.Role{
ScopeId: defaultProjRole.GetScopeId(),
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: defaultOrgRole.GetScopeId()},
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Can't specify Id",
req: &pbs.CreateRoleRequest{Item: &pb.Role{
@@ -1128,7 +1108,6 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: or.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: p.GetPublicId()},
GrantScopeIds: []string{p.GetPublicId()},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
@@ -1143,12 +1122,11 @@ func TestUpdate(t *testing.T) {
scopeId: or.GetScopeId(),
req: &pbs.UpdateRoleRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,description,grant_scope_id"},
Paths: []string{"name,description"},
},
Item: &pb.Role{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
},
},
res: &pbs.UpdateRoleResponse{
@@ -1159,8 +1137,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: or.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantScopeIds: []string{p.GetPublicId()},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
PrincipalIds: []string{u.GetPublicId()},
@@ -1190,7 +1167,6 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: pr.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
@@ -1221,7 +1197,6 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: pr.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
@@ -1283,8 +1258,7 @@ func TestUpdate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: or.GetScopeId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()},
Description: &wrapperspb.StringValue{Value: "default"},
CreatedTime: or.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantScopeIds: []string{p.GetPublicId()},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
PrincipalIds: []string{u.GetPublicId()},
@@ -1313,8 +1287,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "updated"},
Description: &wrapperspb.StringValue{Value: "default"},
CreatedTime: or.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantScopeIds: []string{p.GetPublicId()},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
PrincipalIds: []string{u.GetPublicId()},
@@ -1343,8 +1316,7 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "default"},
Description: &wrapperspb.StringValue{Value: "notignored"},
CreatedTime: or.GetCreateTime().GetTimestamp(),
GrantScopeId: &wrapperspb.StringValue{Value: globals.GrantScopeThis},
GrantScopeIds: []string{globals.GrantScopeThis},
GrantScopeIds: []string{p.GetPublicId()},
GrantStrings: []string{grant.GetRaw()},
Grants: []*pb.Grant{grant},
PrincipalIds: []string{u.GetPublicId()},
-4
View File
@@ -6896,10 +6896,6 @@
"format": "int64",
"description": "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version."
},
"grant_scope_id": {
"type": "string",
"description": "The Scope the grants will apply to. If the Role is at the global scope,\nthis can be an org or project. If the Role is at an org scope, this can be\na project within the org. It is invalid for this to be anything other than\nthe Role's scope when the Role's scope is a project.\n\nDeprecated: Use \"grant_scope_ids\" instead."
},
"grant_scope_ids": {
"type": "array",
"items": {
-12
View File
@@ -30,7 +30,6 @@ type options struct {
withName string
withDescription string
withLimit int
withGrantScopeId *string
withGrantScopeIds []string
withSkipVetForWrite bool
withDisassociate bool
@@ -85,17 +84,6 @@ func WithLimit(limit int) Option {
}
}
// WithGrantScopeId provides an option to specify the scope ID for grants in
// roles.
func WithGrantScopeId(id string) Option {
return func(o *options) {
if o.withGrantScopeId == nil {
o.withGrantScopeId = new(string)
}
*o.withGrantScopeId = id
}
}
// WithGrantScopeIds provides an option to specify the scope ID for grants in
// roles. In most tests this is likely the option to use, however, for tests
// that call repo functions instead of test functions the other option is still
-9
View File
@@ -61,15 +61,6 @@ func Test_GetOpts(t *testing.T) {
testOpts.withLimit = 1
assert.Equal(opts, testOpts)
})
t.Run("WithGrantScopeId", func(t *testing.T) {
assert := assert.New(t)
str := "o_1234"
opts := getOpts(WithGrantScopeId(str))
testOpts := getDefaultOptions()
testOpts.withGrantScopeId = &str
assert.Equal(opts, testOpts)
})
t.Run("WithDisassociate", func(t *testing.T) {
assert := assert.New(t)
// test default of false
+5 -32
View File
@@ -40,18 +40,6 @@ func (r *Repository) CreateRole(ctx context.Context, role *Role, opt ...Option)
c := role.Clone().(*Role)
c.PublicId = id
opts := getOpts(opt...)
var initialScope string
switch {
case opts.withGrantScopeId == nil:
initialScope = globals.GrantScopeThis
case *opts.withGrantScopeId == "":
initialScope = globals.GrantScopeThis
default:
initialScope = *opts.withGrantScopeId
}
var resource Resource
var pr []*PrincipalRole
var rg []*RoleGrant
@@ -65,7 +53,7 @@ func (r *Repository) CreateRole(ctx context.Context, role *Role, opt ...Option)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("while creating role"))
}
_, _, err = r.SetRoleGrantScopes(ctx, id, resource.(*Role).Version, []string{initialScope}, WithReaderWriter(reader, writer))
_, _, err = r.SetRoleGrantScopes(ctx, id, resource.(*Role).Version, []string{globals.GrantScopeThis}, WithReaderWriter(reader, writer))
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("while setting grant scopes"))
}
@@ -112,18 +100,6 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32,
}
}
opts := getOpts(opt...)
var grantScopeIdToSet []string
if opts.withGrantScopeId != nil {
// If the value is empty, they're trying to clear it (e.g. a
// null field), which is represented by an empty slice in
// SetRoleGrantScopes
grantScopeIdToSet = make([]string, 0, 1)
if *opts.withGrantScopeId != "" {
grantScopeIdToSet = append(grantScopeIdToSet, *opts.withGrantScopeId)
}
}
var dbMask, nullFields []string
dbMask, nullFields = dbw.BuildUpdatePaths(
map[string]any{
@@ -133,9 +109,11 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32,
fieldMaskPaths,
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 && grantScopeIdToSet == nil {
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, nil, nil, nil, db.NoRowsAffected, errors.E(ctx, errors.WithCode(errors.EmptyFieldMask), errors.WithOp(op))
}
var resource Resource
var rowsUpdated int
var pr []*PrincipalRole
@@ -156,12 +134,7 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, version uint32,
}
version = resource.(*Role).Version
}
if grantScopeIdToSet != nil {
_, _, err = r.SetRoleGrantScopes(ctx, role.PublicId, version, grantScopeIdToSet, WithReaderWriter(read, w))
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("while setting grant scopes"))
}
}
// Do a fresh lookup since version may have gone up by 1 or 2 based
// on grant scope id
resource, pr, rg, grantScopes, err = r.LookupRole(ctx, role.PublicId, WithReaderWriter(read, w))
+1 -1
View File
@@ -429,7 +429,7 @@ func TestRepository_UpdateRole(t *testing.T) {
roleAfterUpdate, principals, grants, _, updatedRows, err := repo.UpdateRole(context.Background(), &updateRole, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
if tt.wantErr {
assert.Error(err)
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsError), err))
assert.Nil(roleAfterUpdate)
assert.Equal(0, updatedRows)
+1 -13
View File
@@ -192,9 +192,6 @@ func TestUser(t testing.TB, repo *Repository, scopeId string, opt ...Option) *Us
func TestRole(t testing.TB, conn *db.DB, scopeId string, opt ...Option) *Role {
t.Helper()
opts := getOpts(opt...)
if opts.withGrantScopeId != nil && *opts.withGrantScopeId != "" && len(opts.withGrantScopeIds) > 0 {
require.FailNow(t, "cannot specify both withGrantScopeId and withGrantScopeIds")
}
ctx := context.Background()
require := require.New(t)
@@ -210,16 +207,7 @@ func TestRole(t testing.TB, conn *db.DB, scopeId string, opt ...Option) *Role {
grantScopeIds := opts.withGrantScopeIds
if len(grantScopeIds) == 0 {
var scpId string
switch {
case opts.withGrantScopeId == nil:
scpId = globals.GrantScopeThis
case *opts.withGrantScopeId == "":
scpId = globals.GrantScopeThis
default:
scpId = *opts.withGrantScopeId
}
grantScopeIds = []string{scpId}
grantScopeIds = []string{globals.GrantScopeThis}
}
for _, gsi := range grantScopeIds {
if gsi == "testing-none" {
@@ -51,6 +51,10 @@ message Grant {
// Role contains all fields related to a Role resource
message Role {
// Used to be "grant_scope_id", replaced with "grant_scope_ids".
reserved 90;
reserved "grant_scope_id";
// Output only. The ID of the Role.
string id = 10; // @gotags: `class:"public" eventstream:"observation"`
@@ -88,18 +92,6 @@ message Role {
// The mutation will fail if the version does not match the latest known good version.
uint32 version = 80; // @gotags: `class:"public"`
// The Scope the grants will apply to. If the Role is at the global scope,
// this can be an org or project. If the Role is at an org scope, this can be
// a project within the org. It is invalid for this to be anything other than
// the Role's scope when the Role's scope is a project.
//
// Deprecated: Use "grant_scope_ids" instead.
google.protobuf.StringValue grant_scope_id = 90 [
json_name = "grant_scope_id",
deprecated = true,
(custom_options.v1.generate_sdk_option) = true
]; // @gotags: `class:"public" eventstream:"observation"`
// Output only. The IDs of Scopes the grants will apply to. This can include
// the role's own scope ID, or "this" for the same behavior; specific IDs of
// scopes that are children of the role's scope; the value "children" to match
+10 -12
View File
@@ -48,12 +48,11 @@ func TestRoles(t *testing.T) {
Description: "scope-description",
ParentScopeId: "scope-parent-scope-id",
},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "description"},
CreatedTime: pbNow,
UpdatedTime: pbNow,
Version: 0,
GrantScopeId: &wrapperspb.StringValue{Value: "grant-scope-id"},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "description"},
CreatedTime: pbNow,
UpdatedTime: pbNow,
Version: 0,
GrantScopeIds: []string{
globals.GrantScopeThis,
"grant-scope-id",
@@ -98,12 +97,11 @@ func TestRoles(t *testing.T) {
Description: "scope-description",
ParentScopeId: "scope-parent-scope-id",
},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "description"},
CreatedTime: pbNow,
UpdatedTime: pbNow,
Version: 0,
GrantScopeId: &wrapperspb.StringValue{Value: "grant-scope-id"},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "description"},
CreatedTime: pbNow,
UpdatedTime: pbNow,
Version: 0,
GrantScopeIds: []string{
globals.GrantScopeThis,
"grant-scope-id",
+10 -2
View File
@@ -6,12 +6,20 @@ load _authorized_actions
function create_role() {
local sid=$1
local name=$2
local gsid=$3
boundary roles create \
-scope-id $sid \
-name $name \
-description 'test role' \
-description 'test role'
}
function set_grant_scopes() {
local sid=$1
local name=$2
local gsid=$3
boundary roles set-grant-scopes \
-id $(role_id $name $sid) \
-grant-scope-id $gsid
}
+6 -2
View File
@@ -15,13 +15,17 @@ export NEW_GRANT='ids=*;type=*;actions=create,read,update,delete,list'
}
@test "boundary/roles: can add $NEW_ROLE role to global scope granting rights in default org scope" {
run create_role $DEFAULT_GLOBAL $NEW_ROLE $DEFAULT_O_ID
run create_role $DEFAULT_GLOBAL $NEW_ROLE
echo "$output"
[ "$status" -eq 0 ]
run set_grant_scopes $DEFAULT_GLOBAL $NEW_ROLE $DEFAULT_O_ID
echo "$output"
[ "$status" -eq 0 ]
}
@test "boundary/roles: can not add already created $NEW_ROLE role" {
run create_role $DEFAULT_GLOBAL $NEW_ROLE $DEFAULT_O_ID
run create_role $DEFAULT_GLOBAL $NEW_ROLE
echo "$output"
[ "$status" -eq 1 ]
}
@@ -261,15 +261,6 @@ type Role struct {
// Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.
// The mutation will fail if the version does not match the latest known good version.
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
// The Scope the grants will apply to. If the Role is at the global scope,
// this can be an org or project. If the Role is at an org scope, this can be
// a project within the org. It is invalid for this to be anything other than
// the Role's scope when the Role's scope is a project.
//
// Deprecated: Use "grant_scope_ids" instead.
//
// Deprecated: Marked as deprecated in controller/api/resources/roles/v1/role.proto.
GrantScopeId *wrapperspb.StringValue `protobuf:"bytes,90,opt,name=grant_scope_id,proto3" json:"grant_scope_id,omitempty" class:"public" eventstream:"observation"` // @gotags: `class:"public" eventstream:"observation"`
// Output only. The IDs of Scopes the grants will apply to. This can include
// the role's own scope ID, or "this" for the same behavior; specific IDs of
// scopes that are children of the role's scope; the value "children" to match
@@ -378,14 +369,6 @@ func (x *Role) GetVersion() uint32 {
return 0
}
// Deprecated: Marked as deprecated in controller/api/resources/roles/v1/role.proto.
func (x *Role) GetGrantScopeId() *wrapperspb.StringValue {
if x != nil {
return x.GrantScopeId
}
return nil
}
func (x *Role) GetGrantScopeIds() []string {
if x != nil {
return x.GrantScopeIds
@@ -464,7 +447,7 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{
0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72,
0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4a, 0x73, 0x6f,
0x6e, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0xc3, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65,
0x6e, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x8b, 0x06, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05,
@@ -492,37 +475,33 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a,
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74,
0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0xa0,
0xda, 0x29, 0x01, 0x18, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73,
0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x5b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x12,
0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73,
0x18, 0x64, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
0x6c, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
0x61, 0x6c, 0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72,
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
0x61, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x73, 0x18, 0x78, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x6e,
0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x67, 0x72, 0x61,
0x6e, 0x74, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x12,
0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x4c, 0x5a,
0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73,
0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f,
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74,
0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x5b, 0x20, 0x03, 0x28, 0x09,
0x52, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64,
0x73, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69,
0x64, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69,
0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63,
0x69, 0x70, 0x61, 0x6c, 0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63,
0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x78, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x67, 0x72,
0x61, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x41, 0x0a, 0x06, 0x67,
0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2f,
0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4a,
0x04, 0x08, 0x5a, 0x10, 0x5b, 0x52, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f,
0x70, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f,
0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -554,14 +533,13 @@ var file_controller_api_resources_roles_v1_role_proto_depIdxs = []int32{
5, // 3: controller.api.resources.roles.v1.Role.description:type_name -> google.protobuf.StringValue
6, // 4: controller.api.resources.roles.v1.Role.created_time:type_name -> google.protobuf.Timestamp
6, // 5: controller.api.resources.roles.v1.Role.updated_time:type_name -> google.protobuf.Timestamp
5, // 6: controller.api.resources.roles.v1.Role.grant_scope_id:type_name -> google.protobuf.StringValue
0, // 7: controller.api.resources.roles.v1.Role.principals:type_name -> controller.api.resources.roles.v1.Principal
2, // 8: controller.api.resources.roles.v1.Role.grants:type_name -> controller.api.resources.roles.v1.Grant
9, // [9:9] is the sub-list for method output_type
9, // [9:9] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
0, // 6: controller.api.resources.roles.v1.Role.principals:type_name -> controller.api.resources.roles.v1.Principal
2, // 7: controller.api.resources.roles.v1.Role.grants:type_name -> controller.api.resources.roles.v1.Grant
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_controller_api_resources_roles_v1_role_proto_init() }
@@ -32,12 +32,9 @@ $ boundary roles create [options] [args]
### Command options
- `-description=<string>` - The description to assign to the role.
- `-grant-scope-id=<string>` - The scope ID for any grants set on the role.
The `grant-scope-id` field is now deprecated in favor of multiple grant scope support using [add-grant-scopes](/boundary/docs/commands/roles/add-grant-scopes).
For more information, refer to [Version 0.15.0 feature deprecations and EOL](/boundary/docs/release-notes/v0_15_0#feature-deprecations-and-eol).
- `-name=<string>` - The name to assign to the role.
- `-scope-id=<string>` - The scope in which you want to create the role.
The default is `global`.
You can also specify the scope using the **BOUNDARY_SCOPE_ID** environment variable.
@include 'cmd-option-note.mdx'
@include 'cmd-option-note.mdx'
@@ -32,12 +32,9 @@ $ boundary roles update [options] [args]
### Command options
- `-description=<string>` - The description to set on the role.
- `-grant-scope-id=<string>` - The scope ID for any grants set on the role.
The `grant-scope-id` field is now deprecated in favor of multiple grant scope support using [add-grant-scopes](/boundary/docs/commands/roles/add-grant-scopes).
For more information, refer to [Version 0.15.0 feature deprecations and EOL](/boundary/docs/release-notes/v0_15_0#feature-deprecations-and-eol).
- `-id=<string>` - The ID of the role you want to update.
- `-name=<string>` - The name to set on the role.
- `-version=<int>` - The version of the role you want to update.
If you do not specify a version, the command performs a check-and-set automatically.
@include 'cmd-option-note.mdx'
@include 'cmd-option-note.mdx'
@@ -378,7 +378,10 @@ Assumes recovery key export from above steps is still set:
```shell-session
$ boundary roles create -name 'org_admin' \
-recovery-config /tmp/recovery.hcl \
-scope-id 'global' \
-scope-id 'global'
$ boundary roles set-grant-scopes \
-id <org_admin_id> \
-grant-scope-id <org_scope_id>
$ boundary roles add-grants -id <org_admin_id> \
@@ -397,7 +400,7 @@ $ boundary roles add-principals -id <org_admin_id> \
```hcl
resource "boundary_role" "org_admin" {
scope_id = "global"
grant_scope_id = boundary_scope.org.id
grant_scope_ids = [boundary_scope.org.id]
grant_strings = [
"ids=*;type=*;actions=*"
]
@@ -438,8 +441,8 @@ $ boundary roles add-principals -id <project_admin_id> \
```hcl
resource "boundary_role" "project_admin" {
scope_id = boundary_scope.org.id
grant_scope_id = boundary_scope.project.id
scope_id = boundary_scope.org.id
grant_scope_ids = [boundary_scope.project.id]
grant_strings = [
"ids=*;type=*;actions=*"
]