From 5b1e4a680d15dca21913109043319c2ea133969e Mon Sep 17 00:00:00 2001 From: Todd Knight Date: Mon, 22 Jun 2020 06:56:27 -0700 Subject: [PATCH] Create Role CUDLR API and SDK (#135) * Implement the Role CRUD API. * Implement the Role List API. * Adding Roles SDK. --- api/internal/genapi/create.go | 5 + api/internal/genapi/delete.go | 5 + api/internal/genapi/input.go | 11 + api/internal/genapi/read.go | 5 + api/internal/genapi/update.go | 5 + api/roles/role.gen.go | 53 + api/roles/role_test.go | 98 ++ api/scopes/create.gen.go | 39 + api/scopes/delete.gen.go | 45 + api/scopes/read.gen.go | 42 + api/scopes/update.gen.go | 42 + internal/gen/controller.swagger.json | 248 ++++ .../controller/api/resources/roles/role.pb.go | 237 ++++ .../api/services/role_service.pb.go | 1186 +++++++++++++++++ .../api/services/role_service.pb.gw.go | 770 +++++++++++ .../api/resources/roles/v1/role.proto | 32 + .../api/services/v1/role_service.proto | 138 ++ internal/servers/controller/handler.go | 8 + .../handlers/roles/roles_service.go | 354 +++++ .../handlers/roles/roles_service_test.go | 605 +++++++++ 20 files changed, 3928 insertions(+) create mode 100644 api/roles/role.gen.go create mode 100644 api/roles/role_test.go create mode 100644 internal/gen/controller/api/resources/roles/role.pb.go create mode 100644 internal/gen/controller/api/services/role_service.pb.go create mode 100644 internal/gen/controller/api/services/role_service.pb.gw.go create mode 100644 internal/proto/local/controller/api/resources/roles/v1/role.proto create mode 100644 internal/proto/local/controller/api/services/v1/role_service.proto create mode 100644 internal/servers/controller/handlers/roles/roles_service.go create mode 100644 internal/servers/controller/handlers/roles/roles_service_test.go diff --git a/api/internal/genapi/create.go b/api/internal/genapi/create.go index 479aa7cd1..7f68ebc6f 100644 --- a/api/internal/genapi/create.go +++ b/api/internal/genapi/create.go @@ -39,6 +39,11 @@ var createFuncs = map[string][]*createInfo{ targetType: "groups.Group", path: `"groups"`, }, + { + baseType: "Organization", + targetType: "roles.Role", + path: `"roles"`, + }, { baseType: "Organization", targetType: "users.User", diff --git a/api/internal/genapi/delete.go b/api/internal/genapi/delete.go index 11b2fe6b2..22be22499 100644 --- a/api/internal/genapi/delete.go +++ b/api/internal/genapi/delete.go @@ -27,6 +27,11 @@ var deleteFuncs = map[string][]*deleteInfo{ "groups.Group", "groups", }, + { + "Organization", + "roles.Role", + "roles", + }, { "Organization", "users.User", diff --git a/api/internal/genapi/input.go b/api/internal/genapi/input.go index 8d8c3f1a9..ce6b9d112 100644 --- a/api/internal/genapi/input.go +++ b/api/internal/genapi/input.go @@ -125,6 +125,17 @@ var inputStructs = []*structInfo{ "", templateTypeResource, }, + { + os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/roles/role.pb.go", + "Role", + os.Getenv("GEN_BASEPATH") + "/api/roles/role.gen.go", + "Role", + "roles", + "", + "", + "", + templateTypeResource, + }, { os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go", "StaticHostCatalogDetails", diff --git a/api/internal/genapi/read.go b/api/internal/genapi/read.go index b2842614b..b326d454c 100644 --- a/api/internal/genapi/read.go +++ b/api/internal/genapi/read.go @@ -27,6 +27,11 @@ var readFuncs = map[string][]*readInfo{ targetType: "groups.Group", path: "groups", }, + { + baseType: "Organization", + targetType: "roles.Role", + path: "roles", + }, { baseType: "Organization", targetType: "users.User", diff --git a/api/internal/genapi/update.go b/api/internal/genapi/update.go index 136ca187c..9b751d8b6 100644 --- a/api/internal/genapi/update.go +++ b/api/internal/genapi/update.go @@ -27,6 +27,11 @@ var updateFuncs = map[string][]*updateInfo{ targetType: "groups.Group", path: "groups", }, + { + baseType: "Organization", + targetType: "roles.Role", + path: "roles", + }, { baseType: "Organization", targetType: "users.User", diff --git a/api/roles/role.gen.go b/api/roles/role.gen.go new file mode 100644 index 000000000..4b73efde5 --- /dev/null +++ b/api/roles/role.gen.go @@ -0,0 +1,53 @@ +// Code generated by "make api"; DO NOT EDIT. +package roles + +import ( + "encoding/json" + "time" + + "github.com/fatih/structs" + + "github.com/hashicorp/watchtower/api" + "github.com/hashicorp/watchtower/api/internal/strutil" +) + +type Role struct { + Client *api.Client `json:"-"` + + defaultFields []string + + // The ID of the Role + // Output only. + Id string `json:"id,omitempty"` + // Optional name for identification purposes + Name *string `json:"name,omitempty"` + // Optional user-set description for identification purposes + Description *string `json:"description,omitempty"` + // The time this resource was created + // Output only. + CreatedTime time.Time `json:"created_time,omitempty"` + // The time this resource was last updated. + // Output only. + UpdatedTime time.Time `json:"updated_time,omitempty"` + // Whether the resource is disabled + Disabled *bool `json:"disabled,omitempty"` +} + +func (s *Role) SetDefault(key string) { + s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key) +} + +func (s *Role) UnsetDefault(key string) { + s.defaultFields = strutil.StrListDelete(s.defaultFields, key) +} + +func (s Role) MarshalJSON() ([]byte, error) { + m := structs.Map(s) + if m == nil { + m = make(map[string]interface{}) + } + for _, k := range s.defaultFields { + m[k] = nil + } + return json.Marshal(m) +} diff --git a/api/roles/role_test.go b/api/roles/role_test.go new file mode 100644 index 000000000..8b7a0eb47 --- /dev/null +++ b/api/roles/role_test.go @@ -0,0 +1,98 @@ +package roles_test + +import ( + "net/http" + "testing" + + "github.com/hashicorp/watchtower/api" + "github.com/hashicorp/watchtower/api/roles" + "github.com/hashicorp/watchtower/api/scopes" + "github.com/hashicorp/watchtower/internal/iam" + "github.com/hashicorp/watchtower/internal/servers/controller" + "github.com/stretchr/testify/assert" +) + +func TestRole_Crud(t *testing.T) { + tc := controller.NewTestController(t, nil) + defer tc.Shutdown() + + client := tc.Client() + org := &scopes.Organization{ + Client: client, + } + + checkRole := func(step string, g *roles.Role, apiErr *api.Error, err error, wantedName string) { + assert := assert.New(t) + assert.NoError(err, step) + if !assert.Nil(apiErr, step) && apiErr.Message != nil { + t.Errorf("ApiError message: %q", *apiErr.Message) + } + assert.NotNil(g, "returned no resource", step) + gotName := "" + if g.Name != nil { + gotName = *g.Name + } + assert.Equal(wantedName, gotName, step) + } + + g, apiErr, err := org.CreateRole(tc.Context(), &roles.Role{Name: api.String("foo")}) + checkRole("create", g, apiErr, err, "foo") + + g, apiErr, err = org.ReadRole(tc.Context(), &roles.Role{Id: g.Id}) + checkRole("read", g, apiErr, err, "foo") + + g = &roles.Role{Id: g.Id} + g.Name = api.String("bar") + g, apiErr, err = org.UpdateRole(tc.Context(), g) + checkRole("update", g, apiErr, err, "bar") + + g = &roles.Role{Id: g.Id} + g.SetDefault("name") + g, apiErr, err = org.UpdateRole(tc.Context(), g) + checkRole("update", g, apiErr, err, "") + + existed, apiErr, err := org.DeleteRole(tc.Context(), g) + assert.NoError(t, err) + assert.True(t, existed, "Expected existing user when deleted, but it wasn't.") + + existed, apiErr, err = org.DeleteRole(tc.Context(), g) + assert.NoError(t, err) + assert.False(t, existed, "Expected user to not exist when deleted, but it did.") +} + +func TestRole_Errors(t *testing.T) { + assert := assert.New(t) + tc := controller.NewTestController(t, nil) + defer tc.Shutdown() + ctx := tc.Context() + + client := tc.Client() + org := &scopes.Organization{ + Client: client, + } + + u, apiErr, err := org.CreateRole(ctx, &roles.Role{Name: api.String("first")}) + assert.NoError(err) + assert.Nil(apiErr) + assert.NotNil(u) + + // Create another resource with the same name. + _, apiErr, err = org.CreateRole(ctx, &roles.Role{Name: api.String("first")}) + assert.NoError(err) + assert.NotNil(apiErr) + + _, apiErr, err = org.ReadRole(ctx, &roles.Role{Id: iam.RolePrefix + "_doesntexis"}) + assert.NoError(err) + assert.NotNil(apiErr) + assert.EqualValues(*apiErr.Status, http.StatusNotFound) + + _, apiErr, err = org.ReadRole(ctx, &roles.Role{Id: "invalid id"}) + assert.NoError(err) + assert.NotNil(apiErr) + assert.EqualValues(*apiErr.Status, http.StatusBadRequest) + + _, apiErr, err = org.UpdateRole(ctx, &roles.Role{Id: u.Id}) + assert.NoError(err) + assert.NotNil(apiErr) + assert.EqualValues(*apiErr.Status, http.StatusBadRequest) +} diff --git a/api/scopes/create.gen.go b/api/scopes/create.gen.go index de8a7176f..890efc952 100644 --- a/api/scopes/create.gen.go +++ b/api/scopes/create.gen.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/watchtower/api" "github.com/hashicorp/watchtower/api/groups" "github.com/hashicorp/watchtower/api/hosts" + "github.com/hashicorp/watchtower/api/roles" "github.com/hashicorp/watchtower/api/users" ) @@ -88,6 +89,44 @@ func (s Organization) CreateGroup(ctx context.Context, r *groups.Group) (*groups return target, apiErr, nil } +func (s Organization) CreateRole(ctx context.Context, r *roles.Role) (*roles.Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in Createroles.Role request") + } + if s.Id == "" { + + // Assume the client has been configured with organization already and + // move on + + } else { + // If it's explicitly set here, override anything that might be in the + // client + + ctx = context.WithValue(ctx, "org", s.Id) + + } + + req, err := s.Client.NewRequest(ctx, "POST", "roles", r) + if err != nil { + return nil, nil, fmt.Errorf("error creating Createroles.Role request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during Createroles.Role call: %w", err) + } + + target := new(roles.Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding Createroles.Role repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} + func (s Organization) CreateUser(ctx context.Context, r *users.User) (*users.User, *api.Error, error) { if s.Client == nil { return nil, nil, fmt.Errorf("nil client in Createusers.User request") diff --git a/api/scopes/delete.gen.go b/api/scopes/delete.gen.go index 766cdb333..55f7df7f1 100644 --- a/api/scopes/delete.gen.go +++ b/api/scopes/delete.gen.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/watchtower/api" "github.com/hashicorp/watchtower/api/groups" "github.com/hashicorp/watchtower/api/hosts" + "github.com/hashicorp/watchtower/api/roles" "github.com/hashicorp/watchtower/api/users" ) @@ -99,6 +100,50 @@ func (s Organization) DeleteGroup(ctx context.Context, r *groups.Group) (bool, * return target.Existed, apiErr, nil } +// DeleteRole returns true iff the roles.Role existed when the delete attempt was made. +func (s Organization) DeleteRole(ctx context.Context, r *roles.Role) (bool, *api.Error, error) { + if s.Client == nil { + return false, nil, fmt.Errorf("nil client in DeleteRole request") + } + if s.Id == "" { + + // Assume the client has been configured with organization already and + // move on + + } else { + // If it's explicitly set here, override anything that might be in the + // client + + ctx = context.WithValue(ctx, "org", s.Id) + + } + if r.Id == "" { + return false, nil, fmt.Errorf("empty roles.Role ID field in DeleteRole request") + } + + req, err := s.Client.NewRequest(ctx, "DELETE", fmt.Sprintf("%s/%s", "roles", r.Id), nil) + if err != nil { + return false, nil, fmt.Errorf("error creating DeleteRole request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return false, nil, fmt.Errorf("error performing client request during DeleteRole call: %w", err) + } + + type deleteResponse struct { + Existed bool + } + target := &deleteResponse{} + + apiErr, err := resp.Decode(target) + if err != nil { + return false, nil, fmt.Errorf("error decoding DeleteRole repsonse: %w", err) + } + + return target.Existed, apiErr, nil +} + // DeleteUser returns true iff the users.User existed when the delete attempt was made. func (s Organization) DeleteUser(ctx context.Context, r *users.User) (bool, *api.Error, error) { if s.Client == nil { diff --git a/api/scopes/read.gen.go b/api/scopes/read.gen.go index 537b5f194..e44b9f381 100644 --- a/api/scopes/read.gen.go +++ b/api/scopes/read.gen.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/watchtower/api" "github.com/hashicorp/watchtower/api/groups" "github.com/hashicorp/watchtower/api/hosts" + "github.com/hashicorp/watchtower/api/roles" "github.com/hashicorp/watchtower/api/users" ) @@ -94,6 +95,47 @@ func (s Organization) ReadGroup(ctx context.Context, r *groups.Group) (*groups.G return target, apiErr, nil } +func (s Organization) ReadRole(ctx context.Context, r *roles.Role) (*roles.Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in ReadRole request") + } + if s.Id == "" { + + // Assume the client has been configured with organization already and + // move on + + } else { + // If it's explicitly set here, override anything that might be in the + // client + + ctx = context.WithValue(ctx, "org", s.Id) + + } + if r.Id == "" { + return nil, nil, fmt.Errorf("empty roles.Role ID field in ReadRole request") + } + + req, err := s.Client.NewRequest(ctx, "GET", fmt.Sprintf("%s/%s", "roles", r.Id), r) + if err != nil { + return nil, nil, fmt.Errorf("error creating ReadRole request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during ReadRole call: %w", err) + } + + target := new(roles.Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding ReadRole repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} + func (s Organization) ReadUser(ctx context.Context, r *users.User) (*users.User, *api.Error, error) { if s.Client == nil { return nil, nil, fmt.Errorf("nil client in ReadUser request") diff --git a/api/scopes/update.gen.go b/api/scopes/update.gen.go index b9e996bb9..0d00e4b41 100644 --- a/api/scopes/update.gen.go +++ b/api/scopes/update.gen.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/watchtower/api" "github.com/hashicorp/watchtower/api/groups" "github.com/hashicorp/watchtower/api/hosts" + "github.com/hashicorp/watchtower/api/roles" "github.com/hashicorp/watchtower/api/users" ) @@ -94,6 +95,47 @@ func (s Organization) UpdateGroup(ctx context.Context, r *groups.Group) (*groups return target, apiErr, nil } +func (s Organization) UpdateRole(ctx context.Context, r *roles.Role) (*roles.Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in CreateRole request") + } + if s.Id == "" { + + // Assume the client has been configured with organization already and + // move on + + } else { + // If it's explicitly set here, override anything that might be in the + // client + + ctx = context.WithValue(ctx, "org", s.Id) + + } + + id := r.Id + r.Id = "" + + req, err := s.Client.NewRequest(ctx, "PATCH", fmt.Sprintf("%s/%s", "roles", id), r) + if err != nil { + return nil, nil, fmt.Errorf("error creating CreateRole request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during UpdateRole call: %w", err) + } + + target := new(roles.Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding UpdateRole repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} + func (s Organization) UpdateUser(ctx context.Context, r *users.User) (*users.User, *api.Error, error) { if s.Client == nil { return nil, nil, fmt.Errorf("nil client in CreateUser request") diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index c6bc745bb..2bc5f70e4 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -1791,6 +1791,171 @@ ] } }, + "/v1/orgs/{org_id}/roles": { + "get": { + "summary": "Lists all Roles", + "operationId": "RoleService_ListRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/controller.api.services.v1.ListRolesResponse" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "view", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + }, + "post": { + "summary": "Creates a single Role", + "operationId": "RoleService_CreateRole", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, + "/v1/orgs/{org_id}/roles/{id}": { + "get": { + "summary": "Gets a single Role", + "operationId": "RoleService_GetRole", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "view", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + }, + "delete": { + "summary": "Deletes a Role", + "operationId": "RoleService_DeleteRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/controller.api.services.v1.DeleteRoleResponse" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + }, + "patch": { + "summary": "Updates a Role", + "operationId": "RoleService_UpdateRole", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/users": { "get": { "summary": "Lists all Users", @@ -2136,6 +2301,42 @@ }, "title": "HostSet is a collection of Hosts created and managed by a HostCatalog" }, + "controller.api.resources.roles.v1.Role": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the Role\nOutput only.", + "readOnly": true + }, + "name": { + "type": "string", + "title": "Optional name for identification purposes" + }, + "description": { + "type": "string", + "title": "Optional user-set description for identification purposes" + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "The time this resource was created\nOutput only.", + "readOnly": true + }, + "updated_time": { + "type": "string", + "format": "date-time", + "description": "The time this resource was last updated.\nOutput only.", + "readOnly": true + }, + "disabled": { + "type": "boolean", + "format": "boolean", + "title": "Whether the resource is disabled" + } + }, + "title": "Role contains all fields related to a Role resource" + }, "controller.api.resources.scopes.v1.Organization": { "type": "object", "properties": { @@ -2297,6 +2498,17 @@ } } }, + "controller.api.services.v1.CreateRoleResponse": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.CreateUserResponse": { "type": "object", "properties": { @@ -2353,6 +2565,15 @@ } } }, + "controller.api.services.v1.DeleteRoleResponse": { + "type": "object", + "properties": { + "existed": { + "type": "boolean", + "format": "boolean" + } + } + }, "controller.api.services.v1.DeleteUserResponse": { "type": "object", "properties": { @@ -2410,6 +2631,14 @@ } } }, + "controller.api.services.v1.GetRoleResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.GetUserResponse": { "type": "object", "properties": { @@ -2484,6 +2713,17 @@ } } }, + "controller.api.services.v1.ListRolesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + } + }, "controller.api.services.v1.ListUsersResponse": { "type": "object", "properties": { @@ -2538,6 +2778,14 @@ } } }, + "controller.api.services.v1.UpdateRoleResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.UpdateUserResponse": { "type": "object", "properties": { diff --git a/internal/gen/controller/api/resources/roles/role.pb.go b/internal/gen/controller/api/resources/roles/role.pb.go new file mode 100644 index 000000000..9c864b322 --- /dev/null +++ b/internal/gen/controller/api/resources/roles/role.pb.go @@ -0,0 +1,237 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.24.0 +// protoc v3.12.3 +// source: controller/api/resources/roles/v1/role.proto + +package roles + +import ( + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + wrappers "github.com/golang/protobuf/ptypes/wrappers" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +// Role contains all fields related to a Role resource +type Role struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The ID of the Role + // Output only. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Optional name for identification purposes + Name *wrappers.StringValue `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Optional user-set description for identification purposes + Description *wrappers.StringValue `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // The time this resource was created + // Output only. + CreatedTime *timestamp.Timestamp `protobuf:"bytes,4,opt,name=created_time,proto3" json:"created_time,omitempty"` + // The time this resource was last updated. + // Output only. + UpdatedTime *timestamp.Timestamp `protobuf:"bytes,5,opt,name=updated_time,proto3" json:"updated_time,omitempty"` + // Whether the resource is disabled + Disabled *wrappers.BoolValue `protobuf:"bytes,6,opt,name=disabled,proto3" json:"disabled,omitempty"` +} + +func (x *Role) Reset() { + *x = Role{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Role) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Role) ProtoMessage() {} + +func (x *Role) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Role.ProtoReflect.Descriptor instead. +func (*Role) Descriptor() ([]byte, []int) { + return file_controller_api_resources_roles_v1_role_proto_rawDescGZIP(), []int{0} +} + +func (x *Role) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Role) GetName() *wrappers.StringValue { + if x != nil { + return x.Name + } + return nil +} + +func (x *Role) GetDescription() *wrappers.StringValue { + if x != nil { + return x.Description + } + return nil +} + +func (x *Role) GetCreatedTime() *timestamp.Timestamp { + if x != nil { + return x.CreatedTime + } + return nil +} + +func (x *Role) GetUpdatedTime() *timestamp.Timestamp { + if x != nil { + return x.UpdatedTime + } + return nil +} + +func (x *Role) GetDisabled() *wrappers.BoolValue { + if x != nil { + return x.Disabled + } + return nil +} + +var File_controller_api_resources_roles_v1_role_proto protoreflect.FileDescriptor + +var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{ + 0x0a, 0x2c, 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, + 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, + 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, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xc0, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 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, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 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, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, + 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 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, 0x36, 0x0a, + 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 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, 0x77, 0x61, + 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 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, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_controller_api_resources_roles_v1_role_proto_rawDescOnce sync.Once + file_controller_api_resources_roles_v1_role_proto_rawDescData = file_controller_api_resources_roles_v1_role_proto_rawDesc +) + +func file_controller_api_resources_roles_v1_role_proto_rawDescGZIP() []byte { + file_controller_api_resources_roles_v1_role_proto_rawDescOnce.Do(func() { + file_controller_api_resources_roles_v1_role_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_api_resources_roles_v1_role_proto_rawDescData) + }) + return file_controller_api_resources_roles_v1_role_proto_rawDescData +} + +var file_controller_api_resources_roles_v1_role_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_controller_api_resources_roles_v1_role_proto_goTypes = []interface{}{ + (*Role)(nil), // 0: controller.api.resources.roles.v1.Role + (*wrappers.StringValue)(nil), // 1: google.protobuf.StringValue + (*timestamp.Timestamp)(nil), // 2: google.protobuf.Timestamp + (*wrappers.BoolValue)(nil), // 3: google.protobuf.BoolValue +} +var file_controller_api_resources_roles_v1_role_proto_depIdxs = []int32{ + 1, // 0: controller.api.resources.roles.v1.Role.name:type_name -> google.protobuf.StringValue + 1, // 1: controller.api.resources.roles.v1.Role.description:type_name -> google.protobuf.StringValue + 2, // 2: controller.api.resources.roles.v1.Role.created_time:type_name -> google.protobuf.Timestamp + 2, // 3: controller.api.resources.roles.v1.Role.updated_time:type_name -> google.protobuf.Timestamp + 3, // 4: controller.api.resources.roles.v1.Role.disabled:type_name -> google.protobuf.BoolValue + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_controller_api_resources_roles_v1_role_proto_init() } +func file_controller_api_resources_roles_v1_role_proto_init() { + if File_controller_api_resources_roles_v1_role_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controller_api_resources_roles_v1_role_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Role); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controller_api_resources_roles_v1_role_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_controller_api_resources_roles_v1_role_proto_goTypes, + DependencyIndexes: file_controller_api_resources_roles_v1_role_proto_depIdxs, + MessageInfos: file_controller_api_resources_roles_v1_role_proto_msgTypes, + }.Build() + File_controller_api_resources_roles_v1_role_proto = out.File + file_controller_api_resources_roles_v1_role_proto_rawDesc = nil + file_controller_api_resources_roles_v1_role_proto_goTypes = nil + file_controller_api_resources_roles_v1_role_proto_depIdxs = nil +} diff --git a/internal/gen/controller/api/services/role_service.pb.go b/internal/gen/controller/api/services/role_service.pb.go new file mode 100644 index 000000000..a3c86b2b0 --- /dev/null +++ b/internal/gen/controller/api/services/role_service.pb.go @@ -0,0 +1,1186 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.24.0 +// protoc v3.12.3 +// source: controller/api/services/v1/role_service.proto + +package services + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" + roles "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles" + _ "google.golang.org/genproto/googleapis/api/annotations" + field_mask "google.golang.org/genproto/protobuf/field_mask" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type GetRoleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + View string `protobuf:"bytes,3,opt,name=view,proto3" json:"view,omitempty"` +} + +func (x *GetRoleRequest) Reset() { + *x = GetRoleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoleRequest) ProtoMessage() {} + +func (x *GetRoleRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoleRequest.ProtoReflect.Descriptor instead. +func (*GetRoleRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{0} +} + +func (x *GetRoleRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *GetRoleRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetRoleRequest) GetView() string { + if x != nil { + return x.View + } + return "" +} + +type GetRoleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetRoleResponse) Reset() { + *x = GetRoleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoleResponse) ProtoMessage() {} + +func (x *GetRoleResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoleResponse.ProtoReflect.Descriptor instead. +func (*GetRoleResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetRoleResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type ListRolesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + View string `protobuf:"bytes,2,opt,name=view,proto3" json:"view,omitempty"` +} + +func (x *ListRolesRequest) Reset() { + *x = ListRolesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRolesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesRequest) ProtoMessage() {} + +func (x *ListRolesRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesRequest.ProtoReflect.Descriptor instead. +func (*ListRolesRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ListRolesRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *ListRolesRequest) GetView() string { + if x != nil { + return x.View + } + return "" +} + +type ListRolesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*roles.Role `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *ListRolesResponse) Reset() { + *x = ListRolesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRolesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRolesResponse) ProtoMessage() {} + +func (x *ListRolesResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRolesResponse.ProtoReflect.Descriptor instead. +func (*ListRolesResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{3} +} + +func (x *ListRolesResponse) GetItems() []*roles.Role { + if x != nil { + return x.Items + } + return nil +} + +type CreateRoleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + Item *roles.Role `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *CreateRoleRequest) Reset() { + *x = CreateRoleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateRoleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateRoleRequest) ProtoMessage() {} + +func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateRoleRequest.ProtoReflect.Descriptor instead. +func (*CreateRoleRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateRoleRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *CreateRoleRequest) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type CreateRoleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"` + Item *roles.Role `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *CreateRoleResponse) Reset() { + *x = CreateRoleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateRoleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateRoleResponse) ProtoMessage() {} + +func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateRoleResponse.ProtoReflect.Descriptor instead. +func (*CreateRoleResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateRoleResponse) GetUri() string { + if x != nil { + return x.Uri + } + return "" +} + +func (x *CreateRoleResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type UpdateRoleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Item *roles.Role `protobuf:"bytes,3,opt,name=item,proto3" json:"item,omitempty"` + UpdateMask *field_mask.FieldMask `protobuf:"bytes,4,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` +} + +func (x *UpdateRoleRequest) Reset() { + *x = UpdateRoleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRoleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRoleRequest) ProtoMessage() {} + +func (x *UpdateRoleRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateRoleRequest.ProtoReflect.Descriptor instead. +func (*UpdateRoleRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{6} +} + +func (x *UpdateRoleRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *UpdateRoleRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateRoleRequest) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +func (x *UpdateRoleRequest) GetUpdateMask() *field_mask.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type UpdateRoleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *UpdateRoleResponse) Reset() { + *x = UpdateRoleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRoleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRoleResponse) ProtoMessage() {} + +func (x *UpdateRoleResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateRoleResponse.ProtoReflect.Descriptor instead. +func (*UpdateRoleResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateRoleResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type DeleteRoleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteRoleRequest) Reset() { + *x = DeleteRoleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRoleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRoleRequest) ProtoMessage() {} + +func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRoleRequest.ProtoReflect.Descriptor instead. +func (*DeleteRoleRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteRoleRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *DeleteRoleRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteRoleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Existed bool `protobuf:"varint,1,opt,name=existed,proto3" json:"existed,omitempty"` +} + +func (x *DeleteRoleResponse) Reset() { + *x = DeleteRoleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRoleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRoleResponse) ProtoMessage() {} + +func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRoleResponse.ProtoReflect.Descriptor instead. +func (*DeleteRoleResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteRoleResponse) GetExisted() bool { + if x != nil { + return x.Existed + } + return false +} + +var File_controller_api_services_v1_role_service_proto protoreflect.FileDescriptor + +var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x2c, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, + 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 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, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x76, 0x69, 0x65, 0x77, 0x22, 0x4e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, + 0x69, 0x74, 0x65, 0x6d, 0x22, 0x3d, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, + 0x69, 0x65, 0x77, 0x22, 0x52, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, + 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x67, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, + 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, + 0x67, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x22, 0x63, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb4, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, + 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, + 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, + 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, + 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x51, 0x0a, 0x12, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 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, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, + 0x3a, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x32, 0xe4, 0x06, 0x0a, 0x0b, + 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa5, 0x01, 0x0a, 0x07, + 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, + 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x14, 0x12, + 0x12, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, + 0x6f, 0x6c, 0x65, 0x12, 0x9d, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, + 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x92, + 0x41, 0x11, 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x52, 0x6f, + 0x6c, 0x65, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, + 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x45, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x6f, + 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, + 0x17, 0x12, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xb0, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x32, 0x1c, + 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, + 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x10, 0x12, 0x0e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xa4, 0x01, 0x0a, 0x0a, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1e, 0x2a, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92, + 0x41, 0x10, 0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f, + 0x6c, 0x65, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, + 0x74, 0x6f, 0x77, 0x65, 0x72, 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, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_controller_api_services_v1_role_service_proto_rawDescOnce sync.Once + file_controller_api_services_v1_role_service_proto_rawDescData = file_controller_api_services_v1_role_service_proto_rawDesc +) + +func file_controller_api_services_v1_role_service_proto_rawDescGZIP() []byte { + file_controller_api_services_v1_role_service_proto_rawDescOnce.Do(func() { + file_controller_api_services_v1_role_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_api_services_v1_role_service_proto_rawDescData) + }) + return file_controller_api_services_v1_role_service_proto_rawDescData +} + +var file_controller_api_services_v1_role_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_controller_api_services_v1_role_service_proto_goTypes = []interface{}{ + (*GetRoleRequest)(nil), // 0: controller.api.services.v1.GetRoleRequest + (*GetRoleResponse)(nil), // 1: controller.api.services.v1.GetRoleResponse + (*ListRolesRequest)(nil), // 2: controller.api.services.v1.ListRolesRequest + (*ListRolesResponse)(nil), // 3: controller.api.services.v1.ListRolesResponse + (*CreateRoleRequest)(nil), // 4: controller.api.services.v1.CreateRoleRequest + (*CreateRoleResponse)(nil), // 5: controller.api.services.v1.CreateRoleResponse + (*UpdateRoleRequest)(nil), // 6: controller.api.services.v1.UpdateRoleRequest + (*UpdateRoleResponse)(nil), // 7: controller.api.services.v1.UpdateRoleResponse + (*DeleteRoleRequest)(nil), // 8: controller.api.services.v1.DeleteRoleRequest + (*DeleteRoleResponse)(nil), // 9: controller.api.services.v1.DeleteRoleResponse + (*roles.Role)(nil), // 10: controller.api.resources.roles.v1.Role + (*field_mask.FieldMask)(nil), // 11: google.protobuf.FieldMask +} +var file_controller_api_services_v1_role_service_proto_depIdxs = []int32{ + 10, // 0: controller.api.services.v1.GetRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 10, // 1: controller.api.services.v1.ListRolesResponse.items:type_name -> controller.api.resources.roles.v1.Role + 10, // 2: controller.api.services.v1.CreateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role + 10, // 3: controller.api.services.v1.CreateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 10, // 4: controller.api.services.v1.UpdateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role + 11, // 5: controller.api.services.v1.UpdateRoleRequest.update_mask:type_name -> google.protobuf.FieldMask + 10, // 6: controller.api.services.v1.UpdateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 0, // 7: controller.api.services.v1.RoleService.GetRole:input_type -> controller.api.services.v1.GetRoleRequest + 2, // 8: controller.api.services.v1.RoleService.ListRoles:input_type -> controller.api.services.v1.ListRolesRequest + 4, // 9: controller.api.services.v1.RoleService.CreateRole:input_type -> controller.api.services.v1.CreateRoleRequest + 6, // 10: controller.api.services.v1.RoleService.UpdateRole:input_type -> controller.api.services.v1.UpdateRoleRequest + 8, // 11: controller.api.services.v1.RoleService.DeleteRole:input_type -> controller.api.services.v1.DeleteRoleRequest + 1, // 12: controller.api.services.v1.RoleService.GetRole:output_type -> controller.api.services.v1.GetRoleResponse + 3, // 13: controller.api.services.v1.RoleService.ListRoles:output_type -> controller.api.services.v1.ListRolesResponse + 5, // 14: controller.api.services.v1.RoleService.CreateRole:output_type -> controller.api.services.v1.CreateRoleResponse + 7, // 15: controller.api.services.v1.RoleService.UpdateRole:output_type -> controller.api.services.v1.UpdateRoleResponse + 9, // 16: controller.api.services.v1.RoleService.DeleteRole:output_type -> controller.api.services.v1.DeleteRoleResponse + 12, // [12:17] is the sub-list for method output_type + 7, // [7:12] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_controller_api_services_v1_role_service_proto_init() } +func file_controller_api_services_v1_role_service_proto_init() { + if File_controller_api_services_v1_role_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controller_api_services_v1_role_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRoleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRoleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRolesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRolesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateRoleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateRoleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRoleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRoleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRoleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRoleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controller_api_services_v1_role_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_controller_api_services_v1_role_service_proto_goTypes, + DependencyIndexes: file_controller_api_services_v1_role_service_proto_depIdxs, + MessageInfos: file_controller_api_services_v1_role_service_proto_msgTypes, + }.Build() + File_controller_api_services_v1_role_service_proto = out.File + file_controller_api_services_v1_role_service_proto_rawDesc = nil + file_controller_api_services_v1_role_service_proto_goTypes = nil + file_controller_api_services_v1_role_service_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// RoleServiceClient is the client API for RoleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type RoleServiceClient interface { + // GetRole returns a stored Role if present. The provided request + // must include the org and role id for the role being retrieved. If + // any of those ids are missing, malformed or reference a non existing + // resource an error is returned. + GetRole(ctx context.Context, in *GetRoleRequest, opts ...grpc.CallOption) (*GetRoleResponse, error) + // ListRoles returns a list of stored roles which exist inside the org + // referenced inside the request. The request must include the org id for + // the roles being retrieved. If the org id is missing, malformed, or + // reference a non existing organization, an error is returned. + ListRoles(ctx context.Context, in *ListRolesRequest, opts ...grpc.CallOption) (*ListRolesResponse, error) + // CreateRole creates and stores a role in watchtower. The provided + // request must include the org id in which the role will be created. + // If the org id is missing, malformed or references a non existing + // organization, an error is returned. If a name is provided that is in + // use in another role in the same organization, an error is returned. + CreateRole(ctx context.Context, in *CreateRoleRequest, opts ...grpc.CallOption) (*CreateRoleResponse, error) + // UpdateRole updates an existing role in watchtower. The provided + // role must not have any read only fields set. The update mask must be + // included in the request and contain at least 1 mutable field. To unset + // a field's value, include the field in the update mask and don't set it + // in the provided role. An error is returned if either the organization + // or role ids are missing or reference a non existing resource. An error + // is also returned if the request attempts to update the name to one that is + // already in use in this organization. + UpdateRole(ctx context.Context, in *UpdateRoleRequest, opts ...grpc.CallOption) (*UpdateRoleResponse, error) + // DeleteRole removes a role from Watchtower. If the provided org or role ids + // are malformed or not provided an error is returned. No error is returned + // if either ids reference resources that do not exist as the response itself + // specifies if the resource existed before the DeleteRole request was + // received. + DeleteRole(ctx context.Context, in *DeleteRoleRequest, opts ...grpc.CallOption) (*DeleteRoleResponse, error) +} + +type roleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRoleServiceClient(cc grpc.ClientConnInterface) RoleServiceClient { + return &roleServiceClient{cc} +} + +func (c *roleServiceClient) GetRole(ctx context.Context, in *GetRoleRequest, opts ...grpc.CallOption) (*GetRoleResponse, error) { + out := new(GetRoleResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/GetRole", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) ListRoles(ctx context.Context, in *ListRolesRequest, opts ...grpc.CallOption) (*ListRolesResponse, error) { + out := new(ListRolesResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/ListRoles", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) CreateRole(ctx context.Context, in *CreateRoleRequest, opts ...grpc.CallOption) (*CreateRoleResponse, error) { + out := new(CreateRoleResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/CreateRole", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) UpdateRole(ctx context.Context, in *UpdateRoleRequest, opts ...grpc.CallOption) (*UpdateRoleResponse, error) { + out := new(UpdateRoleResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/UpdateRole", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) DeleteRole(ctx context.Context, in *DeleteRoleRequest, opts ...grpc.CallOption) (*DeleteRoleResponse, error) { + out := new(DeleteRoleResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/DeleteRole", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RoleServiceServer is the server API for RoleService service. +type RoleServiceServer interface { + // GetRole returns a stored Role if present. The provided request + // must include the org and role id for the role being retrieved. If + // any of those ids are missing, malformed or reference a non existing + // resource an error is returned. + GetRole(context.Context, *GetRoleRequest) (*GetRoleResponse, error) + // ListRoles returns a list of stored roles which exist inside the org + // referenced inside the request. The request must include the org id for + // the roles being retrieved. If the org id is missing, malformed, or + // reference a non existing organization, an error is returned. + ListRoles(context.Context, *ListRolesRequest) (*ListRolesResponse, error) + // CreateRole creates and stores a role in watchtower. The provided + // request must include the org id in which the role will be created. + // If the org id is missing, malformed or references a non existing + // organization, an error is returned. If a name is provided that is in + // use in another role in the same organization, an error is returned. + CreateRole(context.Context, *CreateRoleRequest) (*CreateRoleResponse, error) + // UpdateRole updates an existing role in watchtower. The provided + // role must not have any read only fields set. The update mask must be + // included in the request and contain at least 1 mutable field. To unset + // a field's value, include the field in the update mask and don't set it + // in the provided role. An error is returned if either the organization + // or role ids are missing or reference a non existing resource. An error + // is also returned if the request attempts to update the name to one that is + // already in use in this organization. + UpdateRole(context.Context, *UpdateRoleRequest) (*UpdateRoleResponse, error) + // DeleteRole removes a role from Watchtower. If the provided org or role ids + // are malformed or not provided an error is returned. No error is returned + // if either ids reference resources that do not exist as the response itself + // specifies if the resource existed before the DeleteRole request was + // received. + DeleteRole(context.Context, *DeleteRoleRequest) (*DeleteRoleResponse, error) +} + +// UnimplementedRoleServiceServer can be embedded to have forward compatible implementations. +type UnimplementedRoleServiceServer struct { +} + +func (*UnimplementedRoleServiceServer) GetRole(context.Context, *GetRoleRequest) (*GetRoleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRole not implemented") +} +func (*UnimplementedRoleServiceServer) ListRoles(context.Context, *ListRolesRequest) (*ListRolesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListRoles not implemented") +} +func (*UnimplementedRoleServiceServer) CreateRole(context.Context, *CreateRoleRequest) (*CreateRoleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateRole not implemented") +} +func (*UnimplementedRoleServiceServer) UpdateRole(context.Context, *UpdateRoleRequest) (*UpdateRoleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateRole not implemented") +} +func (*UnimplementedRoleServiceServer) DeleteRole(context.Context, *DeleteRoleRequest) (*DeleteRoleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteRole not implemented") +} + +func RegisterRoleServiceServer(s *grpc.Server, srv RoleServiceServer) { + s.RegisterService(&_RoleService_serviceDesc, srv) +} + +func _RoleService_GetRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRoleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).GetRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/GetRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).GetRole(ctx, req.(*GetRoleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_ListRoles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRolesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).ListRoles(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/ListRoles", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).ListRoles(ctx, req.(*ListRolesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_CreateRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateRoleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).CreateRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/CreateRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).CreateRole(ctx, req.(*CreateRoleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_UpdateRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateRoleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).UpdateRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/UpdateRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).UpdateRole(ctx, req.(*UpdateRoleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_DeleteRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRoleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).DeleteRole(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/DeleteRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).DeleteRole(ctx, req.(*DeleteRoleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _RoleService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "controller.api.services.v1.RoleService", + HandlerType: (*RoleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetRole", + Handler: _RoleService_GetRole_Handler, + }, + { + MethodName: "ListRoles", + Handler: _RoleService_ListRoles_Handler, + }, + { + MethodName: "CreateRole", + Handler: _RoleService_CreateRole_Handler, + }, + { + MethodName: "UpdateRole", + Handler: _RoleService_UpdateRole_Handler, + }, + { + MethodName: "DeleteRole", + Handler: _RoleService_DeleteRole_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "controller/api/services/v1/role_service.proto", +} diff --git a/internal/gen/controller/api/services/role_service.pb.gw.go b/internal/gen/controller/api/services/role_service.pb.gw.go new file mode 100644 index 000000000..44b3db2f0 --- /dev/null +++ b/internal/gen/controller/api/services/role_service.pb.gw.go @@ -0,0 +1,770 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: controller/api/services/v1/role_service.proto + +/* +Package services is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package services + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +var ( + filter_RoleService_GetRole_0 = &utilities.DoubleArray{Encoding: map[string]int{"org_id": 0, "id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + +func request_RoleService_GetRole_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_GetRole_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_GetRole_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_GetRole_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetRole(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_RoleService_ListRoles_0 = &utilities.DoubleArray{Encoding: map[string]int{"org_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_RoleService_ListRoles_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListRolesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_ListRoles_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListRoles(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_ListRoles_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListRolesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_ListRoles_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListRoles(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_CreateRole_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateRoleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Item); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + msg, err := client.CreateRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_CreateRole_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateRoleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Item); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + msg, err := server.CreateRole(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_RoleService_UpdateRole_0 = &utilities.DoubleArray{Encoding: map[string]int{"item": 0, "org_id": 1, "id": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} +) + +func request_RoleService_UpdateRole_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateRoleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Item); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + _, md := descriptor.ForMessage(protoReq.Item) + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_UpdateRole_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_UpdateRole_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateRoleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Item); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + _, md := descriptor.ForMessage(protoReq.Item) + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RoleService_UpdateRole_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateRole(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_DeleteRole_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRoleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.DeleteRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_DeleteRole_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRoleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.DeleteRole(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterRoleServiceHandlerServer registers the http handlers for service RoleService to "mux". +// UnaryRPC :call RoleServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +func RegisterRoleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server RoleServiceServer) error { + + mux.Handle("GET", pattern_RoleService_GetRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_GetRole_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_GetRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_GetRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_RoleService_ListRoles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_ListRoles_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_ListRoles_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_CreateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_CreateRole_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_CreateRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_CreateRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_RoleService_UpdateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_UpdateRole_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_UpdateRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_UpdateRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_RoleService_DeleteRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_DeleteRole_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_DeleteRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterRoleServiceHandlerFromEndpoint is same as RegisterRoleServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterRoleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterRoleServiceHandler(ctx, mux, conn) +} + +// RegisterRoleServiceHandler registers the http handlers for service RoleService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterRoleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterRoleServiceHandlerClient(ctx, mux, NewRoleServiceClient(conn)) +} + +// RegisterRoleServiceHandlerClient registers the http handlers for service RoleService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "RoleServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "RoleServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "RoleServiceClient" to call the correct interceptors. +func RegisterRoleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client RoleServiceClient) error { + + mux.Handle("GET", pattern_RoleService_GetRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_GetRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_GetRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_GetRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_RoleService_ListRoles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_ListRoles_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_ListRoles_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_CreateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_CreateRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_CreateRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_CreateRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_RoleService_UpdateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_UpdateRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_UpdateRole_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_UpdateRole_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_RoleService_DeleteRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_DeleteRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_DeleteRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +type response_RoleService_GetRole_0 struct { + proto.Message +} + +func (m response_RoleService_GetRole_0) XXX_ResponseBody() interface{} { + response := m.Message.(*GetRoleResponse) + return response.Item +} + +type response_RoleService_CreateRole_0 struct { + proto.Message +} + +func (m response_RoleService_CreateRole_0) XXX_ResponseBody() interface{} { + response := m.Message.(*CreateRoleResponse) + return response.Item +} + +type response_RoleService_UpdateRole_0 struct { + proto.Message +} + +func (m response_RoleService_UpdateRole_0) XXX_ResponseBody() interface{} { + response := m.Message.(*UpdateRoleResponse) + return response.Item +} + +var ( + pattern_RoleService_GetRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_ListRoles_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1", "orgs", "org_id", "roles"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_CreateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1", "orgs", "org_id", "roles"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_UpdateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_DeleteRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "id"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_RoleService_GetRole_0 = runtime.ForwardResponseMessage + + forward_RoleService_ListRoles_0 = runtime.ForwardResponseMessage + + forward_RoleService_CreateRole_0 = runtime.ForwardResponseMessage + + forward_RoleService_UpdateRole_0 = runtime.ForwardResponseMessage + + forward_RoleService_DeleteRole_0 = runtime.ForwardResponseMessage +) diff --git a/internal/proto/local/controller/api/resources/roles/v1/role.proto b/internal/proto/local/controller/api/resources/roles/v1/role.proto new file mode 100644 index 000000000..e66c4d040 --- /dev/null +++ b/internal/proto/local/controller/api/resources/roles/v1/role.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package controller.api.resources.roles.v1; + +option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles;roles"; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +// Role contains all fields related to a Role resource +message Role { + // The ID of the Role + // Output only. + string id = 1; + + // Optional name for identification purposes + google.protobuf.StringValue name = 2; + + // Optional user-set description for identification purposes + google.protobuf.StringValue description = 3; + + // The time this resource was created + // Output only. + google.protobuf.Timestamp created_time = 4 [json_name="created_time"]; + + // The time this resource was last updated. + // Output only. + google.protobuf.Timestamp updated_time = 5 [json_name="updated_time"]; + + // Whether the resource is disabled + google.protobuf.BoolValue disabled = 6; +} diff --git a/internal/proto/local/controller/api/services/v1/role_service.proto b/internal/proto/local/controller/api/services/v1/role_service.proto new file mode 100644 index 000000000..1ddb0f428 --- /dev/null +++ b/internal/proto/local/controller/api/services/v1/role_service.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; + +package controller.api.services.v1; + +option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api/services;services"; + +import "protoc-gen-swagger/options/annotations.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/field_mask.proto"; +import "controller/api/resources/roles/v1/role.proto"; + +service RoleService { + + // GetRole returns a stored Role if present. The provided request + // must include the org and role id for the role being retrieved. If + // any of those ids are missing, malformed or reference a non existing + // resource an error is returned. + rpc GetRole(GetRoleRequest) returns (GetRoleResponse) { + option (google.api.http) = { + get: "/v1/orgs/{org_id}/roles/{id}" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Gets a single Role" + }; + } + + // ListRoles returns a list of stored roles which exist inside the org + // referenced inside the request. The request must include the org id for + // the roles being retrieved. If the org id is missing, malformed, or + // reference a non existing organization, an error is returned. + rpc ListRoles(ListRolesRequest) returns (ListRolesResponse) { + option (google.api.http) = { + get: "/v1/orgs/{org_id}/roles" + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Lists all Roles" + }; + } + + // CreateRole creates and stores a role in watchtower. The provided + // request must include the org id in which the role will be created. + // If the org id is missing, malformed or references a non existing + // organization, an error is returned. If a name is provided that is in + // use in another role in the same organization, an error is returned. + rpc CreateRole(CreateRoleRequest) returns (CreateRoleResponse) { + option (google.api.http) = { + post: "/v1/orgs/{org_id}/roles" + body: "item" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Creates a single Role" + }; + } + + // UpdateRole updates an existing role in watchtower. The provided + // role must not have any read only fields set. The update mask must be + // included in the request and contain at least 1 mutable field. To unset + // a field's value, include the field in the update mask and don't set it + // in the provided role. An error is returned if either the organization + // or role ids are missing or reference a non existing resource. An error + // is also returned if the request attempts to update the name to one that is + // already in use in this organization. + rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse) { + option (google.api.http) = { + patch: "/v1/orgs/{org_id}/roles/{id}" + body: "item" + response_body: "item" + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Updates a Role" + }; + } + + // DeleteRole removes a role from Watchtower. If the provided org or role ids + // are malformed or not provided an error is returned. No error is returned + // if either ids reference resources that do not exist as the response itself + // specifies if the resource existed before the DeleteRole request was + // received. + rpc DeleteRole(DeleteRoleRequest) returns (DeleteRoleResponse) { + option (google.api.http) = { + delete: "/v1/orgs/{org_id}/roles/{id}" + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Deletes a Role" + }; + } +} + +message GetRoleRequest { + string org_id = 1; + string id = 2; + string view = 3; +} + +message GetRoleResponse { + resources.roles.v1.Role item = 1; +} + +message ListRolesRequest { + string org_id = 1; + string view = 2; +} + +message ListRolesResponse { + repeated resources.roles.v1.Role items = 1; +} + +message CreateRoleRequest { + string org_id = 1; + resources.roles.v1.Role item = 2; +} + +message CreateRoleResponse { + string uri = 1; + resources.roles.v1.Role item = 2; +} + +message UpdateRoleRequest { + string org_id = 1; + string id = 2; + resources.roles.v1.Role item = 3; + google.protobuf.FieldMask update_mask = 4; +} + +message UpdateRoleResponse { + resources.roles.v1.Role item = 1; +} + +message DeleteRoleRequest { + string org_id = 1; + string id = 2; +} + +message DeleteRoleResponse { + bool existed = 1; +} diff --git a/internal/servers/controller/handler.go b/internal/servers/controller/handler.go index 712fbd2cb..c430c64a5 100644 --- a/internal/servers/controller/handler.go +++ b/internal/servers/controller/handler.go @@ -23,6 +23,7 @@ import ( "github.com/hashicorp/watchtower/internal/servers/controller/handlers/hosts" "github.com/hashicorp/watchtower/internal/servers/controller/handlers/organizations" "github.com/hashicorp/watchtower/internal/servers/controller/handlers/projects" + "github.com/hashicorp/watchtower/internal/servers/controller/handlers/roles" "github.com/hashicorp/watchtower/internal/servers/controller/handlers/users" ) @@ -108,6 +109,13 @@ func handleGrpcGateway(c *Controller) (http.Handler, error) { if err := services.RegisterGroupServiceHandlerServer(ctx, mux, gs); err != nil { return nil, fmt.Errorf("failed to register group service handler: %w", err) } + rs, err := roles.NewService(c.IamRepoFn) + if err != nil { + return nil, fmt.Errorf("failed to create role handler service: %w", err) + } + if err := services.RegisterRoleServiceHandlerServer(ctx, mux, rs); err != nil { + return nil, fmt.Errorf("failed to register role service handler: %w", err) + } return mux, nil } diff --git a/internal/servers/controller/handlers/roles/roles_service.go b/internal/servers/controller/handlers/roles/roles_service.go new file mode 100644 index 000000000..2d2bb4c83 --- /dev/null +++ b/internal/servers/controller/handlers/roles/roles_service.go @@ -0,0 +1,354 @@ +package roles + +import ( + "context" + "errors" + "fmt" + "regexp" + "strings" + + "github.com/hashicorp/watchtower/internal/db" + pb "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles" + pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services" + "github.com/hashicorp/watchtower/internal/iam" + "github.com/hashicorp/watchtower/internal/servers/controller/handlers" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +const orgIdFieldName = "org_id" + +var ( + reInvalidID = regexp.MustCompile("[^A-Za-z0-9]") + // TODO(ICU-28): Find a way to auto update these names and enforce the mappings between wire and storage. + wireToStorageMask = map[string]string{ + "name": "Name", + "description": "Description", + } +) + +// Service handles request as described by the pbs.RoleServiceServer interface. +type Service struct { + repoFn func() (*iam.Repository, error) +} + +// NewService returns a role service which handles role related requests to watchtower. +func NewService(repo func() (*iam.Repository, error)) (Service, error) { + if repo == nil { + return Service{}, fmt.Errorf("nil iam repostiroy provided") + } + return Service{repoFn: repo}, nil +} + +var _ pbs.RoleServiceServer = Service{} + +// ListRoles implements the interface pbs.RoleServiceServer. +func (s Service) ListRoles(ctx context.Context, req *pbs.ListRolesRequest) (*pbs.ListRolesResponse, error) { + if err := validateListRequest(req); err != nil { + return nil, err + } + gl, err := s.listFromRepo(ctx, req.GetOrgId()) + if err != nil { + return nil, err + } + return &pbs.ListRolesResponse{Items: gl}, nil +} + +// GetRoles implements the interface pbs.RoleServiceServer. +func (s Service) GetRole(ctx context.Context, req *pbs.GetRoleRequest) (*pbs.GetRoleResponse, error) { + if err := validateGetRequest(req); err != nil { + return nil, err + } + u, err := s.getFromRepo(ctx, req.GetId()) + if err != nil { + return nil, err + } + return &pbs.GetRoleResponse{Item: u}, nil +} + +// CreateRole implements the interface pbs.RoleServiceServer. +func (s Service) CreateRole(ctx context.Context, req *pbs.CreateRoleRequest) (*pbs.CreateRoleResponse, error) { + if err := validateCreateRequest(req); err != nil { + return nil, err + } + r, err := s.createInRepo(ctx, req.GetOrgId(), req.GetItem()) + if err != nil { + return nil, err + } + return &pbs.CreateRoleResponse{Item: r, Uri: fmt.Sprintf("orgs/%s/roles/%s", req.GetOrgId(), r.GetId())}, nil +} + +// UpdateRole implements the interface pbs.RoleServiceServer. +func (s Service) UpdateRole(ctx context.Context, req *pbs.UpdateRoleRequest) (*pbs.UpdateRoleResponse, error) { + if err := validateUpdateRequest(req); err != nil { + return nil, err + } + u, err := s.updateInRepo(ctx, req.GetOrgId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem()) + if err != nil { + return nil, err + } + return &pbs.UpdateRoleResponse{Item: u}, nil +} + +// DeleteRole implements the interface pbs.RoleServiceServer. +func (s Service) DeleteRole(ctx context.Context, req *pbs.DeleteRoleRequest) (*pbs.DeleteRoleResponse, error) { + if err := validateDeleteRequest(req); err != nil { + return nil, err + } + existed, err := s.deleteFromRepo(ctx, req.GetId()) + if err != nil { + return nil, err + } + return &pbs.DeleteRoleResponse{Existed: existed}, nil +} + +func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Role, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + u, err := repo.LookupRole(ctx, id) + if err != nil { + if errors.Is(err, db.ErrRecordNotFound) { + return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) + } + return nil, err + } + if u == nil { + return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) + } + return toProto(u), nil +} + +func (s Service) createInRepo(ctx context.Context, orgId string, item *pb.Role) (*pb.Role, error) { + var opts []iam.Option + if item.GetName() != nil { + opts = append(opts, iam.WithName(item.GetName().GetValue())) + } + if item.GetDescription() != nil { + opts = append(opts, iam.WithDescription(item.GetDescription().GetValue())) + } + u, err := iam.NewRole(orgId, opts...) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to build role for creation: %v.", err) + } + repo, err := s.repoFn() + if err != nil { + return nil, err + } + out, err := repo.CreateRole(ctx, u) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to create role: %v.", err) + } + if out == nil { + return nil, status.Error(codes.Internal, "Unable to create role but no error returned from repository.") + } + return toProto(out), nil +} + +func (s Service) updateInRepo(ctx context.Context, orgId, id string, mask []string, item *pb.Role) (*pb.Role, error) { + var opts []iam.Option + if desc := item.GetDescription(); desc != nil { + opts = append(opts, iam.WithDescription(desc.GetValue())) + } + if name := item.GetName(); name != nil { + opts = append(opts, iam.WithName(name.GetValue())) + } + u, err := iam.NewRole(orgId, opts...) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to build role for update: %v.", err) + } + u.PublicId = id + dbMask, err := toDbUpdateMask(mask) + if err != nil { + return nil, err + } + if len(dbMask) == 0 { + return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid paths provided in the update mask."}) + } + repo, err := s.repoFn() + if err != nil { + return nil, err + } + out, rowsUpdated, err := repo.UpdateRole(ctx, u, dbMask) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to update role: %v.", err) + } + if rowsUpdated == 0 { + return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) + } + return toProto(out), nil +} + +func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) { + repo, err := s.repoFn() + if err != nil { + return false, err + } + rows, err := repo.DeleteRole(ctx, id) + if err != nil { + if errors.Is(err, db.ErrRecordNotFound) { + return false, nil + } + return false, status.Errorf(codes.Internal, "Unable to delete role: %v.", err) + } + return rows > 0, nil +} + +func (s Service) listFromRepo(ctx context.Context, orgId string) ([]*pb.Role, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + rl, err := repo.ListRoles(ctx, orgId) + if err != nil { + return nil, err + } + var outRl []*pb.Role + for _, g := range rl { + outRl = append(outRl, toProto(g)) + } + return outRl, nil +} + +// toDbUpdateMask converts the wire format's FieldMask into a list of strings containing FieldMask paths used +func toDbUpdateMask(paths []string) ([]string, error) { + var dbPaths []string + var invalid []string + for _, p := range paths { + for _, f := range strings.Split(p, ",") { + if dbField, ok := wireToStorageMask[strings.TrimSpace(f)]; ok { + dbPaths = append(dbPaths, dbField) + } else { + invalid = append(invalid, f) + } + } + } + if len(invalid) > 0 { + return nil, handlers.InvalidArgumentErrorf(fmt.Sprintf("Invalid fields passed in update_update mask: %v.", invalid), map[string]string{"update_mask": fmt.Sprintf("Unknown paths provided in update mask: %q", strings.Join(invalid, ","))}) + } + return dbPaths, nil +} + +func toProto(in *iam.Role) *pb.Role { + out := pb.Role{ + Id: in.GetPublicId(), + CreatedTime: in.GetCreateTime().GetTimestamp(), + UpdatedTime: in.GetUpdateTime().GetTimestamp(), + } + if in.GetDescription() != "" { + out.Description = &wrapperspb.StringValue{Value: in.GetDescription()} + } + if in.GetName() != "" { + out.Name = &wrapperspb.StringValue{Value: in.GetName()} + } + return &out +} + +// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce +// requirements on the structure of the request. They verify that: +// * The path passed in is correctly formatted +// * All required parameters are set +// * There are no conflicting parameters provided +func validateGetRequest(req *pbs.GetRoleRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetId(), iam.RolePrefix+"_") { + badFields["id"] = "Invalid formatted role id." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields) + } + return nil +} + +func validateCreateRequest(req *pbs.CreateRoleRequest) error { + badFields := validateAncestors(req) + item := req.GetItem() + if item.GetId() != "" { + badFields["id"] = "This is a read only field." + } + if item.GetCreatedTime() != nil { + badFields["created_time"] = "This is a read only field." + } + if item.GetUpdatedTime() != nil { + badFields["updated_time"] = "This is a read only field." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Argument errors found in the request.", badFields) + } + return nil +} + +func validateUpdateRequest(req *pbs.UpdateRoleRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetId(), iam.RolePrefix+"_") { + badFields["role_id"] = "Improperly formatted path identifier." + } + if req.GetUpdateMask() == nil { + badFields["update_mask"] = "UpdateMask not provided but is required to update a role." + } + + item := req.GetItem() + if item == nil { + // It is legitimate for no item to be specified in an update request as it indicates all fields provided in + // the mask will be marked as unset. + return nil + } + if item.GetId() != "" { + badFields["id"] = "This is a read only field and cannot be specified in an update request." + } + if item.GetCreatedTime() != nil { + badFields["created_time"] = "This is a read only field and cannot be specified in an update request." + } + if item.GetUpdatedTime() != nil { + badFields["updated_time"] = "This is a read only field and cannot be specified in an update request." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + + return nil +} + +func validateDeleteRequest(req *pbs.DeleteRoleRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetId(), iam.RolePrefix+"_") { + badFields["id"] = "Incorrectly formatted identifier." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + return nil +} + +func validateListRequest(req *pbs.ListRolesRequest) error { + badFields := validateAncestors(req) + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields) + } + return nil +} + +func validId(id, prefix string) bool { + if !strings.HasPrefix(id, prefix) { + return false + } + id = strings.TrimPrefix(id, prefix) + return !reInvalidID.Match([]byte(id)) +} + +type ancestorProvider interface { + GetOrgId() string +} + +// validateAncestors verifies that the ancestors of this call are properly set and provided. +func validateAncestors(r ancestorProvider) map[string]string { + if r.GetOrgId() == "" { + return map[string]string{orgIdFieldName: "Missing organization id."} + } + if !validId(r.GetOrgId(), iam.OrganizationScope.Prefix()+"_") { + return map[string]string{orgIdFieldName: "Improperly formatted identifier."} + } + return map[string]string{} +} diff --git a/internal/servers/controller/handlers/roles/roles_service_test.go b/internal/servers/controller/handlers/roles/roles_service_test.go new file mode 100644 index 000000000..7124fbccd --- /dev/null +++ b/internal/servers/controller/handlers/roles/roles_service_test.go @@ -0,0 +1,605 @@ +package roles_test + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/golang/protobuf/ptypes" + "github.com/hashicorp/watchtower/internal/db" + pb "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles" + pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services" + "github.com/hashicorp/watchtower/internal/iam" + "github.com/hashicorp/watchtower/internal/servers/controller/handlers/roles" + "google.golang.org/genproto/protobuf/field_mask" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func createDefaultRoleAndRepo(t *testing.T) (*iam.Role, func() (*iam.Repository, error)) { + t.Helper() + cleanup, conn, _ := db.TestSetup(t, "postgres") + t.Cleanup(func() { + if err := conn.Close(); err != nil { + t.Errorf("Error when closing gorm DB: %v", err) + } + if err := cleanup(); err != nil { + t.Errorf("Error when cleaning up TestSetup: %v", err) + } + }) + rw := db.New(conn) + wrap := db.TestWrapper(t) + repoFn := func() (*iam.Repository, error) { + return iam.NewRepository(rw, rw, wrap) + } + + o, _ := iam.TestScopes(t, conn) + u := iam.TestRole(t, conn, o.GetPublicId(), iam.WithDescription("default"), iam.WithName("default")) + return u, repoFn +} + +func TestGet(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + u, repo := createDefaultRoleAndRepo(t) + toMerge := &pbs.GetRoleRequest{ + OrgId: u.GetScopeId(), + Id: u.GetPublicId(), + } + + wantU := &pb.Role{ + Id: u.GetPublicId(), + Name: &wrapperspb.StringValue{Value: u.GetName()}, + Description: &wrapperspb.StringValue{Value: u.GetDescription()}, + CreatedTime: u.CreateTime.GetTimestamp(), + UpdatedTime: u.UpdateTime.GetTimestamp(), + } + + cases := []struct { + name string + req *pbs.GetRoleRequest + res *pbs.GetRoleResponse + errCode codes.Code + }{ + { + name: "Get an Existing Role", + req: &pbs.GetRoleRequest{Id: u.GetPublicId()}, + res: &pbs.GetRoleResponse{Item: wantU}, + errCode: codes.OK, + }, + { + name: "Get a non existant Role", + req: &pbs.GetRoleRequest{Id: iam.RolePrefix + "_DoesntExis"}, + res: nil, + errCode: codes.NotFound, + }, + { + name: "Wrong id prefix", + req: &pbs.GetRoleRequest{Id: "j_1234567890"}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "space in id", + req: &pbs.GetRoleRequest{Id: iam.RolePrefix + "_1 23456789"}, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + req := proto.Clone(toMerge).(*pbs.GetRoleRequest) + proto.Merge(req, tc.req) + + s, err := roles.NewService(repo) + require.NoError(err, "Couldn't create new role service.") + + got, gErr := s.GetRole(context.Background(), req) + assert.Equal(tc.errCode, status.Code(gErr), "GetRole(%+v) got error %v, wanted %v", req, gErr, tc.errCode) + assert.True(proto.Equal(got, tc.res), "GetRole(%q) got response %q, wanted %q", req, got, tc.res) + }) + } +} + +func TestList(t *testing.T) { + assert, require := assert.New(t), require.New(t) + cleanup, conn, _ := db.TestSetup(t, "postgres") + t.Cleanup(func() { + if err := conn.Close(); err != nil { + t.Errorf("Error when closing gorm DB: %v", err) + } + if err := cleanup(); err != nil { + t.Errorf("Error when cleaning up TestSetup: %v", err) + } + }) + rw := db.New(conn) + wrap := db.TestWrapper(t) + repoFn := func() (*iam.Repository, error) { + return iam.NewRepository(rw, rw, wrap) + } + oNoRoles, _ := iam.TestScopes(t, conn) + oWithRoles, _ := iam.TestScopes(t, conn) + var wantRoles []*pb.Role + for i := 0; i < 10; i++ { + g := iam.TestRole(t, conn, oWithRoles.GetPublicId()) + wantRoles = append(wantRoles, &pb.Role{ + Id: g.GetPublicId(), + CreatedTime: g.GetCreateTime().GetTimestamp(), + UpdatedTime: g.GetUpdateTime().GetTimestamp(), + }) + } + + cases := []struct { + name string + req *pbs.ListRolesRequest + res *pbs.ListRolesResponse + errCode codes.Code + }{ + { + name: "List Many Role", + req: &pbs.ListRolesRequest{OrgId: oWithRoles.GetPublicId()}, + res: &pbs.ListRolesResponse{Items: wantRoles}, + errCode: codes.OK, + }, + { + name: "List No Roles", + req: &pbs.ListRolesRequest{OrgId: oNoRoles.GetPublicId()}, + res: &pbs.ListRolesResponse{}, + errCode: codes.OK, + }, + { + name: "Invalid Org Id", + req: &pbs.ListRolesRequest{OrgId: iam.OrganizationScope.Prefix() + "_this is invalid"}, + res: nil, + errCode: codes.InvalidArgument, + }, + // TODO: When an org doesn't exist, we should return a 404 instead of an empty list. + { + name: "Unfound Org", + req: &pbs.ListRolesRequest{OrgId: iam.OrganizationScope.Prefix() + "_DoesntExis"}, + res: &pbs.ListRolesResponse{}, + errCode: codes.OK, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + s, err := roles.NewService(repoFn) + require.NoError(err, "Couldn't create new role service.") + + got, gErr := s.ListRoles(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "ListRoles(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + assert.True(proto.Equal(got, tc.res), "ListRoles(%q) got response %q, wanted %q", tc.req, got, tc.res) + }) + } +} + +func TestDelete(t *testing.T) { + require := require.New(t) + u, repo := createDefaultRoleAndRepo(t) + + s, err := roles.NewService(repo) + require.NoError(err, "Error when getting new role service.") + + cases := []struct { + name string + req *pbs.DeleteRoleRequest + res *pbs.DeleteRoleResponse + errCode codes.Code + }{ + { + name: "Delete an Existing Role", + req: &pbs.DeleteRoleRequest{ + OrgId: u.GetScopeId(), + Id: u.GetPublicId(), + }, + res: &pbs.DeleteRoleResponse{ + Existed: true, + }, + errCode: codes.OK, + }, + { + name: "Delete bad role id", + req: &pbs.DeleteRoleRequest{ + OrgId: u.GetScopeId(), + Id: iam.RolePrefix + "_doesntexis", + }, + res: &pbs.DeleteRoleResponse{ + Existed: false, + }, + errCode: codes.OK, + }, + { + name: "Delete bad org id", + req: &pbs.DeleteRoleRequest{ + OrgId: "o_doesntexis", + Id: u.GetPublicId(), + }, + res: &pbs.DeleteRoleResponse{ + Existed: false, + }, + errCode: codes.OK, + }, + { + name: "Bad org formatting", + req: &pbs.DeleteRoleRequest{ + OrgId: "bad_format", + Id: u.GetPublicId(), + }, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Role Id formatting", + req: &pbs.DeleteRoleRequest{ + OrgId: u.GetScopeId(), + Id: "bad_format", + }, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + got, gErr := s.DeleteRole(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "DeleteRole(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + assert.EqualValuesf(tc.res, got, "DeleteRole(%q) got response %q, wanted %q", tc.req, got, tc.res) + }) + } +} + +func TestDelete_twice(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + u, repo := createDefaultRoleAndRepo(t) + + s, err := roles.NewService(repo) + require.NoError(err, "Error when getting new role service") + req := &pbs.DeleteRoleRequest{ + OrgId: u.GetScopeId(), + Id: u.GetPublicId(), + } + got, gErr := s.DeleteRole(context.Background(), req) + assert.NoError(gErr, "First attempt") + assert.True(got.GetExisted(), "Expected existed to be true for the first delete.") + got, gErr = s.DeleteRole(context.Background(), req) + assert.NoError(gErr, "Second attempt") + assert.False(got.GetExisted(), "Expected existed to be false for the second delete.") +} + +func TestCreate(t *testing.T) { + require := require.New(t) + defaultRole, repo := createDefaultRoleAndRepo(t) + defaultCreated, err := ptypes.Timestamp(defaultRole.GetCreateTime().GetTimestamp()) + require.NoError(err, "Error converting proto to timestamp.") + toMerge := &pbs.CreateRoleRequest{ + OrgId: defaultRole.GetScopeId(), + } + + cases := []struct { + name string + req *pbs.CreateRoleRequest + res *pbs.CreateRoleResponse + errCode codes.Code + }{ + { + name: "Create a valid Role", + req: &pbs.CreateRoleRequest{Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "name"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + }}, + res: &pbs.CreateRoleResponse{ + Uri: fmt.Sprintf("orgs/%s/roles/%s_", defaultRole.GetScopeId(), iam.RolePrefix), + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "name"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + }, + }, + errCode: codes.OK, + }, + { + name: "Can't specify Id", + req: &pbs.CreateRoleRequest{Item: &pb.Role{ + Id: iam.RolePrefix + "_notallowed", + }}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "Can't specify Created Time", + req: &pbs.CreateRoleRequest{Item: &pb.Role{ + CreatedTime: ptypes.TimestampNow(), + }}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "Can't specify Update Time", + req: &pbs.CreateRoleRequest{Item: &pb.Role{ + UpdatedTime: ptypes.TimestampNow(), + }}, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + req := proto.Clone(toMerge).(*pbs.CreateRoleRequest) + proto.Merge(req, tc.req) + + s, err := roles.NewService(repo) + require.NoError(err, "Error when getting new role service.") + + got, gErr := s.CreateRole(context.Background(), req) + assert.Equal(tc.errCode, status.Code(gErr), "CreateRole(%+v) got error %v, wanted %v", req, gErr, tc.errCode) + if got != nil { + assert.True(strings.HasPrefix(got.GetUri(), tc.res.Uri), "Expected %q to have the prefix %q", got.GetUri(), tc.res.GetUri()) + assert.True(strings.HasPrefix(got.GetItem().GetId(), iam.RolePrefix+"_"), "Expected %q to have the prefix %q", got.GetItem().GetId(), iam.RolePrefix+"_") + gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) + require.NoError(err, "Error converting proto to timestamp.") + gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + require.NoError(err, "Error converting proto to timestamp.") + // Verify it is a role created after the test setup's default role + assert.True(gotCreateTime.After(defaultCreated), "New role should have been created after default role. Was created %v, which is after %v", gotCreateTime, defaultCreated) + assert.True(gotUpdateTime.After(defaultCreated), "New role should have been updated after default role. Was updated %v, which is after %v", gotUpdateTime, defaultCreated) + + // Clear all values which are hard to compare against. + got.Uri, tc.res.Uri = "", "" + got.Item.Id, tc.res.Item.Id = "", "" + got.Item.CreatedTime, got.Item.UpdatedTime, tc.res.Item.CreatedTime, tc.res.Item.UpdatedTime = nil, nil, nil, nil + } + assert.True(proto.Equal(got, tc.res), "CreateRole(%q) got response %q, wanted %q", req, got, tc.res) + }) + } +} + +func TestUpdate(t *testing.T) { + require := require.New(t) + u, repoFn := createDefaultRoleAndRepo(t) + tested, err := roles.NewService(repoFn) + require.NoError(err, "Error when getting new role service.") + + resetRole := func() { + repo, err := repoFn() + require.NoError(err, "Couldn't get a new repo") + u, _, err = repo.UpdateRole(context.Background(), u, []string{"Name", "Description"}) + require.NoError(err, "Failed to reset the role") + } + + created, err := ptypes.Timestamp(u.GetCreateTime().GetTimestamp()) + require.NoError(err, "Error converting proto to timestamp") + toMerge := &pbs.UpdateRoleRequest{ + OrgId: u.GetScopeId(), + Id: u.GetPublicId(), + } + + cases := []struct { + name string + req *pbs.UpdateRoleRequest + res *pbs.UpdateRoleResponse + errCode codes.Code + }{ + { + name: "Update an Existing Role", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"name", "description"}, + }, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + }, + }, + res: &pbs.UpdateRoleResponse{ + Item: &pb.Role{ + Id: u.GetPublicId(), + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + CreatedTime: u.GetCreateTime().GetTimestamp(), + }, + }, + errCode: codes.OK, + }, + { + name: "Multiple Paths in single string", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"name,description"}, + }, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + }, + }, + res: &pbs.UpdateRoleResponse{ + Item: &pb.Role{ + Id: u.GetPublicId(), + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + CreatedTime: u.GetCreateTime().GetTimestamp(), + }, + }, + errCode: codes.OK, + }, + { + name: "No Update Mask", + req: &pbs.UpdateRoleRequest{ + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "updated name"}, + Description: &wrapperspb.StringValue{Value: "updated desc"}, + }, + }, + errCode: codes.InvalidArgument, + }, + { + name: "No Paths in Mask", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{Paths: []string{}}, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "updated name"}, + Description: &wrapperspb.StringValue{Value: "updated desc"}, + }, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Only non-existant paths in Mask", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{Paths: []string{"nonexistant_field"}}, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "updated name"}, + Description: &wrapperspb.StringValue{Value: "updated desc"}, + }, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Unset Name", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"name"}, + }, + Item: &pb.Role{ + Description: &wrapperspb.StringValue{Value: "ignored"}, + }, + }, + res: &pbs.UpdateRoleResponse{ + Item: &pb.Role{ + Id: u.GetPublicId(), + Description: &wrapperspb.StringValue{Value: "default"}, + CreatedTime: u.GetCreateTime().GetTimestamp(), + }, + }, + errCode: codes.OK, + }, + { + name: "Update Only Name", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"name"}, + }, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "updated"}, + Description: &wrapperspb.StringValue{Value: "ignored"}, + }, + }, + res: &pbs.UpdateRoleResponse{ + Item: &pb.Role{ + Id: u.GetPublicId(), + Name: &wrapperspb.StringValue{Value: "updated"}, + Description: &wrapperspb.StringValue{Value: "default"}, + CreatedTime: u.GetCreateTime().GetTimestamp(), + }, + }, + errCode: codes.OK, + }, + { + name: "Update Only Description", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"description"}, + }, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "ignored"}, + Description: &wrapperspb.StringValue{Value: "notignored"}, + }, + }, + res: &pbs.UpdateRoleResponse{ + Item: &pb.Role{ + Id: u.GetPublicId(), + Name: &wrapperspb.StringValue{Value: "default"}, + Description: &wrapperspb.StringValue{Value: "notignored"}, + CreatedTime: u.GetCreateTime().GetTimestamp(), + }, + }, + errCode: codes.OK, + }, + // TODO: Updating a non existant role should result in a NotFound exception but currently results in + // the repoFn returning an internal error. + { + name: "Update a Non Existing Role", + req: &pbs.UpdateRoleRequest{ + Id: iam.RolePrefix + "_DoesntExis", + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"description"}, + }, + Item: &pb.Role{ + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "desc"}, + }, + }, + errCode: codes.Internal, + }, + { + name: "Cant change Id", + req: &pbs.UpdateRoleRequest{ + Id: u.GetPublicId(), + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"id"}, + }, + Item: &pb.Role{ + Id: iam.RolePrefix + "_somethinge", + Name: &wrapperspb.StringValue{Value: "new"}, + Description: &wrapperspb.StringValue{Value: "new desc"}, + }}, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "Cant specify Created Time", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"created_time"}, + }, + Item: &pb.Role{ + CreatedTime: ptypes.TimestampNow(), + }, + }, + res: nil, + errCode: codes.InvalidArgument, + }, + { + name: "Cant specify Updated Time", + req: &pbs.UpdateRoleRequest{ + UpdateMask: &field_mask.FieldMask{ + Paths: []string{"updated_time"}, + }, + Item: &pb.Role{ + UpdatedTime: ptypes.TimestampNow(), + }, + }, + res: nil, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + defer resetRole() + assert := assert.New(t) + req := proto.Clone(toMerge).(*pbs.UpdateRoleRequest) + proto.Merge(req, tc.req) + + got, gErr := tested.UpdateRole(context.Background(), req) + assert.Equal(tc.errCode, status.Code(gErr), "UpdateRole(%+v) got error %v, wanted %v", req, gErr, tc.errCode) + + if got != nil { + assert.NotNilf(tc.res, "Expected UpdateRole response to be nil, but was %v", got) + gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + require.NoError(err, "Error converting proto to timestamp") + // Verify it is a role updated after it was created + assert.True(gotUpdateTime.After(created), "Updated role should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, created) + + // Clear all values which are hard to compare against. + got.Item.UpdatedTime, tc.res.Item.UpdatedTime = nil, nil + } + assert.True(proto.Equal(got, tc.res), "UpdateRole(%q) got response %q, wanted %q", req, got, tc.res) + }) + } +}