Scopes type field and types in updates allowed (#335)
This commit is contained in:
1 parent
c3ecea172d
commit
99d5456d7a
16 files changed
+309
-42
No files matched your search
@@ -22,6 +22,7 @@ type Scope struct {
|
||||
CreatedTime time.Time `json:"created_time,omitempty"`
|
||||
UpdatedTime time.Time `json:"updated_time,omitempty"`
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Client is a client for this collection
|
||||
|
||||
@@ -4686,6 +4686,10 @@
|
||||
"format": "int64",
|
||||
"description": "The version can be used in subsequent write requests to ensure this\nresource has not changed and to fail the write if it has.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"title": "The type of the resource"
|
||||
}
|
||||
},
|
||||
"title": "Scope contains all fields related to a Scope resource"
|
||||
|
||||
@@ -145,6 +145,8 @@ type Scope struct {
|
||||
// resource has not changed and to fail the write if it has.
|
||||
// Output only.
|
||||
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// The type of the resource
|
||||
Type string `protobuf:"bytes,90,opt,name=type,proto3" json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Scope) Reset() {
|
||||
@@ -235,6 +237,13 @@ func (x *Scope) GetVersion() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Scope) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_controller_api_resources_scopes_v1_scope_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
|
||||
@@ -259,7 +268,7 @@ var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x72,
|
||||
0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x5f, 0x69, 0x64, 0x22, 0xbe, 0x03, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x0e, 0x0a,
|
||||
0x5f, 0x69, 0x64, 0x22, 0xd2, 0x03, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 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, 0x73, 0x63, 0x6f,
|
||||
@@ -287,13 +296,14 @@ var file_controller_api_resources_scopes_v1_scope_proto_rawDesc = []byte{
|
||||
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, 0x42, 0x53, 0x5a, 0x51, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67,
|
||||
0x65, 0x6e, 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, 0x73, 0x63, 0x6f, 0x70,
|
||||
0x65, 0x73, 0x3b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x5a, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x42, 0x53, 0x5a, 0x51, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 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,
|
||||
0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x3b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -61,4 +61,7 @@ message Scope {
|
||||
// resource has not changed and to fail the write if it has.
|
||||
// Output only.
|
||||
uint32 version = 80;
|
||||
|
||||
// The type of the resource
|
||||
string type = 90;
|
||||
}
|
||||
@@ -419,7 +419,20 @@ func validateCreateRequest(req *pbs.CreateAccountRequest) error {
|
||||
}
|
||||
|
||||
func validateUpdateRequest(req *pbs.UpdateAccountRequest) error {
|
||||
return handlers.ValidateUpdateRequest(password.AccountPrefix, req, req.GetItem(), handlers.NoopValidatorFn)
|
||||
return handlers.ValidateUpdateRequest(password.AccountPrefix, req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
switch auth.SubtypeFromId(req.GetId()) {
|
||||
case auth.PasswordSubtype:
|
||||
if req.GetItem().GetType() != "" && req.GetItem().GetType() != auth.PasswordSubtype.String() {
|
||||
badFields["type"] = "Cannot modify resource type."
|
||||
}
|
||||
pwAttrs := &pb.PasswordAccountAttributes{}
|
||||
if err := handlers.StructToProto(req.GetItem().GetAttributes(), pwAttrs); err != nil {
|
||||
badFields["attributes"] = "Attribute fields do not match the expected format."
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
}
|
||||
|
||||
func validateDeleteRequest(req *pbs.DeleteAccountRequest) error {
|
||||
|
||||
@@ -517,6 +517,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.Account{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: "password",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateAccountResponse{
|
||||
@@ -540,6 +541,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.Account{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: "password",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateAccountResponse{
|
||||
@@ -565,6 +567,19 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Cant change type",
|
||||
req: &pbs.UpdateAccountRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name"},
|
||||
},
|
||||
Item: &pb.Account{
|
||||
Name: &wrapperspb.StringValue{Value: ""},
|
||||
Type: "oidc",
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "No Paths in Mask",
|
||||
req: &pbs.UpdateAccountRequest{
|
||||
|
||||
@@ -362,8 +362,17 @@ func validateCreateRequest(req *pbs.CreateAuthMethodRequest) error {
|
||||
func validateUpdateRequest(req *pbs.UpdateAuthMethodRequest) error {
|
||||
return handlers.ValidateUpdateRequest(password.AuthMethodPrefix, req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
if req.GetItem().GetType() != "" {
|
||||
badFields["type"] = "This is a read only field and cannot be specified in an update request."
|
||||
switch auth.SubtypeFromId(req.GetId()) {
|
||||
case auth.PasswordSubtype:
|
||||
if req.GetItem().GetType() != "" && auth.SubtypeFromType(req.GetItem().GetType()) != auth.PasswordSubtype {
|
||||
badFields["type"] = "Cannot modify resource type."
|
||||
}
|
||||
pwAttrs := &pb.PasswordAuthMethodAttributes{}
|
||||
if err := handlers.StructToProto(req.GetItem().GetAttributes(), pwAttrs); err != nil {
|
||||
badFields["attributes"] = "Attribute fields do not match the expected format."
|
||||
}
|
||||
default:
|
||||
badFields["id"] = "Incorrectly formatted identifier."
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
|
||||
@@ -529,6 +529,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.AuthMethod{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: "password",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateAuthMethodResponse{
|
||||
@@ -550,11 +551,12 @@ func TestUpdate(t *testing.T) {
|
||||
name: "Multiple Paths in single string",
|
||||
req: &pbs.UpdateAuthMethodRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name,description"},
|
||||
Paths: []string{"name,description,type"},
|
||||
},
|
||||
Item: &pb.AuthMethod{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: "password",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateAuthMethodResponse{
|
||||
@@ -604,6 +606,17 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Cant change type",
|
||||
req: &pbs.UpdateAuthMethodRequest{
|
||||
UpdateMask: &field_mask.FieldMask{Paths: []string{"name", "type"}},
|
||||
Item: &pb.AuthMethod{
|
||||
Name: &wrapperspb.StringValue{Value: "updated name"},
|
||||
Type: "oidc",
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Unset Name",
|
||||
req: &pbs.UpdateAuthMethodRequest{
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
|
||||
"github.com/hashicorp/boundary/internal/types/action"
|
||||
"github.com/hashicorp/boundary/internal/types/resource"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
@@ -314,6 +315,9 @@ func validateGetRequest(req *pbs.GetHostCatalogRequest) error {
|
||||
func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error {
|
||||
return handlers.ValidateCreateRequest(req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
if !handlers.ValidId(scope.Project.Prefix(), req.GetItem().GetScopeId()) {
|
||||
badFields["scope_id"] = "This field must be a valid project scope id."
|
||||
}
|
||||
switch host.SubtypeFromType(req.GetItem().GetType()) {
|
||||
case host.StaticSubtype:
|
||||
default:
|
||||
@@ -326,8 +330,11 @@ func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error {
|
||||
func validateUpdateRequest(req *pbs.UpdateHostCatalogRequest) error {
|
||||
return handlers.ValidateUpdateRequest(static.HostCatalogPrefix, req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
if req.GetItem().GetType() != "" {
|
||||
badFields["type"] = "This is a read only field and cannot be specified in an update request."
|
||||
switch host.SubtypeFromId(req.GetId()) {
|
||||
case host.StaticSubtype:
|
||||
if req.GetItem().GetType() != "" && host.SubtypeFromType(req.GetItem().GetType()) != host.StaticSubtype {
|
||||
badFields["type"] = "Cannot modify resource type."
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
@@ -339,6 +346,9 @@ func validateDeleteRequest(req *pbs.DeleteHostCatalogRequest) error {
|
||||
|
||||
func validateListRequest(req *pbs.ListHostCatalogsRequest) error {
|
||||
badFields := map[string]string{}
|
||||
if !handlers.ValidId(scope.Project.Prefix(), req.GetScopeId()) {
|
||||
badFields["scope_id"] = "This field must be a valid project scope id."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields)
|
||||
}
|
||||
|
||||
@@ -198,6 +198,11 @@ func TestList(t *testing.T) {
|
||||
scopeId: scope.Project.Prefix() + "_DoesntExis",
|
||||
errCode: codes.PermissionDenied,
|
||||
},
|
||||
{
|
||||
name: "Bad scope level",
|
||||
scopeId: scope.Global.String(),
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@@ -318,6 +323,26 @@ func TestCreate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Cant create in org",
|
||||
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
|
||||
ScopeId: proj.GetParentId(),
|
||||
Name: &wrappers.StringValue{Value: "name"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
}},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Cant create in global",
|
||||
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
|
||||
ScopeId: scope.Global.String(),
|
||||
Name: &wrappers.StringValue{Value: "name"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
}},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Create with unknown type",
|
||||
req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{
|
||||
@@ -433,6 +458,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.HostCatalog{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostCatalogResponse{
|
||||
@@ -457,6 +483,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.HostCatalog{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostCatalogResponse{
|
||||
@@ -596,6 +623,19 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Cant change type",
|
||||
req: &pbs.UpdateHostCatalogRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name", "type"},
|
||||
},
|
||||
Item: &pb.HostCatalog{
|
||||
Name: &wrappers.StringValue{Value: "updated name"},
|
||||
Type: "ec2",
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Update a Non Existing HostCatalog",
|
||||
req: &pbs.UpdateHostCatalogRequest{
|
||||
|
||||
@@ -430,8 +430,11 @@ func validateCreateRequest(req *pbs.CreateHostSetRequest) error {
|
||||
func validateUpdateRequest(req *pbs.UpdateHostSetRequest) error {
|
||||
return handlers.ValidateUpdateRequest(static.HostSetPrefix, req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
if req.GetItem().GetType() != "" {
|
||||
badFields["type"] = "This is a read only field and cannot be specified in an update request."
|
||||
switch host.SubtypeFromId(req.GetId()) {
|
||||
case host.StaticSubtype:
|
||||
if req.GetItem().GetType() != "" && req.GetItem().GetType() != host.StaticSubtype.String() {
|
||||
badFields["type"] = "Cannot modify the resource type."
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
|
||||
@@ -462,11 +462,12 @@ func TestUpdate(t *testing.T) {
|
||||
name: "Update an Existing Host",
|
||||
req: &pbs.UpdateHostSetRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name", "description"},
|
||||
Paths: []string{"name", "description", "type"},
|
||||
},
|
||||
Item: &pb.HostSet{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostSetResponse{
|
||||
@@ -487,11 +488,12 @@ func TestUpdate(t *testing.T) {
|
||||
name: "Multiple Paths in single string",
|
||||
req: &pbs.UpdateHostSetRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name,description"},
|
||||
Paths: []string{"name,description,type"},
|
||||
},
|
||||
Item: &pb.HostSet{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostSetResponse{
|
||||
@@ -508,6 +510,20 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Cant modify type",
|
||||
req: &pbs.UpdateHostSetRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name,type"},
|
||||
},
|
||||
Item: &pb.HostSet{
|
||||
Name: &wrappers.StringValue{Value: "updated name"},
|
||||
Description: &wrappers.StringValue{Value: "updated desc"},
|
||||
Type: "ec2",
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "No Update Mask",
|
||||
req: &pbs.UpdateHostSetRequest{
|
||||
|
||||
@@ -362,13 +362,14 @@ func validateCreateRequest(req *pbs.CreateHostRequest) error {
|
||||
func validateUpdateRequest(req *pbs.UpdateHostRequest) error {
|
||||
return handlers.ValidateUpdateRequest(static.HostPrefix, req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
ct := host.SubtypeFromId(req.GetId())
|
||||
if ct == host.UnknownSubtype {
|
||||
switch host.SubtypeFromId(req.GetId()) {
|
||||
case host.StaticSubtype:
|
||||
if req.GetItem().GetType() != "" && req.GetItem().GetType() != host.StaticSubtype.String() {
|
||||
badFields["type"] = "Cannot modify the resource type."
|
||||
}
|
||||
default:
|
||||
badFields["id"] = "Improperly formatted identifier used."
|
||||
}
|
||||
if req.GetItem().GetType() != "" {
|
||||
badFields["type"] = "This is a read only field and cannot be specified in an update request."
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
}
|
||||
|
||||
@@ -464,11 +464,12 @@ func TestUpdate(t *testing.T) {
|
||||
name: "Update an Existing Host",
|
||||
req: &pbs.UpdateHostRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name", "description"},
|
||||
Paths: []string{"name", "description", "type"},
|
||||
},
|
||||
Item: &pb.Host{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostResponse{
|
||||
@@ -491,11 +492,12 @@ func TestUpdate(t *testing.T) {
|
||||
name: "Multiple Paths in single string",
|
||||
req: &pbs.UpdateHostRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name,description"},
|
||||
Paths: []string{"name,description,type"},
|
||||
},
|
||||
Item: &pb.Host{
|
||||
Name: &wrappers.StringValue{Value: "new"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateHostResponse{
|
||||
@@ -524,6 +526,19 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "No Update Mask",
|
||||
req: &pbs.UpdateHostRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name,type"},
|
||||
},
|
||||
Item: &pb.Host{
|
||||
Name: &wrappers.StringValue{Value: "updated name"},
|
||||
Type: "ec2",
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Empty Path",
|
||||
req: &pbs.UpdateHostRequest{
|
||||
|
||||
@@ -324,6 +324,7 @@ func ToProto(in *iam.Scope) *pb.Scope {
|
||||
CreatedTime: in.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: in.GetUpdateTime().GetTimestamp(),
|
||||
Version: in.GetVersion(),
|
||||
Type: in.GetType(),
|
||||
}
|
||||
if in.GetDescription() != "" {
|
||||
out.Description = &wrapperspb.StringValue{Value: in.GetDescription()}
|
||||
@@ -365,7 +366,19 @@ func validateCreateRequest(req *pbs.CreateScopeRequest) error {
|
||||
badFields := map[string]string{}
|
||||
item := req.GetItem()
|
||||
if item.GetScopeId() == "" {
|
||||
badFields["scope_id"] = "Missing value for scope_id"
|
||||
badFields["scope_id"] = "Missing value for scope_id."
|
||||
}
|
||||
switch item.GetType() {
|
||||
case scope.Global.String():
|
||||
badFields["type"] = "Cannot create a global scope."
|
||||
case scope.Org.String():
|
||||
if !strings.EqualFold(scope.Global.String(), item.GetScopeId()) {
|
||||
badFields["type"] = "Org scopes can only be created under the global scope."
|
||||
}
|
||||
case scope.Project.String():
|
||||
if !handlers.ValidId(scope.Org.Prefix(), item.GetScopeId()) {
|
||||
badFields["type"] = "Project scopes can only be created under an org scope."
|
||||
}
|
||||
}
|
||||
if item.GetId() != "" {
|
||||
badFields["id"] = "This is a read only field."
|
||||
@@ -394,10 +407,16 @@ func validateUpdateRequest(req *pbs.UpdateScopeRequest) error {
|
||||
if !handlers.ValidId(scope.Org.Prefix(), id) {
|
||||
badFields["id"] = "Invalidly formatted scope id."
|
||||
}
|
||||
if req.GetItem().GetType() != "" && !strings.EqualFold(scope.Org.String(), req.GetItem().GetType()) {
|
||||
badFields["type"] = "Cannot modify the resource type."
|
||||
}
|
||||
case strings.HasPrefix(id, scope.Project.Prefix()):
|
||||
if !handlers.ValidId(scope.Project.Prefix(), id) {
|
||||
badFields["id"] = "Invalidly formatted scope id."
|
||||
}
|
||||
if req.GetItem().GetType() != "" && !strings.EqualFold(scope.Project.String(), req.GetItem().GetType()) {
|
||||
badFields["type"] = "Cannot modify the resource type."
|
||||
}
|
||||
default:
|
||||
badFields["id"] = "Invalidly formatted scope id."
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ func TestGet(t *testing.T) {
|
||||
CreatedTime: org.CreateTime.GetTimestamp(),
|
||||
UpdatedTime: org.UpdateTime.GetTimestamp(),
|
||||
Version: 2,
|
||||
Type: scope.Org.String(),
|
||||
}
|
||||
|
||||
pScope := &pb.Scope{
|
||||
@@ -80,6 +81,7 @@ func TestGet(t *testing.T) {
|
||||
CreatedTime: proj.CreateTime.GetTimestamp(),
|
||||
UpdatedTime: proj.UpdateTime.GetTimestamp(),
|
||||
Version: 2,
|
||||
Type: scope.Project.String(),
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
@@ -223,6 +225,7 @@ func TestList(t *testing.T) {
|
||||
CreatedTime: o.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: o.GetUpdateTime().GetTimestamp(),
|
||||
Version: 1,
|
||||
Type: scope.Org.String(),
|
||||
})
|
||||
}
|
||||
wantOrgs = append(wantOrgs, initialOrgs...)
|
||||
@@ -241,6 +244,7 @@ func TestList(t *testing.T) {
|
||||
CreatedTime: p.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: p.GetUpdateTime().GetTimestamp(),
|
||||
Version: 1,
|
||||
Type: scope.Project.String(),
|
||||
})
|
||||
}
|
||||
scopes.SortScopes(wantProjects)
|
||||
@@ -393,22 +397,21 @@ func TestDelete_twice(t *testing.T) {
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
require := require.New(t)
|
||||
defaultOrg, defaultProj, repoFn := createDefaultScopesAndRepo(t)
|
||||
defaultProjCreated, err := ptypes.Timestamp(defaultProj.GetCreateTime().GetTimestamp())
|
||||
require.NoError(err, "Error converting proto to timestamp.")
|
||||
require.NoError(t, err, "Error converting proto to timestamp.")
|
||||
toMerge := &pbs.CreateScopeRequest{}
|
||||
|
||||
repo, err := repoFn()
|
||||
require.NoError(err)
|
||||
require.NoError(t, err)
|
||||
globalUser, err := iam.NewUser(scope.Global.String())
|
||||
require.NoError(err)
|
||||
require.NoError(t, err)
|
||||
globalUser, err = repo.CreateUser(ctx, globalUser)
|
||||
require.NoError(err)
|
||||
require.NoError(t, err)
|
||||
orgUser, err := iam.NewUser(defaultOrg.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NoError(t, err)
|
||||
orgUser, err = repo.CreateUser(ctx, orgUser)
|
||||
require.NoError(err)
|
||||
require.NoError(t, err)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
@@ -435,6 +438,7 @@ func TestCreate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "name"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Version: 1,
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -457,10 +461,79 @@ func TestCreate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "name"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Version: 1,
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Create a valid Project with type specified",
|
||||
scopeId: defaultOrg.GetPublicId(),
|
||||
req: &pbs.CreateScopeRequest{
|
||||
Item: &pb.Scope{
|
||||
ScopeId: defaultOrg.GetPublicId(),
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
res: &pbs.CreateScopeResponse{
|
||||
Uri: "scopes/p_",
|
||||
Item: &pb.Scope{
|
||||
ScopeId: defaultOrg.GetPublicId(),
|
||||
Scope: &pb.ScopeInfo{Id: defaultOrg.GetPublicId(), Type: scope.Org.String()},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Version: 1,
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Create a valid Org with type specified",
|
||||
scopeId: scope.Global.String(),
|
||||
req: &pbs.CreateScopeRequest{
|
||||
Item: &pb.Scope{
|
||||
ScopeId: scope.Global.String(),
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
res: &pbs.CreateScopeResponse{
|
||||
Uri: "scopes/o_",
|
||||
Item: &pb.Scope{
|
||||
ScopeId: scope.Global.String(),
|
||||
Scope: &pb.ScopeInfo{Id: scope.Global.String(), Type: scope.Global.String()},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Version: 1,
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
},
|
||||
{
|
||||
name: "Project with bad type specified",
|
||||
scopeId: defaultOrg.GetPublicId(),
|
||||
req: &pbs.CreateScopeRequest{
|
||||
Item: &pb.Scope{
|
||||
ScopeId: defaultOrg.GetPublicId(),
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Org with bad type specified",
|
||||
scopeId: scope.Global.String(),
|
||||
req: &pbs.CreateScopeRequest{
|
||||
Item: &pb.Scope{
|
||||
ScopeId: scope.Global.String(),
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Can't specify Id",
|
||||
scopeId: defaultOrg.GetPublicId(),
|
||||
@@ -492,6 +565,7 @@ func TestCreate(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
for _, withUserId := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("%s-userid-%t", tc.name, withUserId), func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
var name string
|
||||
if tc.req != nil && tc.req.GetItem() != nil && tc.req.GetItem().GetName() != nil {
|
||||
name = tc.req.GetItem().GetName().GetValue()
|
||||
@@ -500,7 +574,6 @@ func TestCreate(t *testing.T) {
|
||||
tc.res.GetItem().GetName().Value = localName
|
||||
}()
|
||||
}
|
||||
assert := assert.New(t)
|
||||
req := proto.Clone(toMerge).(*pbs.CreateScopeRequest)
|
||||
proto.Merge(req, tc.req)
|
||||
|
||||
@@ -563,10 +636,9 @@ func TestCreate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
require := require.New(t)
|
||||
org, proj, repoFn := createDefaultScopesAndRepo(t)
|
||||
tested, err := scopes.NewService(repoFn)
|
||||
require.NoError(err, "Error when getting new project service.")
|
||||
require.NoError(t, err, "Error when getting new project service.")
|
||||
|
||||
var orgVersion uint32 = 2
|
||||
var projVersion uint32 = 2
|
||||
@@ -574,23 +646,23 @@ func TestUpdate(t *testing.T) {
|
||||
resetOrg := func() {
|
||||
orgVersion++
|
||||
repo, err := repoFn()
|
||||
require.NoError(err, "Couldn't get a new repo")
|
||||
require.NoError(t, err, "Couldn't get a new repo")
|
||||
org, _, err = repo.UpdateScope(context.Background(), org, orgVersion, []string{"Name", "Description"})
|
||||
require.NoError(err, "Failed to reset the org")
|
||||
require.NoError(t, err, "Failed to reset the org")
|
||||
orgVersion++
|
||||
}
|
||||
|
||||
resetProject := func() {
|
||||
projVersion++
|
||||
repo, err := repoFn()
|
||||
require.NoError(err, "Couldn't get a new repo")
|
||||
require.NoError(t, err, "Couldn't get a new repo")
|
||||
proj, _, err = repo.UpdateScope(context.Background(), proj, projVersion, []string{"Name", "Description"})
|
||||
require.NoError(err, "Failed to reset the project")
|
||||
require.NoError(t, err, "Failed to reset the project")
|
||||
projVersion++
|
||||
}
|
||||
|
||||
projCreated, err := ptypes.Timestamp(proj.GetCreateTime().GetTimestamp())
|
||||
require.NoError(err, "Error converting proto to timestamp")
|
||||
require.NoError(t, err, "Error converting proto to timestamp")
|
||||
projToMerge := &pbs.UpdateScopeRequest{
|
||||
Id: proj.GetPublicId(),
|
||||
}
|
||||
@@ -616,6 +688,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.Scope{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateScopeResponse{
|
||||
@@ -626,6 +699,7 @@ func TestUpdate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -640,6 +714,7 @@ func TestUpdate(t *testing.T) {
|
||||
Item: &pb.Scope{
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
res: &pbs.UpdateScopeResponse{
|
||||
@@ -650,6 +725,7 @@ func TestUpdate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
CreatedTime: org.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -674,6 +750,7 @@ func TestUpdate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "new"},
|
||||
Description: &wrapperspb.StringValue{Value: "desc"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -689,6 +766,20 @@ func TestUpdate(t *testing.T) {
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "Cant modify type",
|
||||
scopeId: org.GetPublicId(),
|
||||
req: &pbs.UpdateScopeRequest{
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"name", "type"},
|
||||
},
|
||||
Item: &pb.Scope{
|
||||
Name: &wrapperspb.StringValue{Value: "updated name"},
|
||||
Type: scope.Org.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
},
|
||||
{
|
||||
name: "No Paths in Mask",
|
||||
scopeId: org.GetPublicId(),
|
||||
@@ -731,6 +822,7 @@ func TestUpdate(t *testing.T) {
|
||||
Scope: &pb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String()},
|
||||
Description: &wrapperspb.StringValue{Value: "defaultProj"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -753,6 +845,7 @@ func TestUpdate(t *testing.T) {
|
||||
Scope: &pb.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String()},
|
||||
Name: &wrappers.StringValue{Value: "defaultProj"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -777,6 +870,7 @@ func TestUpdate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "updated"},
|
||||
Description: &wrapperspb.StringValue{Value: "defaultProj"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -801,6 +895,7 @@ func TestUpdate(t *testing.T) {
|
||||
Name: &wrapperspb.StringValue{Value: "defaultProj"},
|
||||
Description: &wrapperspb.StringValue{Value: "notignored"},
|
||||
CreatedTime: proj.GetCreateTime().GetTimestamp(),
|
||||
Type: scope.Project.String(),
|
||||
},
|
||||
},
|
||||
errCode: codes.OK,
|
||||
@@ -874,7 +969,7 @@ func TestUpdate(t *testing.T) {
|
||||
}
|
||||
tc.req.Item.Version = ver
|
||||
|
||||
assert := assert.New(t)
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
var req *pbs.UpdateScopeRequest
|
||||
switch tc.scopeId {
|
||||
case scope.Global.String():
|
||||
|
||||
Reference in new issue
Block a user