From 853f263437b7dea6684f0b8b5fbd1a2144daf7b5 Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Wed, 13 May 2026 22:47:00 +0000 Subject: [PATCH 1/6] Add config-key backed API keys admin-only API keys persisted into mon's kv store. machine clients can auth without resuing human oauth password Signed-off-by: Joshua Blanch --- api/auth.proto | 41 ++ api/gen/grpc/go/auth.pb.go | 681 +++++++++++++++++++++++++++--- api/gen/grpc/go/auth.pb.gw.go | 294 ++++++++++++- api/gen/grpc/go/auth_grpc.pb.go | 160 ++++++- api/http.yaml | 10 + api/openapi/ceph-api.swagger.json | 195 +++++++++ pkg/api/auth_api_handlers.go | 69 +++ pkg/app/start.go | 4 +- pkg/auth/apikey.go | 82 ++++ pkg/auth/apikey_auth.go | 55 +++ pkg/auth/apikey_handler.go | 105 +++++ pkg/auth/apikey_store.go | 184 ++++++++ pkg/auth/apikey_test.go | 208 +++++++++ pkg/auth/discovery_handler.go | 6 +- pkg/auth/grpc_interceptor.go | 6 +- pkg/auth/keystore_test.go | 18 + pkg/auth/oauth_server.go | 3 +- pkg/user/service.go | 9 + 18 files changed, 2049 insertions(+), 81 deletions(-) create mode 100644 pkg/auth/apikey.go create mode 100644 pkg/auth/apikey_auth.go create mode 100644 pkg/auth/apikey_handler.go create mode 100644 pkg/auth/apikey_store.go create mode 100644 pkg/auth/apikey_test.go diff --git a/api/auth.proto b/api/auth.proto index 91479cc..7c8cfd4 100644 --- a/api/auth.proto +++ b/api/auth.proto @@ -14,6 +14,10 @@ service Auth { rpc Logout(google.protobuf.Empty) returns(google.protobuf.Empty); rpc Check(TokenCheckReq)returns(TokenCheckResp); rpc Whoami(google.protobuf.Empty) returns(WhoamiResp); + rpc CreateAPIKey(CreateAPIKeyReq) returns(CreateAPIKeyResp); + rpc ListAPIKeys(google.protobuf.Empty) returns(ListAPIKeysResp); + rpc GetAPIKey(GetAPIKeyReq) returns(APIKeyResp); + rpc RevokeAPIKey(RevokeAPIKeyReq) returns(google.protobuf.Empty); } message LoginReq{ @@ -50,6 +54,43 @@ message WhoamiResp{ map permissions=5 ; } +message CreateAPIKeyReq{ + string name =1; + string description =2; + optional google.protobuf.Timestamp expires_at =3; +} + +message CreateAPIKeyResp{ + APIKeyResp key =1; + string token =2; +} + +message ListAPIKeysResp{ + repeated APIKeyResp keys =1; +} + +message GetAPIKeyReq{ + string key_id =1; +} + +message RevokeAPIKeyReq{ + string key_id =1; +} + +message APIKeyResp{ + string id =1; + string name =2; + string description =3; + string owner =4; + string cluster_id =5; + bool enabled =6; + optional google.protobuf.Timestamp revoked_at =7; + optional google.protobuf.Timestamp created_at =8; + string created_by =9; + optional google.protobuf.Timestamp expires_at =10; + optional google.protobuf.Timestamp last_used_at =11; +} + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Ceph management API"; diff --git a/api/gen/grpc/go/auth.pb.go b/api/gen/grpc/go/auth.pb.go index fd78d40..9539731 100644 --- a/api/gen/grpc/go/auth.pb.go +++ b/api/gen/grpc/go/auth.pb.go @@ -371,6 +371,392 @@ func (x *WhoamiResp) GetPermissions() map[string]*structpb.ListValue { return nil } +type CreateAPIKeyReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` +} + +func (x *CreateAPIKeyReq) Reset() { + *x = CreateAPIKeyReq{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateAPIKeyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAPIKeyReq) ProtoMessage() {} + +func (x *CreateAPIKeyReq) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 CreateAPIKeyReq.ProtoReflect.Descriptor instead. +func (*CreateAPIKeyReq) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateAPIKeyReq) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateAPIKeyReq) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateAPIKeyReq) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +type CreateAPIKeyResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *APIKeyResp `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *CreateAPIKeyResp) Reset() { + *x = CreateAPIKeyResp{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateAPIKeyResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAPIKeyResp) ProtoMessage() {} + +func (x *CreateAPIKeyResp) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 CreateAPIKeyResp.ProtoReflect.Descriptor instead. +func (*CreateAPIKeyResp) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateAPIKeyResp) GetKey() *APIKeyResp { + if x != nil { + return x.Key + } + return nil +} + +func (x *CreateAPIKeyResp) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ListAPIKeysResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keys []*APIKeyResp `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (x *ListAPIKeysResp) Reset() { + *x = ListAPIKeysResp{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAPIKeysResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAPIKeysResp) ProtoMessage() {} + +func (x *ListAPIKeysResp) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 ListAPIKeysResp.ProtoReflect.Descriptor instead. +func (*ListAPIKeysResp) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{7} +} + +func (x *ListAPIKeysResp) GetKeys() []*APIKeyResp { + if x != nil { + return x.Keys + } + return nil +} + +type GetAPIKeyReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` +} + +func (x *GetAPIKeyReq) Reset() { + *x = GetAPIKeyReq{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAPIKeyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAPIKeyReq) ProtoMessage() {} + +func (x *GetAPIKeyReq) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 GetAPIKeyReq.ProtoReflect.Descriptor instead. +func (*GetAPIKeyReq) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{8} +} + +func (x *GetAPIKeyReq) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +type RevokeAPIKeyReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` +} + +func (x *RevokeAPIKeyReq) Reset() { + *x = RevokeAPIKeyReq{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RevokeAPIKeyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeAPIKeyReq) ProtoMessage() {} + +func (x *RevokeAPIKeyReq) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 RevokeAPIKeyReq.ProtoReflect.Descriptor instead. +func (*RevokeAPIKeyReq) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{9} +} + +func (x *RevokeAPIKeyReq) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +type APIKeyResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty"` + ClusterId string `protobuf:"bytes,5,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + Enabled bool `protobuf:"varint,6,opt,name=enabled,proto3" json:"enabled,omitempty"` + RevokedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=revoked_at,json=revokedAt,proto3,oneof" json:"revoked_at,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3,oneof" json:"created_at,omitempty"` + CreatedBy string `protobuf:"bytes,9,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=last_used_at,json=lastUsedAt,proto3,oneof" json:"last_used_at,omitempty"` +} + +func (x *APIKeyResp) Reset() { + *x = APIKeyResp{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *APIKeyResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*APIKeyResp) ProtoMessage() {} + +func (x *APIKeyResp) ProtoReflect() protoreflect.Message { + mi := &file_auth_proto_msgTypes[10] + 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 APIKeyResp.ProtoReflect.Descriptor instead. +func (*APIKeyResp) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{10} +} + +func (x *APIKeyResp) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *APIKeyResp) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *APIKeyResp) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *APIKeyResp) GetOwner() string { + if x != nil { + return x.Owner + } + return "" +} + +func (x *APIKeyResp) GetClusterId() string { + if x != nil { + return x.ClusterId + } + return "" +} + +func (x *APIKeyResp) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *APIKeyResp) GetRevokedAt() *timestamppb.Timestamp { + if x != nil { + return x.RevokedAt + } + return nil +} + +func (x *APIKeyResp) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *APIKeyResp) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *APIKeyResp) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *APIKeyResp) GetLastUsedAt() *timestamppb.Timestamp { + if x != nil { + return x.LastUsedAt + } + return nil +} + var File_auth_proto protoreflect.FileDescriptor var file_auth_proto_rawDesc = []byte{ @@ -456,42 +842,112 @@ var file_auth_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xd2, - 0x01, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x12, 0x0e, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, - 0x1a, 0x0f, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x12, 0x38, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x05, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x63, 0x65, 0x70, 0x68, - 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x12, - 0x32, 0x0a, 0x06, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x52, - 0x65, 0x73, 0x70, 0x42, 0xcc, 0x02, 0x92, 0x41, 0xa1, 0x02, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x43, - 0x65, 0x70, 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x41, - 0x50, 0x49, 0x22, 0x2d, 0x0a, 0x08, 0x43, 0x65, 0x70, 0x68, 0x20, 0x41, 0x50, 0x49, 0x12, 0x21, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, - 0x69, 0x2a, 0x46, 0x0a, 0x0f, 0x47, 0x50, 0x4c, 0x2d, 0x33, 0x2e, 0x30, 0x20, 0x6c, 0x69, 0x63, - 0x65, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, - 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, - 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, - 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, - 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, - 0x6e, 0x5a, 0x52, 0x0a, 0x50, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x12, 0x46, 0x08, - 0x03, 0x28, 0x02, 0x3a, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x39, 0x39, 0x36, 0x39, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6f, - 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x19, 0x0a, 0x17, 0x0a, 0x06, - 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x12, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x62, 0x14, 0x0a, 0x12, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, - 0x32, 0x12, 0x08, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x5a, 0x25, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, - 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x3b, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, + 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 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, 0x48, 0x00, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x22, 0x4c, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, + 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x37, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, + 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, + 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x25, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, + 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x28, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, + 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, + 0x81, 0x04, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x07, 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, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, + 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x08, 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, 0x48, 0x01, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x42, 0x79, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, + 0x18, 0x0a, 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, 0x48, 0x02, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, + 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x0b, 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, 0x48, 0x03, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, + 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x61, 0x74, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x32, 0xc1, 0x03, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x05, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x0e, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x38, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x32, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x63, 0x65, 0x70, 0x68, + 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x14, + 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x32, 0x0a, 0x06, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x12, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x57, 0x68, + 0x6f, 0x61, 0x6d, 0x69, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, + 0x16, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, + 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x12, 0x12, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, + 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x6f, + 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, + 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0xcc, 0x02, 0x92, 0x41, 0xa1, 0x02, 0x12, 0x8c, + 0x01, 0x0a, 0x13, 0x43, 0x65, 0x70, 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x41, 0x50, 0x49, 0x22, 0x2d, 0x0a, 0x08, 0x43, 0x65, 0x70, 0x68, 0x20, 0x41, + 0x50, 0x49, 0x12, 0x21, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, + 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2a, 0x46, 0x0a, 0x0f, 0x47, 0x50, 0x4c, 0x2d, 0x33, 0x2e, 0x30, + 0x20, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, + 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x62, + 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x2a, 0x02, 0x01, + 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, + 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x5a, 0x52, 0x0a, 0x50, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, + 0x32, 0x12, 0x46, 0x08, 0x03, 0x28, 0x02, 0x3a, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x39, 0x39, 0x36, 0x39, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x19, + 0x0a, 0x17, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x12, 0x0d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x62, 0x14, 0x0a, 0x12, 0x0a, 0x06, 0x4f, + 0x41, 0x75, 0x74, 0x68, 0x32, 0x12, 0x08, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x5a, + 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, + 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x65, 0x70, 0x68, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -506,42 +962,63 @@ func file_auth_proto_rawDescGZIP() []byte { return file_auth_proto_rawDescData } -var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_auth_proto_goTypes = []interface{}{ (*LoginReq)(nil), // 0: ceph.LoginReq (*LoginResp)(nil), // 1: ceph.LoginResp (*TokenCheckReq)(nil), // 2: ceph.TokenCheckReq (*TokenCheckResp)(nil), // 3: ceph.TokenCheckResp (*WhoamiResp)(nil), // 4: ceph.WhoamiResp - nil, // 5: ceph.LoginResp.PermissionsEntry - nil, // 6: ceph.TokenCheckResp.PermissionsEntry - nil, // 7: ceph.WhoamiResp.PermissionsEntry - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp - (*structpb.ListValue)(nil), // 9: google.protobuf.ListValue - (*emptypb.Empty)(nil), // 10: google.protobuf.Empty + (*CreateAPIKeyReq)(nil), // 5: ceph.CreateAPIKeyReq + (*CreateAPIKeyResp)(nil), // 6: ceph.CreateAPIKeyResp + (*ListAPIKeysResp)(nil), // 7: ceph.ListAPIKeysResp + (*GetAPIKeyReq)(nil), // 8: ceph.GetAPIKeyReq + (*RevokeAPIKeyReq)(nil), // 9: ceph.RevokeAPIKeyReq + (*APIKeyResp)(nil), // 10: ceph.APIKeyResp + nil, // 11: ceph.LoginResp.PermissionsEntry + nil, // 12: ceph.TokenCheckResp.PermissionsEntry + nil, // 13: ceph.WhoamiResp.PermissionsEntry + (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp + (*structpb.ListValue)(nil), // 15: google.protobuf.ListValue + (*emptypb.Empty)(nil), // 16: google.protobuf.Empty } var file_auth_proto_depIdxs = []int32{ - 8, // 0: ceph.LoginResp.pwd_expiration_date:type_name -> google.protobuf.Timestamp - 5, // 1: ceph.LoginResp.permissions:type_name -> ceph.LoginResp.PermissionsEntry - 8, // 2: ceph.TokenCheckResp.pwd_expiration_date:type_name -> google.protobuf.Timestamp - 6, // 3: ceph.TokenCheckResp.permissions:type_name -> ceph.TokenCheckResp.PermissionsEntry - 7, // 4: ceph.WhoamiResp.permissions:type_name -> ceph.WhoamiResp.PermissionsEntry - 9, // 5: ceph.LoginResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue - 9, // 6: ceph.TokenCheckResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue - 9, // 7: ceph.WhoamiResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue - 0, // 8: ceph.Auth.Login:input_type -> ceph.LoginReq - 10, // 9: ceph.Auth.Logout:input_type -> google.protobuf.Empty - 2, // 10: ceph.Auth.Check:input_type -> ceph.TokenCheckReq - 10, // 11: ceph.Auth.Whoami:input_type -> google.protobuf.Empty - 1, // 12: ceph.Auth.Login:output_type -> ceph.LoginResp - 10, // 13: ceph.Auth.Logout:output_type -> google.protobuf.Empty - 3, // 14: ceph.Auth.Check:output_type -> ceph.TokenCheckResp - 4, // 15: ceph.Auth.Whoami:output_type -> ceph.WhoamiResp - 12, // [12:16] is the sub-list for method output_type - 8, // [8:12] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 14, // 0: ceph.LoginResp.pwd_expiration_date:type_name -> google.protobuf.Timestamp + 11, // 1: ceph.LoginResp.permissions:type_name -> ceph.LoginResp.PermissionsEntry + 14, // 2: ceph.TokenCheckResp.pwd_expiration_date:type_name -> google.protobuf.Timestamp + 12, // 3: ceph.TokenCheckResp.permissions:type_name -> ceph.TokenCheckResp.PermissionsEntry + 13, // 4: ceph.WhoamiResp.permissions:type_name -> ceph.WhoamiResp.PermissionsEntry + 14, // 5: ceph.CreateAPIKeyReq.expires_at:type_name -> google.protobuf.Timestamp + 10, // 6: ceph.CreateAPIKeyResp.key:type_name -> ceph.APIKeyResp + 10, // 7: ceph.ListAPIKeysResp.keys:type_name -> ceph.APIKeyResp + 14, // 8: ceph.APIKeyResp.revoked_at:type_name -> google.protobuf.Timestamp + 14, // 9: ceph.APIKeyResp.created_at:type_name -> google.protobuf.Timestamp + 14, // 10: ceph.APIKeyResp.expires_at:type_name -> google.protobuf.Timestamp + 14, // 11: ceph.APIKeyResp.last_used_at:type_name -> google.protobuf.Timestamp + 15, // 12: ceph.LoginResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue + 15, // 13: ceph.TokenCheckResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue + 15, // 14: ceph.WhoamiResp.PermissionsEntry.value:type_name -> google.protobuf.ListValue + 0, // 15: ceph.Auth.Login:input_type -> ceph.LoginReq + 16, // 16: ceph.Auth.Logout:input_type -> google.protobuf.Empty + 2, // 17: ceph.Auth.Check:input_type -> ceph.TokenCheckReq + 16, // 18: ceph.Auth.Whoami:input_type -> google.protobuf.Empty + 5, // 19: ceph.Auth.CreateAPIKey:input_type -> ceph.CreateAPIKeyReq + 16, // 20: ceph.Auth.ListAPIKeys:input_type -> google.protobuf.Empty + 8, // 21: ceph.Auth.GetAPIKey:input_type -> ceph.GetAPIKeyReq + 9, // 22: ceph.Auth.RevokeAPIKey:input_type -> ceph.RevokeAPIKeyReq + 1, // 23: ceph.Auth.Login:output_type -> ceph.LoginResp + 16, // 24: ceph.Auth.Logout:output_type -> google.protobuf.Empty + 3, // 25: ceph.Auth.Check:output_type -> ceph.TokenCheckResp + 4, // 26: ceph.Auth.Whoami:output_type -> ceph.WhoamiResp + 6, // 27: ceph.Auth.CreateAPIKey:output_type -> ceph.CreateAPIKeyResp + 7, // 28: ceph.Auth.ListAPIKeys:output_type -> ceph.ListAPIKeysResp + 10, // 29: ceph.Auth.GetAPIKey:output_type -> ceph.APIKeyResp + 16, // 30: ceph.Auth.RevokeAPIKey:output_type -> google.protobuf.Empty + 23, // [23:31] is the sub-list for method output_type + 15, // [15:23] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_auth_proto_init() } @@ -610,16 +1087,90 @@ func file_auth_proto_init() { return nil } } + file_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateAPIKeyReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateAPIKeyResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAPIKeysResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAPIKeyReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeAPIKeyReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*APIKeyResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_auth_proto_msgTypes[1].OneofWrappers = []interface{}{} file_auth_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_auth_proto_msgTypes[5].OneofWrappers = []interface{}{} + file_auth_proto_msgTypes[10].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_auth_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 14, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/grpc/go/auth.pb.gw.go b/api/gen/grpc/go/auth.pb.gw.go index f707ec9..f8e99a2 100644 --- a/api/gen/grpc/go/auth.pb.gw.go +++ b/api/gen/grpc/go/auth.pb.gw.go @@ -126,6 +126,120 @@ func local_request_Auth_Whoami_0(ctx context.Context, marshaler runtime.Marshale return msg, metadata, err } +func request_Auth_CreateAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq CreateAPIKeyReq + metadata runtime.ServerMetadata + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.CreateAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Auth_CreateAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq CreateAPIKeyReq + metadata runtime.ServerMetadata + ) + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.CreateAPIKey(ctx, &protoReq) + return msg, metadata, err +} + +func request_Auth_ListAPIKeys_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) + msg, err := client.ListAPIKeys(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Auth_ListAPIKeys_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq emptypb.Empty + metadata runtime.ServerMetadata + ) + msg, err := server.ListAPIKeys(ctx, &protoReq) + return msg, metadata, err +} + +func request_Auth_GetAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetAPIKeyReq + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["key_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") + } + protoReq.KeyId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) + } + msg, err := client.GetAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Auth_GetAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetAPIKeyReq + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["key_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") + } + protoReq.KeyId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) + } + msg, err := server.GetAPIKey(ctx, &protoReq) + return msg, metadata, err +} + +func request_Auth_RevokeAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq RevokeAPIKeyReq + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["key_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") + } + protoReq.KeyId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) + } + msg, err := client.RevokeAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Auth_RevokeAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq RevokeAPIKeyReq + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["key_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") + } + protoReq.KeyId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) + } + msg, err := server.RevokeAPIKey(ctx, &protoReq) + return msg, metadata, err +} + // RegisterAuthHandlerServer registers the http handlers for service Auth to "mux". // UnaryRPC :call AuthServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -212,6 +326,86 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve } forward_Auth_Whoami_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodPost, pattern_Auth_CreateAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Auth_CreateAPIKey_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_CreateAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Auth_ListAPIKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Auth_ListAPIKeys_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp.(*ListAPIKeysResp)}, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Auth_GetAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Auth_GetAPIKey_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_GetAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodDelete, pattern_Auth_RevokeAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Auth_RevokeAPIKey_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_RevokeAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } @@ -320,19 +514,103 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien } forward_Auth_Whoami_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodPost, pattern_Auth_CreateAPIKey_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) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Auth_CreateAPIKey_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_CreateAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Auth_ListAPIKeys_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) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Auth_ListAPIKeys_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp.(*ListAPIKeysResp)}, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodGet, pattern_Auth_GetAPIKey_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) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Auth_GetAPIKey_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_GetAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + mux.Handle(http.MethodDelete, pattern_Auth_RevokeAPIKey_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) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Auth_RevokeAPIKey_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_Auth_RevokeAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } +type response_Auth_ListAPIKeys_0 struct { + *ListAPIKeysResp +} + +func (m response_Auth_ListAPIKeys_0) XXX_ResponseBody() interface{} { + return m.Keys +} + var ( - pattern_Auth_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "auth"}, "")) - pattern_Auth_Logout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "logout"}, "")) - pattern_Auth_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "check"}, "")) - pattern_Auth_Whoami_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "whoami"}, "")) + pattern_Auth_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "auth"}, "")) + pattern_Auth_Logout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "logout"}, "")) + pattern_Auth_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "check"}, "")) + pattern_Auth_Whoami_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "whoami"}, "")) + pattern_Auth_CreateAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "api-keys"}, "")) + pattern_Auth_ListAPIKeys_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "api-keys"}, "")) + pattern_Auth_GetAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"api", "v1", "auth", "api-keys", "key_id"}, "")) + pattern_Auth_RevokeAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"api", "v1", "auth", "api-keys", "key_id"}, "")) ) var ( - forward_Auth_Login_0 = runtime.ForwardResponseMessage - forward_Auth_Logout_0 = runtime.ForwardResponseMessage - forward_Auth_Check_0 = runtime.ForwardResponseMessage - forward_Auth_Whoami_0 = runtime.ForwardResponseMessage + forward_Auth_Login_0 = runtime.ForwardResponseMessage + forward_Auth_Logout_0 = runtime.ForwardResponseMessage + forward_Auth_Check_0 = runtime.ForwardResponseMessage + forward_Auth_Whoami_0 = runtime.ForwardResponseMessage + forward_Auth_CreateAPIKey_0 = runtime.ForwardResponseMessage + forward_Auth_ListAPIKeys_0 = runtime.ForwardResponseMessage + forward_Auth_GetAPIKey_0 = runtime.ForwardResponseMessage + forward_Auth_RevokeAPIKey_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/auth_grpc.pb.go b/api/gen/grpc/go/auth_grpc.pb.go index 1b2be61..6fd40ac 100644 --- a/api/gen/grpc/go/auth_grpc.pb.go +++ b/api/gen/grpc/go/auth_grpc.pb.go @@ -20,10 +20,14 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Auth_Login_FullMethodName = "/ceph.Auth/Login" - Auth_Logout_FullMethodName = "/ceph.Auth/Logout" - Auth_Check_FullMethodName = "/ceph.Auth/Check" - Auth_Whoami_FullMethodName = "/ceph.Auth/Whoami" + Auth_Login_FullMethodName = "/ceph.Auth/Login" + Auth_Logout_FullMethodName = "/ceph.Auth/Logout" + Auth_Check_FullMethodName = "/ceph.Auth/Check" + Auth_Whoami_FullMethodName = "/ceph.Auth/Whoami" + Auth_CreateAPIKey_FullMethodName = "/ceph.Auth/CreateAPIKey" + Auth_ListAPIKeys_FullMethodName = "/ceph.Auth/ListAPIKeys" + Auth_GetAPIKey_FullMethodName = "/ceph.Auth/GetAPIKey" + Auth_RevokeAPIKey_FullMethodName = "/ceph.Auth/RevokeAPIKey" ) // AuthClient is the client API for Auth service. @@ -34,6 +38,10 @@ type AuthClient interface { Logout(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) Check(ctx context.Context, in *TokenCheckReq, opts ...grpc.CallOption) (*TokenCheckResp, error) Whoami(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*WhoamiResp, error) + CreateAPIKey(ctx context.Context, in *CreateAPIKeyReq, opts ...grpc.CallOption) (*CreateAPIKeyResp, error) + ListAPIKeys(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListAPIKeysResp, error) + GetAPIKey(ctx context.Context, in *GetAPIKeyReq, opts ...grpc.CallOption) (*APIKeyResp, error) + RevokeAPIKey(ctx context.Context, in *RevokeAPIKeyReq, opts ...grpc.CallOption) (*emptypb.Empty, error) } type authClient struct { @@ -84,6 +92,46 @@ func (c *authClient) Whoami(ctx context.Context, in *emptypb.Empty, opts ...grpc return out, nil } +func (c *authClient) CreateAPIKey(ctx context.Context, in *CreateAPIKeyReq, opts ...grpc.CallOption) (*CreateAPIKeyResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateAPIKeyResp) + err := c.cc.Invoke(ctx, Auth_CreateAPIKey_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authClient) ListAPIKeys(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListAPIKeysResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListAPIKeysResp) + err := c.cc.Invoke(ctx, Auth_ListAPIKeys_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authClient) GetAPIKey(ctx context.Context, in *GetAPIKeyReq, opts ...grpc.CallOption) (*APIKeyResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(APIKeyResp) + err := c.cc.Invoke(ctx, Auth_GetAPIKey_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authClient) RevokeAPIKey(ctx context.Context, in *RevokeAPIKeyReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, Auth_RevokeAPIKey_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // AuthServer is the server API for Auth service. // All implementations should embed UnimplementedAuthServer // for forward compatibility. @@ -92,6 +140,10 @@ type AuthServer interface { Logout(context.Context, *emptypb.Empty) (*emptypb.Empty, error) Check(context.Context, *TokenCheckReq) (*TokenCheckResp, error) Whoami(context.Context, *emptypb.Empty) (*WhoamiResp, error) + CreateAPIKey(context.Context, *CreateAPIKeyReq) (*CreateAPIKeyResp, error) + ListAPIKeys(context.Context, *emptypb.Empty) (*ListAPIKeysResp, error) + GetAPIKey(context.Context, *GetAPIKeyReq) (*APIKeyResp, error) + RevokeAPIKey(context.Context, *RevokeAPIKeyReq) (*emptypb.Empty, error) } // UnimplementedAuthServer should be embedded to have @@ -113,6 +165,18 @@ func (UnimplementedAuthServer) Check(context.Context, *TokenCheckReq) (*TokenChe func (UnimplementedAuthServer) Whoami(context.Context, *emptypb.Empty) (*WhoamiResp, error) { return nil, status.Errorf(codes.Unimplemented, "method Whoami not implemented") } +func (UnimplementedAuthServer) CreateAPIKey(context.Context, *CreateAPIKeyReq) (*CreateAPIKeyResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateAPIKey not implemented") +} +func (UnimplementedAuthServer) ListAPIKeys(context.Context, *emptypb.Empty) (*ListAPIKeysResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListAPIKeys not implemented") +} +func (UnimplementedAuthServer) GetAPIKey(context.Context, *GetAPIKeyReq) (*APIKeyResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAPIKey not implemented") +} +func (UnimplementedAuthServer) RevokeAPIKey(context.Context, *RevokeAPIKeyReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RevokeAPIKey not implemented") +} func (UnimplementedAuthServer) testEmbeddedByValue() {} // UnsafeAuthServer may be embedded to opt out of forward compatibility for this service. @@ -205,6 +269,78 @@ func _Auth_Whoami_Handler(srv interface{}, ctx context.Context, dec func(interfa return interceptor(ctx, in, info, handler) } +func _Auth_CreateAPIKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateAPIKeyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).CreateAPIKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Auth_CreateAPIKey_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).CreateAPIKey(ctx, req.(*CreateAPIKeyReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Auth_ListAPIKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).ListAPIKeys(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Auth_ListAPIKeys_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).ListAPIKeys(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Auth_GetAPIKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAPIKeyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).GetAPIKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Auth_GetAPIKey_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).GetAPIKey(ctx, req.(*GetAPIKeyReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Auth_RevokeAPIKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RevokeAPIKeyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).RevokeAPIKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Auth_RevokeAPIKey_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RevokeAPIKey(ctx, req.(*RevokeAPIKeyReq)) + } + return interceptor(ctx, in, info, handler) +} + // Auth_ServiceDesc is the grpc.ServiceDesc for Auth service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -228,6 +364,22 @@ var Auth_ServiceDesc = grpc.ServiceDesc{ MethodName: "Whoami", Handler: _Auth_Whoami_Handler, }, + { + MethodName: "CreateAPIKey", + Handler: _Auth_CreateAPIKey_Handler, + }, + { + MethodName: "ListAPIKeys", + Handler: _Auth_ListAPIKeys_Handler, + }, + { + MethodName: "GetAPIKey", + Handler: _Auth_GetAPIKey_Handler, + }, + { + MethodName: "RevokeAPIKey", + Handler: _Auth_RevokeAPIKey_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "auth.proto", diff --git a/api/http.yaml b/api/http.yaml index d7dc63b..316dca4 100644 --- a/api/http.yaml +++ b/api/http.yaml @@ -71,6 +71,16 @@ http: - selector: ceph.Auth.Whoami get: /api/v1/auth/whoami response_body: "*" + - selector: ceph.Auth.CreateAPIKey + post: /api/v1/auth/api-keys + body: "*" + - selector: ceph.Auth.ListAPIKeys + get: /api/v1/auth/api-keys + response_body: "keys" + - selector: ceph.Auth.GetAPIKey + get: /api/v1/auth/api-keys/{key_id} + - selector: ceph.Auth.RevokeAPIKey + delete: /api/v1/auth/api-keys/{key_id} # CRUSH rules - selector: ceph.CrushRule.ListRules get: /api/crush_rule diff --git a/api/openapi/ceph-api.swagger.json b/api/openapi/ceph-api.swagger.json index 631ecab..78dae4b 100644 --- a/api/openapi/ceph-api.swagger.json +++ b/api/openapi/ceph-api.swagger.json @@ -1047,6 +1047,121 @@ ] } }, + "/api/v1/auth/api-keys": { + "get": { + "operationId": "Auth_ListAPIKeys", + "responses": { + "200": { + "description": "", + "schema": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/cephAPIKeyResp" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Auth" + ] + }, + "post": { + "operationId": "Auth_CreateAPIKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/cephCreateAPIKeyResp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/cephCreateAPIKeyReq" + } + } + ], + "tags": [ + "Auth" + ] + } + }, + "/api/v1/auth/api-keys/{keyId}": { + "get": { + "operationId": "Auth_GetAPIKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/cephAPIKeyResp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "keyId", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Auth" + ] + }, + "delete": { + "operationId": "Auth_RevokeAPIKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "keyId", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Auth" + ] + } + }, "/api/v1/auth/whoami": { "get": { "operationId": "Auth_Whoami", @@ -1955,6 +2070,48 @@ } } }, + "cephAPIKeyResp": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "clusterId": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "revokedAt": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "expiresAt": { + "type": "string", + "format": "date-time" + }, + "lastUsedAt": { + "type": "string", + "format": "date-time" + } + } + }, "cephCephMonDumpAddrVec": { "type": "object", "properties": { @@ -2396,6 +2553,32 @@ } } }, + "cephCreateAPIKeyReq": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "expiresAt": { + "type": "string", + "format": "date-time" + } + } + }, + "cephCreateAPIKeyResp": { + "type": "object", + "properties": { + "key": { + "$ref": "#/definitions/cephAPIKeyResp" + }, + "token": { + "type": "string" + } + } + }, "cephCreateClusterUserReq": { "type": "object", "properties": { @@ -2718,6 +2901,18 @@ } } }, + "cephListAPIKeysResp": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/cephAPIKeyResp" + } + } + } + }, "cephListRulesResponse": { "type": "object", "properties": { diff --git a/pkg/api/auth_api_handlers.go b/pkg/api/auth_api_handlers.go index ecdb157..cf4652d 100644 --- a/pkg/api/auth_api_handlers.go +++ b/pkg/api/auth_api_handlers.go @@ -2,6 +2,7 @@ package api import ( "context" + "time" pb "github.com/clyso/ceph-api/api/gen/grpc/go" "github.com/clyso/ceph-api/pkg/auth" @@ -9,6 +10,7 @@ import ( "github.com/clyso/ceph-api/pkg/types" "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" ) func NewAuthAPI(svc *auth.Server) pb.AuthServer { @@ -63,6 +65,73 @@ func (a *authAPI) Whoami(ctx context.Context, _ *emptypb.Empty) (*pb.WhoamiResp, }, nil } +func (a *authAPI) CreateAPIKey(ctx context.Context, req *pb.CreateAPIKeyReq) (*pb.CreateAPIKeyResp, error) { + var expiresAt *time.Time + if req.GetExpiresAt() != nil { + expires := req.GetExpiresAt().AsTime() + expiresAt = &expires + } + rec, token, err := a.svc.CreateAPIKey(ctx, auth.CreateAPIKeyRequest{ + Name: req.GetName(), + Description: req.GetDescription(), + ExpiresAt: expiresAt, + }) + if err != nil { + return nil, err + } + return &pb.CreateAPIKeyResp{Key: apiKeyToPB(rec), Token: token}, nil +} + +func (a *authAPI) ListAPIKeys(ctx context.Context, _ *emptypb.Empty) (*pb.ListAPIKeysResp, error) { + keys, err := a.svc.ListAPIKeys(ctx) + if err != nil { + return nil, err + } + res := &pb.ListAPIKeysResp{Keys: make([]*pb.APIKeyResp, 0, len(keys))} + for _, key := range keys { + res.Keys = append(res.Keys, apiKeyToPB(key)) + } + return res, nil +} + +func (a *authAPI) GetAPIKey(ctx context.Context, req *pb.GetAPIKeyReq) (*pb.APIKeyResp, error) { + rec, err := a.svc.GetAPIKey(ctx, req.GetKeyId()) + if err != nil { + return nil, err + } + return apiKeyToPB(rec), nil +} + +func (a *authAPI) RevokeAPIKey(ctx context.Context, req *pb.RevokeAPIKeyReq) (*emptypb.Empty, error) { + if err := a.svc.RevokeAPIKey(ctx, req.GetKeyId()); err != nil { + return nil, err + } + return &emptypb.Empty{}, nil +} + +func apiKeyToPB(in auth.APIKeyRecord) *pb.APIKeyResp { + return &pb.APIKeyResp{ + Id: in.ID, + Name: in.Name, + Description: in.Description, + Owner: in.Owner, + ClusterId: in.ClusterID, + Enabled: in.Enabled, + RevokedAt: timeToPB(in.RevokedAt), + CreatedAt: timestamppb.New(in.CreatedAt), + CreatedBy: in.CreatedBy, + ExpiresAt: timeToPB(in.ExpiresAt), + LastUsedAt: timeToPB(in.LastUsedAt), + } +} + +func timeToPB(in *time.Time) *timestamppb.Timestamp { + if in == nil { + return nil + } + return timestamppb.New(*in) +} + func permissionsToPB(in map[string][]string) map[string]*structpb.ListValue { permissions := make(map[string]*structpb.ListValue, len(in)) for p, vals := range in { diff --git a/pkg/app/start.go b/pkg/app/start.go index f1abde9..83a340e 100644 --- a/pkg/app/start.go +++ b/pkg/app/start.go @@ -100,11 +100,13 @@ func Start(ctx context.Context, conf config.Config, build config.Build) error { if err != nil { return fmt.Errorf("load OAuth global secret: %w", err) } + apiKeyStore := auth.NewAPIKeyStore(radosSvc) authServer, err := auth.NewServer(conf.Auth, userSvc, signingKey, signingKID, globalSecret) if err != nil { return err } + authServer.SetAPIKeyStore(apiKeyStore) authAPI := api.NewAuthAPI(authServer) server := util.NewServer() @@ -113,7 +115,7 @@ func Start(ctx context.Context, conf config.Config, build config.Build) error { statusAPI := api.NewStatusAPI(radosSvc) - authChecker := auth.AuthFunc(userSvc, authServer.Provider(), authServer.GetPublicKey) + authChecker := auth.AuthFunc(userSvc, authServer.Provider(), authServer.GetPublicKey, apiKeyStore) grpcServer := api.NewGrpcServer(conf.Api, clusterAPI, usersAPI, authAPI, crushRuleAPI, statusAPI, authChecker, tp, conf.Log) var metricsHandler http.HandlerFunc diff --git a/pkg/auth/apikey.go b/pkg/auth/apikey.go new file mode 100644 index 0000000..57ed458 --- /dev/null +++ b/pkg/auth/apikey.go @@ -0,0 +1,82 @@ +package auth + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "encoding/base32" + "encoding/base64" + "fmt" + "strings" + "time" + + "github.com/clyso/ceph-api/pkg/types" +) + +const ( + apiKeyTokenPrefix = "capi_v1_" + apiKeyIDPrefix = "ak_" + apiKeySecretSize = 32 + apiKeyIDRandSize = 16 +) + +type APIKeyRecord struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Owner string `json:"owner"` + ClusterID string `json:"cluster_id"` + SecretHash string `json:"secret_hash"` + Enabled bool `json:"enabled"` + RevokedAt *time.Time `json:"revoked_at"` + CreatedAt time.Time `json:"created_at"` + CreatedBy string `json:"created_by"` + ExpiresAt *time.Time `json:"expires_at"` + LastUsedAt *time.Time `json:"last_used_at"` +} + +type parsedAPIKeyToken struct { + ID string + Secret string +} + +func newAPIKeyToken() (string, string, string, error) { + idRaw := make([]byte, apiKeyIDRandSize) + if _, err := rand.Read(idRaw); err != nil { + return "", "", "", fmt.Errorf("generate API key id: %w", err) + } + secretRaw := make([]byte, apiKeySecretSize) + if _, err := rand.Read(secretRaw); err != nil { + return "", "", "", fmt.Errorf("generate API key secret: %w", err) + } + + id := apiKeyIDPrefix + strings.ToLower(base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(idRaw)) + secret := base64.RawURLEncoding.EncodeToString(secretRaw) + return id, secret, apiKeyTokenPrefix + id + "." + secret, nil +} + +func parseAPIKeyToken(token string) (parsedAPIKeyToken, error) { + if !strings.HasPrefix(token, apiKeyTokenPrefix) { + return parsedAPIKeyToken{}, types.ErrUnauthenticated + } + rest := strings.TrimPrefix(token, apiKeyTokenPrefix) + id, secret, ok := strings.Cut(rest, ".") + if !ok || !validAPIKeyID(id) || secret == "" || strings.Contains(secret, ".") { + return parsedAPIKeyToken{}, types.ErrUnauthenticated + } + return parsedAPIKeyToken{ID: id, Secret: secret}, nil +} + +func validAPIKeyID(id string) bool { + return strings.HasPrefix(id, apiKeyIDPrefix) && !strings.Contains(id, "/") && len(id) > len(apiKeyIDPrefix) +} + +func hashAPIKeySecret(secret string) string { + sum := sha256.Sum256([]byte(secret)) + return "sha256:" + base64.StdEncoding.EncodeToString(sum[:]) +} + +func compareAPIKeySecret(secret, storedHash string) bool { + computed := hashAPIKeySecret(secret) + return subtle.ConstantTimeCompare([]byte(computed), []byte(storedHash)) == 1 +} diff --git a/pkg/auth/apikey_auth.go b/pkg/auth/apikey_auth.go new file mode 100644 index 0000000..c2e3933 --- /dev/null +++ b/pkg/auth/apikey_auth.go @@ -0,0 +1,55 @@ +package auth + +import ( + "context" + "time" + + xctx "github.com/clyso/ceph-api/pkg/ctx" + "github.com/clyso/ceph-api/pkg/log" + "github.com/clyso/ceph-api/pkg/types" + "github.com/clyso/ceph-api/pkg/user" + "github.com/rs/zerolog" +) + +const apiKeyLastUsedDebounce = time.Minute + +func authenticateAPIKey(ctx context.Context, tokenStr string, store *APIKeyStore) (context.Context, error) { + if store == nil { + return nil, unauthenticated(types.ErrUnauthenticated) + } + parsed, err := parseAPIKeyToken(tokenStr) + if err != nil { + return nil, unauthenticated(err) + } + rec, err := store.Get(ctx, parsed.ID) + if err != nil { + zerolog.Ctx(ctx).Err(err).Str("api_key_id", parsed.ID).Msg("API key not found") + return nil, unauthenticated(types.ErrUnauthenticated) + } + if !rec.Enabled || rec.RevokedAt != nil { + return nil, unauthenticated(types.ErrUnauthenticated) + } + if rec.ExpiresAt != nil && time.Now().After(*rec.ExpiresAt) { + return nil, unauthenticated(types.ErrUnauthenticated) + } + if !compareAPIKeySecret(parsed.Secret, rec.SecretHash) { + return nil, unauthenticated(types.ErrUnauthenticated) + } + + subject := "apikey:" + rec.ID + ctx = log.WithUsername(ctx, subject) + ctx = xctx.SetRoles(ctx, []string{"administrator"}) + ctx = xctx.SetPermissions(ctx, user.AdministratorPermissions()) + ctx = xctx.SetAuthType(ctx, "api_key") + ctx = xctx.SetAPIKeyID(ctx, rec.ID) + + if store.shouldTouchLastUsed(rec, time.Now()) { + go func(ctx context.Context, rec APIKeyRecord) { + if err := store.TouchLastUsed(ctx, rec, time.Now().UTC()); err != nil { + zerolog.Ctx(ctx).Debug().Err(err).Str("api_key_id", rec.ID).Msg("unable to update API key last-used metadata") + } + }(ctx, rec) + } + + return ctx, nil +} diff --git a/pkg/auth/apikey_handler.go b/pkg/auth/apikey_handler.go new file mode 100644 index 0000000..70b04f7 --- /dev/null +++ b/pkg/auth/apikey_handler.go @@ -0,0 +1,105 @@ +package auth + +import ( + "context" + "fmt" + "time" + + xctx "github.com/clyso/ceph-api/pkg/ctx" + "github.com/clyso/ceph-api/pkg/types" +) + +type CreateAPIKeyRequest struct { + Name string + Description string + ExpiresAt *time.Time +} + +func (s *Server) SetAPIKeyStore(store *APIKeyStore) { + s.apiKeyStore = store +} + +func (s *Server) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (APIKeyRecord, string, error) { + if err := requireJWTAdministrator(ctx); err != nil { + return APIKeyRecord{}, "", err + } + if s.apiKeyStore == nil { + return APIKeyRecord{}, "", fmt.Errorf("%w: API key store is not configured", types.ErrInternal) + } + if req.Name == "" { + return APIKeyRecord{}, "", fmt.Errorf("%w: API key name is required", types.ErrInvalidArg) + } + if req.ExpiresAt != nil && req.ExpiresAt.Before(time.Now()) { + return APIKeyRecord{}, "", fmt.Errorf("%w: API key expiration must be in the future", types.ErrInvalidArg) + } + + id, secret, token, err := newAPIKeyToken() + if err != nil { + return APIKeyRecord{}, "", err + } + now := time.Now().UTC() + username := xctx.GetUsername(ctx) + // API-key v1 intentionally issues administrator keys only. Scoped roles are + // deferred until role grants can be persisted and enforced end-to-end. + rec := APIKeyRecord{ + ID: id, + Name: req.Name, + Description: req.Description, + Owner: "user:" + username, + SecretHash: hashAPIKeySecret(secret), + Enabled: true, + CreatedAt: now, + CreatedBy: "user:" + username, + ExpiresAt: req.ExpiresAt, + } + if err := s.apiKeyStore.Create(ctx, rec); err != nil { + return APIKeyRecord{}, "", err + } + return rec, token, nil +} + +func (s *Server) ListAPIKeys(ctx context.Context) ([]APIKeyRecord, error) { + if err := requireJWTAdministrator(ctx); err != nil { + return nil, err + } + if s.apiKeyStore == nil { + return nil, fmt.Errorf("%w: API key store is not configured", types.ErrInternal) + } + return s.apiKeyStore.List(ctx) +} + +func (s *Server) GetAPIKey(ctx context.Context, id string) (APIKeyRecord, error) { + if err := requireJWTAdministrator(ctx); err != nil { + return APIKeyRecord{}, err + } + if s.apiKeyStore == nil { + return APIKeyRecord{}, fmt.Errorf("%w: API key store is not configured", types.ErrInternal) + } + return s.apiKeyStore.Get(ctx, id) +} + +func (s *Server) RevokeAPIKey(ctx context.Context, id string) error { + if err := requireJWTAdministrator(ctx); err != nil { + return err + } + if s.apiKeyStore == nil { + return fmt.Errorf("%w: API key store is not configured", types.ErrInternal) + } + _, err := s.apiKeyStore.Revoke(ctx, id, time.Now().UTC()) + return err +} + +func requireJWTAdministrator(ctx context.Context) error { + if xctx.GetUsername(ctx) == "" { + return types.ErrUnauthenticated + } + if xctx.GetAuthType(ctx) != "jwt" { + return types.ErrAccessDenied + } + for _, role := range xctx.GetRoles(ctx) { + if role == "administrator" { + return nil + } + } + return types.ErrAccessDenied +} diff --git a/pkg/auth/apikey_store.go b/pkg/auth/apikey_store.go new file mode 100644 index 0000000..f974c44 --- /dev/null +++ b/pkg/auth/apikey_store.go @@ -0,0 +1,184 @@ +package auth + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "sort" + "strings" + "sync" + "time" + + "github.com/clyso/ceph-api/pkg/types" +) + +const apiKeyConfigPrefix = "ceph-api/auth/apikeys/" + +type APIKeyStore struct { + mon MonCommander + mu sync.Mutex + lastUsedSeen map[string]time.Time +} + +func NewAPIKeyStore(mon MonCommander) *APIKeyStore { + return &APIKeyStore{mon: mon, lastUsedSeen: map[string]time.Time{}} +} + +func (s *APIKeyStore) Create(ctx context.Context, rec APIKeyRecord) error { + if !validAPIKeyID(rec.ID) { + return fmt.Errorf("%w: invalid API key id", types.ErrInvalidArg) + } + if _, err := s.Get(ctx, rec.ID); err == nil { + return types.ErrAlreadyExists + } else if !errors.Is(err, types.RadosErrorNotFound) && !errors.Is(err, types.ErrNotFound) { + return err + } + return s.store(ctx, rec) +} + +func (s *APIKeyStore) Get(ctx context.Context, id string) (APIKeyRecord, error) { + if !validAPIKeyID(id) { + return APIKeyRecord{}, fmt.Errorf("%w: invalid API key id", types.ErrInvalidArg) + } + cmd, err := json.Marshal(map[string]string{"prefix": "config-key get", "key": apiKeyConfigKey(id)}) + if err != nil { + return APIKeyRecord{}, err + } + raw, err := s.mon.ExecMon(ctx, string(cmd)) + if err != nil { + if errors.Is(err, types.RadosErrorNotFound) { + return APIKeyRecord{}, types.ErrNotFound + } + return APIKeyRecord{}, err + } + + return decodeAPIKeyRecord(id, raw) +} + +func (s *APIKeyStore) List(ctx context.Context) ([]APIKeyRecord, error) { + cmd, err := json.Marshal(map[string]string{"prefix": "config-key dump", "key": apiKeyConfigPrefix}) + if err != nil { + return nil, err + } + raw, err := s.mon.ExecMon(ctx, string(cmd)) + if err != nil { + return nil, err + } + records, err := decodeConfigKeyDump(raw) + if err != nil { + return nil, err + } + sort.Slice(records, func(i, j int) bool { return records[i].ID < records[j].ID }) + return records, nil +} + +func (s *APIKeyStore) Revoke(ctx context.Context, id string, now time.Time) (APIKeyRecord, error) { + rec, err := s.Get(ctx, id) + if err != nil { + return APIKeyRecord{}, err + } + rec.Enabled = false + rec.RevokedAt = &now + if err := s.store(ctx, rec); err != nil { + return APIKeyRecord{}, err + } + return rec, nil +} + +func (s *APIKeyStore) TouchLastUsed(ctx context.Context, rec APIKeyRecord, now time.Time) error { + if rec.LastUsedAt != nil && rec.LastUsedAt.After(now.Add(-apiKeyLastUsedDebounce)) { + return nil + } + latest, err := s.Get(ctx, rec.ID) + if err != nil { + return err + } + if latest.LastUsedAt != nil && latest.LastUsedAt.After(now.Add(-apiKeyLastUsedDebounce)) { + return nil + } + latest.LastUsedAt = &now + return s.store(ctx, latest) +} + +func (s *APIKeyStore) shouldTouchLastUsed(rec APIKeyRecord, now time.Time) bool { + threshold := now.Add(-apiKeyLastUsedDebounce) + if rec.LastUsedAt != nil && rec.LastUsedAt.After(threshold) { + return false + } + s.mu.Lock() + defer s.mu.Unlock() + if s.lastUsedSeen == nil { + s.lastUsedSeen = map[string]time.Time{} + } + if last, ok := s.lastUsedSeen[rec.ID]; ok && last.After(threshold) { + return false + } + s.lastUsedSeen[rec.ID] = now + return true +} + +func (s *APIKeyStore) store(ctx context.Context, rec APIKeyRecord) error { + val, err := json.Marshal(rec) + if err != nil { + return err + } + env, err := json.Marshal(keyStoreEnvelope{Version: 1, Value: json.RawMessage(val)}) + if err != nil { + return err + } + cmd, err := json.Marshal(map[string]string{"prefix": "config-key set", "key": apiKeyConfigKey(rec.ID)}) + if err != nil { + return err + } + _, err = s.mon.ExecMonWithInputBuff(ctx, string(cmd), env) + if err != nil { + return fmt.Errorf("persist API key: %w", err) + } + return nil +} + +func apiKeyConfigKey(id string) string { + return apiKeyConfigPrefix + id +} + +func decodeAPIKeyRecord(id string, raw []byte) (APIKeyRecord, error) { + var env keyStoreEnvelope + if err := json.Unmarshal(raw, &env); err != nil { + return APIKeyRecord{}, fmt.Errorf("decode persisted API key envelope: %w", err) + } + if env.Version == 0 || len(env.Value) == 0 { + return APIKeyRecord{}, fmt.Errorf("decode persisted API key envelope: missing value") + } + var rec APIKeyRecord + if err := json.Unmarshal(env.Value, &rec); err != nil { + return APIKeyRecord{}, fmt.Errorf("decode persisted API key: %w", err) + } + if rec.ID != id { + return APIKeyRecord{}, fmt.Errorf("persisted API key id mismatch") + } + return rec, nil +} + +func decodeConfigKeyDump(raw []byte) ([]APIKeyRecord, error) { + var dumped map[string]json.RawMessage + if err := json.Unmarshal(raw, &dumped); err != nil { + return nil, fmt.Errorf("decode config-key dump: %w", err) + } + records := make([]APIKeyRecord, 0, len(dumped)) + for key, val := range dumped { + if !strings.HasPrefix(key, apiKeyConfigPrefix) { + continue + } + var value string + if err := json.Unmarshal(val, &value); err == nil { + val = json.RawMessage([]byte(value)) + } + rec, err := decodeAPIKeyRecord(strings.TrimPrefix(key, apiKeyConfigPrefix), val) + if err != nil { + return nil, err + } + records = append(records, rec) + } + return records, nil +} diff --git a/pkg/auth/apikey_test.go b/pkg/auth/apikey_test.go new file mode 100644 index 0000000..e703a8a --- /dev/null +++ b/pkg/auth/apikey_test.go @@ -0,0 +1,208 @@ +package auth + +import ( + "context" + "strings" + "testing" + "time" + + xctx "github.com/clyso/ceph-api/pkg/ctx" +) + +func TestAPIKeyTokenHashAndParse(t *testing.T) { + id, secret, token, err := newAPIKeyToken() + if err != nil { + t.Fatalf("newAPIKeyToken() error = %v", err) + } + if !strings.HasPrefix(token, apiKeyTokenPrefix+id+".") { + t.Fatalf("token = %q, want prefix with id", token) + } + parsed, err := parseAPIKeyToken(token) + if err != nil { + t.Fatalf("parseAPIKeyToken() error = %v", err) + } + if parsed.ID != id || parsed.Secret != secret { + t.Fatalf("parsed token = %+v, want id %q and original secret", parsed, id) + } + if !compareAPIKeySecret(secret, hashAPIKeySecret(secret)) { + t.Fatal("compareAPIKeySecret() rejected matching secret") + } + if compareAPIKeySecret(secret+"x", hashAPIKeySecret(secret)) { + t.Fatal("compareAPIKeySecret() accepted wrong secret") + } +} + +func TestAPIKeyStoreCreateListAndRevoke(t *testing.T) { + ctx := context.Background() + store := NewAPIKeyStore(newFakeMonCommander()) + now := time.Now().UTC() + rec := APIKeyRecord{ + ID: "ak_test", + Name: "test-key", + Owner: "user:admin", + SecretHash: hashAPIKeySecret("secret"), + Enabled: true, + CreatedAt: now, + CreatedBy: "user:admin", + } + + if err := store.Create(ctx, rec); err != nil { + t.Fatalf("Create() error = %v", err) + } + got, err := store.Get(ctx, rec.ID) + if err != nil { + t.Fatalf("Get() error = %v", err) + } + if got.ID != rec.ID || got.SecretHash != rec.SecretHash { + t.Fatalf("Get() = %+v, want persisted record", got) + } + listed, err := store.List(ctx) + if err != nil { + t.Fatalf("List() error = %v", err) + } + if len(listed) != 1 || listed[0].ID != rec.ID { + t.Fatalf("List() = %+v, want one record", listed) + } + if store.mon.(*fakeMonCommander).dumps != 1 { + t.Fatalf("config-key dump count = %d, want 1", store.mon.(*fakeMonCommander).dumps) + } + revoked, err := store.Revoke(ctx, rec.ID, now.Add(time.Minute)) + if err != nil { + t.Fatalf("Revoke() error = %v", err) + } + if revoked.Enabled || revoked.RevokedAt == nil { + t.Fatalf("Revoke() = %+v, want disabled record with revoked_at", revoked) + } +} + +func TestAPIKeyStoreTouchLastUsedDebouncesWrites(t *testing.T) { + ctx := context.Background() + mon := newFakeMonCommander() + store := NewAPIKeyStore(mon) + now := time.Now().UTC() + recent := now.Add(-apiKeyLastUsedDebounce / 2) + rec := APIKeyRecord{ + ID: "ak_test", + Name: "test-key", + Owner: "user:admin", + SecretHash: hashAPIKeySecret("secret"), + Enabled: true, + CreatedAt: now, + CreatedBy: "user:admin", + LastUsedAt: &recent, + } + if err := store.Create(ctx, rec); err != nil { + t.Fatalf("Create() error = %v", err) + } + if err := store.TouchLastUsed(ctx, rec, now); err != nil { + t.Fatalf("TouchLastUsed() recent error = %v", err) + } + if mon.sets != 1 { + t.Fatalf("sets after recent touch = %d, want 1", mon.sets) + } + + stale := now.Add(-apiKeyLastUsedDebounce * 2) + rec.LastUsedAt = &stale + if err := store.store(ctx, rec); err != nil { + t.Fatalf("store stale record: %v", err) + } + if err := store.TouchLastUsed(ctx, rec, now); err != nil { + t.Fatalf("TouchLastUsed() stale error = %v", err) + } + if mon.sets != 3 { + t.Fatalf("sets after stale touch = %d, want 3", mon.sets) + } +} + +func TestAPIKeyStoreShouldTouchLastUsedDebouncesInMemory(t *testing.T) { + store := NewAPIKeyStore(newFakeMonCommander()) + now := time.Now().UTC() + stale := now.Add(-apiKeyLastUsedDebounce * 2) + recent := now.Add(-apiKeyLastUsedDebounce / 2) + + if store.shouldTouchLastUsed(APIKeyRecord{ID: "ak_recent", LastUsedAt: &recent}, now) { + t.Fatal("ShouldTouchLastUsed() with recent persisted timestamp = true, want false") + } + if !store.shouldTouchLastUsed(APIKeyRecord{ID: "ak_stale", LastUsedAt: &stale}, now) { + t.Fatal("ShouldTouchLastUsed() first stale touch = false, want true") + } + if store.shouldTouchLastUsed(APIKeyRecord{ID: "ak_stale", LastUsedAt: &stale}, now.Add(time.Second)) { + t.Fatal("ShouldTouchLastUsed() repeated stale touch = true, want false") + } +} + +func TestAuthenticateAPIKeySetsContextMetadata(t *testing.T) { + ctx := context.Background() + store := NewAPIKeyStore(newFakeMonCommander()) + id, secret, token, err := newAPIKeyToken() + if err != nil { + t.Fatalf("newAPIKeyToken() error = %v", err) + } + if err := store.Create(ctx, APIKeyRecord{ + ID: id, + Name: "test-key", + Owner: "user:admin", + SecretHash: hashAPIKeySecret(secret), + Enabled: true, + CreatedAt: time.Now().UTC(), + CreatedBy: "user:admin", + }); err != nil { + t.Fatalf("Create() error = %v", err) + } + + gotCtx, err := authenticateAPIKey(ctx, token, store) + if err != nil { + t.Fatalf("authenticateAPIKey() error = %v", err) + } + if got := xctx.GetAuthType(gotCtx); got != "api_key" { + t.Fatalf("auth type = %q, want api_key", got) + } + if got := xctx.GetAPIKeyID(gotCtx); got != id { + t.Fatalf("api key id = %q, want %q", got, id) + } + if got := xctx.GetUsername(gotCtx); got != "apikey:"+id { + t.Fatalf("username = %q, want apikey subject", got) + } + if len(xctx.GetPermissions(gotCtx)) == 0 { + t.Fatal("permissions are empty, want administrator permissions") + } +} + +func TestServerAPIKeyCRUDRequiresJWTAdministrator(t *testing.T) { + ctx := context.Background() + ctx = xctx.SetUsername(ctx, "admin") + ctx = xctx.SetAuthType(ctx, "jwt") + ctx = xctx.SetRoles(ctx, []string{"administrator"}) + server := &Server{apiKeyStore: NewAPIKeyStore(newFakeMonCommander())} + + rec, token, err := server.CreateAPIKey(ctx, CreateAPIKeyRequest{Name: "terraform"}) + if err != nil { + t.Fatalf("CreateAPIKey() error = %v", err) + } + if token == "" || rec.ID == "" || rec.SecretHash == "" { + t.Fatalf("CreateAPIKey() returned incomplete key: rec=%+v token=%q", rec, token) + } + + listed, err := server.ListAPIKeys(ctx) + if err != nil { + t.Fatalf("ListAPIKeys() error = %v", err) + } + if len(listed) != 1 || listed[0].ID != rec.ID { + t.Fatalf("ListAPIKeys() = %+v, want created key", listed) + } + if err := server.RevokeAPIKey(ctx, rec.ID); err != nil { + t.Fatalf("RevokeAPIKey() error = %v", err) + } + revoked, err := server.GetAPIKey(ctx, rec.ID) + if err != nil { + t.Fatalf("GetAPIKey() error = %v", err) + } + if revoked.Enabled || revoked.RevokedAt == nil { + t.Fatalf("revoked key = %+v, want disabled with revoked_at", revoked) + } + + apiKeyCtx := xctx.SetAuthType(ctx, "api_key") + if _, _, err := server.CreateAPIKey(apiKeyCtx, CreateAPIKeyRequest{Name: "blocked"}); err == nil { + t.Fatal("CreateAPIKey() with API-key auth succeeded, want access denied") + } +} diff --git a/pkg/auth/discovery_handler.go b/pkg/auth/discovery_handler.go index 781f322..3344552 100644 --- a/pkg/auth/discovery_handler.go +++ b/pkg/auth/discovery_handler.go @@ -42,13 +42,17 @@ type jwk struct { } func (s *Server) DiscoveryEndpoint(w http.ResponseWriter, r *http.Request) { + modes := []string{"password"} + if s.apiKeyStore != nil { + modes = append(modes, "api_key") + } writeJSON(w, discoveryDocument{ Auth: discoveryAuth{ Issuer: s.issuer, Audience: s.clientID, TokenEndpoint: tokenEndpoint, RevokeEndpoint: revokeEndpoint, - Modes: []string{"password"}, + Modes: modes, }, JWKSURI: jwksURI, }) diff --git a/pkg/auth/grpc_interceptor.go b/pkg/auth/grpc_interceptor.go index 987b3c4..80dacf7 100644 --- a/pkg/auth/grpc_interceptor.go +++ b/pkg/auth/grpc_interceptor.go @@ -4,6 +4,7 @@ import ( "context" "crypto/rsa" "fmt" + "strings" xctx "github.com/clyso/ceph-api/pkg/ctx" "github.com/clyso/ceph-api/pkg/log" @@ -19,7 +20,7 @@ import ( "google.golang.org/grpc/status" ) -func AuthFunc(userSvc *user.Service, provider fosite.OAuth2Provider, getKey func() *rsa.PublicKey) grpc_auth.AuthFunc { +func AuthFunc(userSvc *user.Service, provider fosite.OAuth2Provider, getKey func() *rsa.PublicKey, apiKeyStore *APIKeyStore) grpc_auth.AuthFunc { return func(ctx context.Context) (context.Context, error) { method, ok := grpc.Method(ctx) if !ok { @@ -36,6 +37,9 @@ func AuthFunc(userSvc *user.Service, provider fosite.OAuth2Provider, getKey func zerolog.Ctx(ctx).Err(err).Msg("unable to extract bearer token from grpc meta") return nil, unauthenticated(fmt.Errorf("no token present: %w", types.ErrUnauthenticated)) } + if strings.HasPrefix(tokenStr, apiKeyTokenPrefix) { + return authenticateAPIKey(ctx, tokenStr, apiKeyStore) + } _, ar, err := provider.IntrospectToken(ctx, tokenStr, fosite.AccessToken, new(fosite.DefaultSession)) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("unable to introspect token") diff --git a/pkg/auth/keystore_test.go b/pkg/auth/keystore_test.go index 696ea9f..4cf3060 100644 --- a/pkg/auth/keystore_test.go +++ b/pkg/auth/keystore_test.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "errors" + "strings" + "sync" "testing" "github.com/clyso/ceph-api/pkg/types" @@ -97,8 +99,10 @@ func TestNewServerUsesProvidedKID(t *testing.T) { } type fakeMonCommander struct { + sync.Mutex values map[string][]byte sets int + dumps int } func newFakeMonCommander() *fakeMonCommander { @@ -106,6 +110,8 @@ func newFakeMonCommander() *fakeMonCommander { } func (f *fakeMonCommander) ExecMon(_ context.Context, cmd string) ([]byte, error) { + f.Lock() + defer f.Unlock() var req struct { Prefix string `json:"prefix"` Key string `json:"key"` @@ -113,6 +119,16 @@ func (f *fakeMonCommander) ExecMon(_ context.Context, cmd string) ([]byte, error if err := json.Unmarshal([]byte(cmd), &req); err != nil { return nil, err } + if req.Prefix == "config-key dump" { + f.dumps++ + values := make(map[string]string, len(f.values)) + for key, value := range f.values { + if req.Key == "" || strings.HasPrefix(key, req.Key) { + values[key] = string(value) + } + } + return json.Marshal(values) + } if req.Prefix != "config-key get" { return nil, errors.New("unexpected ExecMon command") } @@ -124,6 +140,8 @@ func (f *fakeMonCommander) ExecMon(_ context.Context, cmd string) ([]byte, error } func (f *fakeMonCommander) ExecMonWithInputBuff(_ context.Context, cmd string, in []byte) ([]byte, error) { + f.Lock() + defer f.Unlock() var req struct { Prefix string `json:"prefix"` Key string `json:"key"` diff --git a/pkg/auth/oauth_server.go b/pkg/auth/oauth_server.go index f09719b..d884c2e 100644 --- a/pkg/auth/oauth_server.go +++ b/pkg/auth/oauth_server.go @@ -29,7 +29,8 @@ type Server struct { refreshTokenStrategy oauth2.RefreshTokenStrategy accessTokenStrategy oauth2.AccessTokenStrategy - userSvc *user.Service + userSvc *user.Service + apiKeyStore *APIKeyStore } func NewServer(config Config, userSvc *user.Service, privateKey *rsa.PrivateKey, kid string, globalSecret []byte) (*Server, error) { diff --git a/pkg/user/service.go b/pkg/user/service.go index 7475284..1d60d5d 100644 --- a/pkg/user/service.go +++ b/pkg/user/service.go @@ -36,6 +36,15 @@ func HasPermissions(ctx context.Context, scope Scope, perms ...Permission) error return nil } +func AdministratorPermissions() map[string][]string { + role := systemRoleMap["administrator"] + res := make(map[string][]string, len(role.Permissions)) + for scope, perms := range role.Permissions { + res[scope] = append([]string(nil), perms...) + } + return res +} + func New(radosSvc *rados.Svc) (*Service, error) { res := &Service{radosSvc: radosSvc} if err := res.updateFromDB(context.Background()); err != nil { From 2228b9e9d61f2be7394e9a1d9ba00eb9a7cb49d4 Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Wed, 13 May 2026 23:09:52 +0000 Subject: [PATCH 2/6] pkg/auth: API key wiring and auth route prefixes Move Login/Logout/Check to /api/v1/auth/* NewServer takes apiKeyStore directly Signed-off-by: Joshua Blanch --- README.md | 2 +- api/auth.proto | 15 +- api/gen/grpc/go/auth.pb.go | 173 +++---- api/gen/grpc/go/auth.pb.gw.go | 402 ++++++++++----- api/gen/grpc/go/auth_grpc.pb.go | 49 +- api/gen/grpc/go/cluster.pb.gw.go | 401 ++++++++++----- api/gen/grpc/go/cluster_grpc.pb.go | 49 +- api/gen/grpc/go/crush_rule.pb.gw.go | 224 +++++--- api/gen/grpc/go/crush_rule_grpc.pb.go | 37 +- api/gen/grpc/go/status.pb.gw.go | 177 ++++--- api/gen/grpc/go/status_grpc.pb.go | 40 +- api/gen/grpc/go/users.pb.gw.go | 707 ++++++++++++++++++-------- api/gen/grpc/go/users_grpc.pb.go | 61 +-- api/http.yaml | 6 +- api/openapi/ceph-api.swagger.json | 199 ++++---- pkg/api/auth_api_handlers.go | 1 - pkg/app/start.go | 3 +- pkg/auth/apikey.go | 1 - pkg/auth/apikey_auth.go | 2 +- pkg/auth/apikey_handler.go | 5 - pkg/auth/apikey_store.go | 10 +- pkg/auth/apikey_test.go | 121 ++++- pkg/auth/discovery_handler.go | 30 +- pkg/auth/discovery_handler_test.go | 28 +- pkg/auth/keystore_test.go | 2 +- pkg/auth/oauth_adapter.go | 4 +- pkg/auth/oauth_server.go | 3 +- 27 files changed, 1724 insertions(+), 1028 deletions(-) diff --git a/README.md b/README.md index 4662b2b..8e2d867 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Each API user can have `READ`, `CREATE`, `UPDATE`, `DELETE` permission to Ceph r API authenticaiton usage can be found in [test/auth_test.go](./test/auth_test.go). But in general, client authentication can be handled by any client http/gRPC library supporting OAuth2.0. -There is alternative auth API under `/api/auth` path (see [open api](./api/openapi/ceph-api.swagger.json)). This API is **not** implementing OAuth spec and exists for backwards compatibility with old Ceph API. This old api also does not have refresh token feature. +There is alternative auth API under `/api/v1/auth/login`, `/api/v1/auth/logout`, and `/api/v1/auth/check` (see [open api](./api/openapi/ceph-api.swagger.json)). This API is **not** implementing OAuth spec and exists for backwards compatibility with old Ceph API. This old api also does not have refresh token feature. ## Clients diff --git a/api/auth.proto b/api/auth.proto index 7c8cfd4..35e6f92 100644 --- a/api/auth.proto +++ b/api/auth.proto @@ -81,14 +81,13 @@ message APIKeyResp{ string id =1; string name =2; string description =3; - string owner =4; - string cluster_id =5; - bool enabled =6; - optional google.protobuf.Timestamp revoked_at =7; - optional google.protobuf.Timestamp created_at =8; - string created_by =9; - optional google.protobuf.Timestamp expires_at =10; - optional google.protobuf.Timestamp last_used_at =11; + string cluster_id =4; + bool enabled =5; + optional google.protobuf.Timestamp revoked_at =6; + optional google.protobuf.Timestamp created_at =7; + string created_by =8; + optional google.protobuf.Timestamp expires_at =9; + optional google.protobuf.Timestamp last_used_at =10; } option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { diff --git a/api/gen/grpc/go/auth.pb.go b/api/gen/grpc/go/auth.pb.go index 9539731..07f0e27 100644 --- a/api/gen/grpc/go/auth.pb.go +++ b/api/gen/grpc/go/auth.pb.go @@ -638,14 +638,13 @@ type APIKeyResp struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty"` - ClusterId string `protobuf:"bytes,5,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` - Enabled bool `protobuf:"varint,6,opt,name=enabled,proto3" json:"enabled,omitempty"` - RevokedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=revoked_at,json=revokedAt,proto3,oneof" json:"revoked_at,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3,oneof" json:"created_at,omitempty"` - CreatedBy string `protobuf:"bytes,9,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` - ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` - LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=last_used_at,json=lastUsedAt,proto3,oneof" json:"last_used_at,omitempty"` + ClusterId string `protobuf:"bytes,4,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + Enabled bool `protobuf:"varint,5,opt,name=enabled,proto3" json:"enabled,omitempty"` + RevokedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=revoked_at,json=revokedAt,proto3,oneof" json:"revoked_at,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3,oneof" json:"created_at,omitempty"` + CreatedBy string `protobuf:"bytes,8,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_used_at,json=lastUsedAt,proto3,oneof" json:"last_used_at,omitempty"` } func (x *APIKeyResp) Reset() { @@ -701,13 +700,6 @@ func (x *APIKeyResp) GetDescription() string { return "" } -func (x *APIKeyResp) GetOwner() string { - if x != nil { - return x.Owner - } - return "" -} - func (x *APIKeyResp) GetClusterId() string { if x != nil { return x.ClusterId @@ -866,88 +858,87 @@ var file_auth_proto_rawDesc = []byte{ 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x28, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, - 0x81, 0x04, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, + 0xeb, 0x03, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x07, 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, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, - 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x08, 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, 0x48, 0x01, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x42, 0x79, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, - 0x18, 0x0a, 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, 0x48, 0x02, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, - 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x0b, 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, 0x48, 0x03, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, - 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, - 0x61, 0x74, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x32, 0xc1, 0x03, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x05, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x0e, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x38, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, + 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, + 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 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, 0x48, 0x01, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x3e, 0x0a, 0x0a, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x09, 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, 0x48, 0x02, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 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, 0x48, 0x03, + 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, + 0x0d, 0x0a, 0x0b, 0x5f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, + 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, + 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x42, 0x0f, 0x0a, 0x0d, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x32, 0xc1, 0x03, + 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, + 0x0e, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, + 0x0f, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x38, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x12, 0x32, + 0x0a, 0x06, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x32, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x63, 0x65, 0x70, 0x68, - 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x14, - 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x12, 0x32, 0x0a, 0x06, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x57, 0x68, - 0x6f, 0x61, 0x6d, 0x69, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, - 0x16, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, - 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, - 0x65, 0x79, 0x12, 0x12, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, - 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, - 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0xcc, 0x02, 0x92, 0x41, 0xa1, 0x02, 0x12, 0x8c, - 0x01, 0x0a, 0x13, 0x43, 0x65, 0x70, 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x41, 0x50, 0x49, 0x22, 0x2d, 0x0a, 0x08, 0x43, 0x65, 0x70, 0x68, 0x20, 0x41, - 0x50, 0x49, 0x12, 0x21, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, + 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x57, 0x68, 0x6f, 0x61, 0x6d, 0x69, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x63, 0x65, 0x70, 0x68, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x2e, 0x63, + 0x65, 0x70, 0x68, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, + 0x1a, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x3d, 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x12, 0x15, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x42, 0xcc, 0x02, 0x92, 0x41, 0xa1, 0x02, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x43, 0x65, 0x70, + 0x68, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x50, 0x49, + 0x22, 0x2d, 0x0a, 0x08, 0x43, 0x65, 0x70, 0x68, 0x20, 0x41, 0x50, 0x49, 0x12, 0x21, 0x68, 0x74, + 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2a, + 0x46, 0x0a, 0x0f, 0x47, 0x50, 0x4c, 0x2d, 0x33, 0x2e, 0x30, 0x20, 0x6c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x12, 0x33, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, - 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2a, 0x46, 0x0a, 0x0f, 0x47, 0x50, 0x4c, 0x2d, 0x33, 0x2e, 0x30, - 0x20, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, - 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x62, - 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x2a, 0x02, 0x01, - 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, - 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x5a, 0x52, 0x0a, 0x50, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, - 0x32, 0x12, 0x46, 0x08, 0x03, 0x28, 0x02, 0x3a, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x39, 0x39, 0x36, 0x39, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x19, - 0x0a, 0x17, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x12, 0x0d, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x62, 0x14, 0x0a, 0x12, 0x0a, 0x06, 0x4f, - 0x41, 0x75, 0x74, 0x68, 0x32, 0x12, 0x08, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x5a, - 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, - 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, - 0x65, 0x70, 0x68, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, + 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x5a, + 0x52, 0x0a, 0x50, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x12, 0x46, 0x08, 0x03, 0x28, + 0x02, 0x3a, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, + 0x6f, 0x73, 0x74, 0x3a, 0x39, 0x39, 0x36, 0x39, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6f, 0x61, 0x75, + 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x19, 0x0a, 0x17, 0x0a, 0x06, 0x6f, 0x70, + 0x65, 0x6e, 0x69, 0x64, 0x12, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x62, 0x14, 0x0a, 0x12, 0x0a, 0x06, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x12, + 0x08, 0x0a, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6c, 0x79, 0x73, 0x6f, 0x2f, 0x63, 0x65, 0x70, 0x68, + 0x2d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x65, 0x70, 0x68, 0x3b, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/gen/grpc/go/auth.pb.gw.go b/api/gen/grpc/go/auth.pb.gw.go index f8e99a2..66cb50c 100644 --- a/api/gen/grpc/go/auth.pb.gw.go +++ b/api/gen/grpc/go/auth.pb.gw.go @@ -10,7 +10,6 @@ package pb import ( "context" - "errors" "io" "net/http" @@ -26,233 +25,272 @@ import ( ) // Suppress "imported and not used" errors -var ( - _ codes.Code - _ io.Reader - _ status.Status - _ = errors.New - _ = runtime.String - _ = utilities.NewDoubleArray - _ = metadata.Join -) +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join func request_Auth_Login_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq LoginReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq LoginReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.Login(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_Login_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq LoginReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq LoginReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.Login(ctx, &protoReq) return msg, metadata, err + } func request_Auth_Logout_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.Logout(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_Logout_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.Logout(ctx, &protoReq) return msg, metadata, err + } func request_Auth_Check_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq TokenCheckReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq TokenCheckReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.Check(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_Check_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq TokenCheckReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq TokenCheckReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.Check(ctx, &protoReq) return msg, metadata, err + } func request_Auth_Whoami_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.Whoami(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_Whoami_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.Whoami(ctx, &protoReq) return msg, metadata, err + } func request_Auth_CreateAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateAPIKeyReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateAPIKeyReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CreateAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_CreateAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateAPIKeyReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateAPIKeyReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CreateAPIKey(ctx, &protoReq) return msg, metadata, err + } func request_Auth_ListAPIKeys_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.ListAPIKeys(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_ListAPIKeys_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.ListAPIKeys(ctx, &protoReq) return msg, metadata, err + } func request_Auth_GetAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetAPIKeyReq + var metadata runtime.ServerMetadata + var ( - protoReq GetAPIKeyReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["key_id"] + + val, ok = pathParams["key_id"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") } + protoReq.KeyId, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) } + msg, err := client.GetAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_GetAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetAPIKeyReq + var metadata runtime.ServerMetadata + var ( - protoReq GetAPIKeyReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["key_id"] + + val, ok = pathParams["key_id"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") } + protoReq.KeyId, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) } + msg, err := server.GetAPIKey(ctx, &protoReq) return msg, metadata, err + } func request_Auth_RevokeAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RevokeAPIKeyReq + var metadata runtime.ServerMetadata + var ( - protoReq RevokeAPIKeyReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["key_id"] + + val, ok = pathParams["key_id"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") } + protoReq.KeyId, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) } + msg, err := client.RevokeAPIKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Auth_RevokeAPIKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RevokeAPIKeyReq + var metadata runtime.ServerMetadata + var ( - protoReq RevokeAPIKeyReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["key_id"] + + val, ok = pathParams["key_id"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key_id") } + protoReq.KeyId, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key_id", err) } + msg, err := server.RevokeAPIKey(ctx, &protoReq) return msg, metadata, err + } // RegisterAuthHandlerServer registers the http handlers for service Auth to "mux". // UnaryRPC :call AuthServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthHandlerFromEndpoint instead. -// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServer) error { - mux.Handle(http.MethodPost, pattern_Auth_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Login", runtime.WithHTTPPathPattern("/api/auth")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Login", runtime.WithHTTPPathPattern("/api/v1/auth/login")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -264,15 +302,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Login_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_Logout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Logout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Logout", runtime.WithHTTPPathPattern("/api/auth/logout")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Logout", runtime.WithHTTPPathPattern("/api/v1/auth/logout")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -284,15 +327,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Logout_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Check", runtime.WithHTTPPathPattern("/api/auth/check")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Check", runtime.WithHTTPPathPattern("/api/v1/auth/check")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -304,15 +352,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Check_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_Whoami_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_Whoami_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Whoami", runtime.WithHTTPPathPattern("/api/v1/auth/whoami")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/Whoami", runtime.WithHTTPPathPattern("/api/v1/auth/whoami")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -324,15 +377,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Whoami_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_CreateAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_CreateAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -344,15 +402,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_CreateAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_ListAPIKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_ListAPIKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -364,15 +427,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp.(*ListAPIKeysResp)}, mux.GetForwardResponseOptions()...) + + forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_GetAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_GetAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -384,15 +452,20 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_GetAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Auth_RevokeAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Auth_RevokeAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -404,7 +477,9 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_RevokeAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil @@ -413,24 +488,25 @@ func RegisterAuthHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve // RegisterAuthHandlerFromEndpoint is same as RegisterAuthHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterAuthHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.NewClient(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } }() }() + return RegisterAuthHandler(ctx, mux, conn) } @@ -444,13 +520,16 @@ func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc. // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "AuthClient" to call the correct interceptors. This client ignores the HTTP middlewares. +// "AuthClient" to call the correct interceptors. func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthClient) error { - mux.Handle(http.MethodPost, pattern_Auth_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Login_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Login", runtime.WithHTTPPathPattern("/api/auth")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Login", runtime.WithHTTPPathPattern("/api/v1/auth/login")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -461,13 +540,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Login_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_Logout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Logout_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Logout", runtime.WithHTTPPathPattern("/api/auth/logout")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Logout", runtime.WithHTTPPathPattern("/api/v1/auth/logout")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -478,13 +562,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Logout_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_Check_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Check", runtime.WithHTTPPathPattern("/api/auth/check")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Check", runtime.WithHTTPPathPattern("/api/v1/auth/check")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -495,13 +584,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Check_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_Whoami_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_Whoami_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Whoami", runtime.WithHTTPPathPattern("/api/v1/auth/whoami")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/Whoami", runtime.WithHTTPPathPattern("/api/v1/auth/whoami")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -512,13 +606,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_Whoami_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Auth_CreateAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Auth_CreateAPIKey_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/CreateAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -529,13 +628,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_CreateAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_ListAPIKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_ListAPIKeys_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/ListAPIKeys", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -546,13 +650,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp.(*ListAPIKeysResp)}, mux.GetForwardResponseOptions()...) + + forward_Auth_ListAPIKeys_0(annotatedContext, mux, outboundMarshaler, w, req, response_Auth_ListAPIKeys_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Auth_GetAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Auth_GetAPIKey_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/GetAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -563,13 +672,18 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_GetAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Auth_RevokeAPIKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Auth_RevokeAPIKey_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Auth/RevokeAPIKey", runtime.WithHTTPPathPattern("/api/v1/auth/api-keys/{key_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -580,37 +694,55 @@ func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Auth_RevokeAPIKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } type response_Auth_ListAPIKeys_0 struct { - *ListAPIKeysResp + proto.Message } func (m response_Auth_ListAPIKeys_0) XXX_ResponseBody() interface{} { - return m.Keys + response := m.Message.(*ListAPIKeysResp) + return response.Keys } var ( - pattern_Auth_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "auth"}, "")) - pattern_Auth_Logout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "logout"}, "")) - pattern_Auth_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "auth", "check"}, "")) - pattern_Auth_Whoami_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "whoami"}, "")) + pattern_Auth_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "login"}, "")) + + pattern_Auth_Logout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "logout"}, "")) + + pattern_Auth_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "check"}, "")) + + pattern_Auth_Whoami_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "whoami"}, "")) + pattern_Auth_CreateAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "api-keys"}, "")) - pattern_Auth_ListAPIKeys_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "api-keys"}, "")) - pattern_Auth_GetAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"api", "v1", "auth", "api-keys", "key_id"}, "")) + + pattern_Auth_ListAPIKeys_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "api-keys"}, "")) + + pattern_Auth_GetAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"api", "v1", "auth", "api-keys", "key_id"}, "")) + pattern_Auth_RevokeAPIKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"api", "v1", "auth", "api-keys", "key_id"}, "")) ) var ( - forward_Auth_Login_0 = runtime.ForwardResponseMessage - forward_Auth_Logout_0 = runtime.ForwardResponseMessage - forward_Auth_Check_0 = runtime.ForwardResponseMessage - forward_Auth_Whoami_0 = runtime.ForwardResponseMessage + forward_Auth_Login_0 = runtime.ForwardResponseMessage + + forward_Auth_Logout_0 = runtime.ForwardResponseMessage + + forward_Auth_Check_0 = runtime.ForwardResponseMessage + + forward_Auth_Whoami_0 = runtime.ForwardResponseMessage + forward_Auth_CreateAPIKey_0 = runtime.ForwardResponseMessage - forward_Auth_ListAPIKeys_0 = runtime.ForwardResponseMessage - forward_Auth_GetAPIKey_0 = runtime.ForwardResponseMessage + + forward_Auth_ListAPIKeys_0 = runtime.ForwardResponseMessage + + forward_Auth_GetAPIKey_0 = runtime.ForwardResponseMessage + forward_Auth_RevokeAPIKey_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/auth_grpc.pb.go b/api/gen/grpc/go/auth_grpc.pb.go index 6fd40ac..cb411ea 100644 --- a/api/gen/grpc/go/auth_grpc.pb.go +++ b/api/gen/grpc/go/auth_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: auth.proto @@ -16,8 +16,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( Auth_Login_FullMethodName = "/ceph.Auth/Login" @@ -53,9 +53,8 @@ func NewAuthClient(cc grpc.ClientConnInterface) AuthClient { } func (c *authClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(LoginResp) - err := c.cc.Invoke(ctx, Auth_Login_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_Login_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -63,9 +62,8 @@ func (c *authClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallO } func (c *authClient) Logout(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Auth_Logout_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_Logout_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -73,9 +71,8 @@ func (c *authClient) Logout(ctx context.Context, in *emptypb.Empty, opts ...grpc } func (c *authClient) Check(ctx context.Context, in *TokenCheckReq, opts ...grpc.CallOption) (*TokenCheckResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(TokenCheckResp) - err := c.cc.Invoke(ctx, Auth_Check_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_Check_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -83,9 +80,8 @@ func (c *authClient) Check(ctx context.Context, in *TokenCheckReq, opts ...grpc. } func (c *authClient) Whoami(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*WhoamiResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(WhoamiResp) - err := c.cc.Invoke(ctx, Auth_Whoami_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_Whoami_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -93,9 +89,8 @@ func (c *authClient) Whoami(ctx context.Context, in *emptypb.Empty, opts ...grpc } func (c *authClient) CreateAPIKey(ctx context.Context, in *CreateAPIKeyReq, opts ...grpc.CallOption) (*CreateAPIKeyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateAPIKeyResp) - err := c.cc.Invoke(ctx, Auth_CreateAPIKey_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_CreateAPIKey_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -103,9 +98,8 @@ func (c *authClient) CreateAPIKey(ctx context.Context, in *CreateAPIKeyReq, opts } func (c *authClient) ListAPIKeys(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListAPIKeysResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListAPIKeysResp) - err := c.cc.Invoke(ctx, Auth_ListAPIKeys_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_ListAPIKeys_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -113,9 +107,8 @@ func (c *authClient) ListAPIKeys(ctx context.Context, in *emptypb.Empty, opts .. } func (c *authClient) GetAPIKey(ctx context.Context, in *GetAPIKeyReq, opts ...grpc.CallOption) (*APIKeyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(APIKeyResp) - err := c.cc.Invoke(ctx, Auth_GetAPIKey_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_GetAPIKey_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -123,9 +116,8 @@ func (c *authClient) GetAPIKey(ctx context.Context, in *GetAPIKeyReq, opts ...gr } func (c *authClient) RevokeAPIKey(ctx context.Context, in *RevokeAPIKeyReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Auth_RevokeAPIKey_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Auth_RevokeAPIKey_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -134,7 +126,7 @@ func (c *authClient) RevokeAPIKey(ctx context.Context, in *RevokeAPIKeyReq, opts // AuthServer is the server API for Auth service. // All implementations should embed UnimplementedAuthServer -// for forward compatibility. +// for forward compatibility type AuthServer interface { Login(context.Context, *LoginReq) (*LoginResp, error) Logout(context.Context, *emptypb.Empty) (*emptypb.Empty, error) @@ -146,12 +138,9 @@ type AuthServer interface { RevokeAPIKey(context.Context, *RevokeAPIKeyReq) (*emptypb.Empty, error) } -// UnimplementedAuthServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedAuthServer struct{} +// UnimplementedAuthServer should be embedded to have forward compatible implementations. +type UnimplementedAuthServer struct { +} func (UnimplementedAuthServer) Login(context.Context, *LoginReq) (*LoginResp, error) { return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") @@ -177,7 +166,6 @@ func (UnimplementedAuthServer) GetAPIKey(context.Context, *GetAPIKeyReq) (*APIKe func (UnimplementedAuthServer) RevokeAPIKey(context.Context, *RevokeAPIKeyReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method RevokeAPIKey not implemented") } -func (UnimplementedAuthServer) testEmbeddedByValue() {} // UnsafeAuthServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to AuthServer will @@ -187,13 +175,6 @@ type UnsafeAuthServer interface { } func RegisterAuthServer(s grpc.ServiceRegistrar, srv AuthServer) { - // If the following call pancis, it indicates UnimplementedAuthServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&Auth_ServiceDesc, srv) } diff --git a/api/gen/grpc/go/cluster.pb.gw.go b/api/gen/grpc/go/cluster.pb.gw.go index a135814..62c9f05 100644 --- a/api/gen/grpc/go/cluster.pb.gw.go +++ b/api/gen/grpc/go/cluster.pb.gw.go @@ -10,7 +10,6 @@ package pb import ( "context" - "errors" "io" "net/http" @@ -26,229 +25,256 @@ import ( ) // Suppress "imported and not used" errors -var ( - _ codes.Code - _ io.Reader - _ status.Status - _ = errors.New - _ = runtime.String - _ = utilities.NewDoubleArray - _ = metadata.Join -) +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join func request_Cluster_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetStatus(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_UpdateStatus_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ClusterStatus - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq ClusterStatus + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.UpdateStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_UpdateStatus_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ClusterStatus - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq ClusterStatus + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.UpdateStatus(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_GetUsers_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_GetUsers_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetUsers(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq UpdateClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq UpdateClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.UpdateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq UpdateClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq UpdateClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.UpdateUser(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CreateUser(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_ExportUser_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ExportClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq ExportClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.ExportUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_ExportUser_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq ExportClusterUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq ExportClusterUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.ExportUser(ctx, &protoReq) return msg, metadata, err + } func request_Cluster_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteClusterUserReq + var metadata runtime.ServerMetadata + var ( - protoReq DeleteClusterUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["user_entity"] + + val, ok = pathParams["user_entity"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user_entity") } + protoReq.UserEntity, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user_entity", err) } + msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteClusterUserReq + var metadata runtime.ServerMetadata + var ( - protoReq DeleteClusterUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["user_entity"] + + val, ok = pathParams["user_entity"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user_entity") } + protoReq.UserEntity, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user_entity", err) } + msg, err := server.DeleteUser(ctx, &protoReq) return msg, metadata, err + } -var filter_Cluster_SearchConfig_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +var ( + filter_Cluster_SearchConfig_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) func request_Cluster_SearchConfig_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq SearchConfigRequest - metadata runtime.ServerMetadata - ) + var protoReq SearchConfigRequest + var metadata runtime.ServerMetadata + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Cluster_SearchConfig_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.SearchConfig(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Cluster_SearchConfig_0(ctx context.Context, marshaler runtime.Marshaler, server ClusterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq SearchConfigRequest - metadata runtime.ServerMetadata - ) + var protoReq SearchConfigRequest + var metadata runtime.ServerMetadata + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Cluster_SearchConfig_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.SearchConfig(ctx, &protoReq) return msg, metadata, err + } // RegisterClusterHandlerServer registers the http handlers for service Cluster to "mux". // UnaryRPC :call ClusterServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterClusterHandlerFromEndpoint instead. -// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ClusterServer) error { - mux.Handle(http.MethodGet, pattern_Cluster_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/GetStatus", runtime.WithHTTPPathPattern("/api/cluster")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/GetStatus", runtime.WithHTTPPathPattern("/api/cluster")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -260,15 +286,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_GetStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Cluster_UpdateStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Cluster_UpdateStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/UpdateStatus", runtime.WithHTTPPathPattern("/api/cluster")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/UpdateStatus", runtime.WithHTTPPathPattern("/api/cluster")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -280,15 +311,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_UpdateStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Cluster_GetUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_GetUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/GetUsers", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/GetUsers", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -300,15 +336,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Cluster_GetUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_GetUsers_0{resp.(*ClusterUsers)}, mux.GetForwardResponseOptions()...) + + forward_Cluster_GetUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_GetUsers_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Cluster_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Cluster_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/UpdateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/UpdateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -320,15 +361,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Cluster_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Cluster_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/CreateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/CreateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -340,15 +386,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Cluster_ExportUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Cluster_ExportUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/ExportUser", runtime.WithHTTPPathPattern("/api/cluster/user/export")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/ExportUser", runtime.WithHTTPPathPattern("/api/cluster/user/export")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -360,15 +411,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Cluster_ExportUser_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_ExportUser_0{resp.(*ExportClusterUserResp)}, mux.GetForwardResponseOptions()...) + + forward_Cluster_ExportUser_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_ExportUser_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Cluster_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Cluster_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/DeleteUser", runtime.WithHTTPPathPattern("/api/cluster/user/{user_entity}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/DeleteUser", runtime.WithHTTPPathPattern("/api/cluster/user/{user_entity}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -380,15 +436,20 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Cluster_SearchConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_SearchConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/SearchConfig", runtime.WithHTTPPathPattern("/api/cluster/config/search")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Cluster/SearchConfig", runtime.WithHTTPPathPattern("/api/cluster/config/search")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -400,7 +461,9 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_SearchConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil @@ -409,24 +472,25 @@ func RegisterClusterHandlerServer(ctx context.Context, mux *runtime.ServeMux, se // RegisterClusterHandlerFromEndpoint is same as RegisterClusterHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterClusterHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.NewClient(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } }() }() + return RegisterClusterHandler(ctx, mux, conn) } @@ -440,13 +504,16 @@ func RegisterClusterHandler(ctx context.Context, mux *runtime.ServeMux, conn *gr // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ClusterClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ClusterClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "ClusterClient" to call the correct interceptors. This client ignores the HTTP middlewares. +// "ClusterClient" to call the correct interceptors. func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ClusterClient) error { - mux.Handle(http.MethodGet, pattern_Cluster_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_GetStatus_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/GetStatus", runtime.WithHTTPPathPattern("/api/cluster")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/GetStatus", runtime.WithHTTPPathPattern("/api/cluster")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -457,13 +524,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_GetStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Cluster_UpdateStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Cluster_UpdateStatus_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/UpdateStatus", runtime.WithHTTPPathPattern("/api/cluster")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/UpdateStatus", runtime.WithHTTPPathPattern("/api/cluster")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -474,13 +546,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_UpdateStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Cluster_GetUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_GetUsers_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/GetUsers", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/GetUsers", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -491,13 +568,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Cluster_GetUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_GetUsers_0{resp.(*ClusterUsers)}, mux.GetForwardResponseOptions()...) + + forward_Cluster_GetUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_GetUsers_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Cluster_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Cluster_UpdateUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/UpdateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/UpdateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -508,13 +590,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Cluster_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Cluster_CreateUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/CreateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/CreateUser", runtime.WithHTTPPathPattern("/api/cluster/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -525,13 +612,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Cluster_ExportUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Cluster_ExportUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/ExportUser", runtime.WithHTTPPathPattern("/api/cluster/user/export")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/ExportUser", runtime.WithHTTPPathPattern("/api/cluster/user/export")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -542,13 +634,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Cluster_ExportUser_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_ExportUser_0{resp.(*ExportClusterUserResp)}, mux.GetForwardResponseOptions()...) + + forward_Cluster_ExportUser_0(annotatedContext, mux, outboundMarshaler, w, req, response_Cluster_ExportUser_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Cluster_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Cluster_DeleteUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/DeleteUser", runtime.WithHTTPPathPattern("/api/cluster/user/{user_entity}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/DeleteUser", runtime.WithHTTPPathPattern("/api/cluster/user/{user_entity}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -559,13 +656,18 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Cluster_SearchConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Cluster_SearchConfig_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/SearchConfig", runtime.WithHTTPPathPattern("/api/cluster/config/search")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Cluster/SearchConfig", runtime.WithHTTPPathPattern("/api/cluster/config/search")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -576,45 +678,64 @@ func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Cluster_SearchConfig_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } type response_Cluster_GetUsers_0 struct { - *ClusterUsers + proto.Message } func (m response_Cluster_GetUsers_0) XXX_ResponseBody() interface{} { - return m.Users + response := m.Message.(*ClusterUsers) + return response.Users } type response_Cluster_ExportUser_0 struct { - *ExportClusterUserResp + proto.Message } func (m response_Cluster_ExportUser_0) XXX_ResponseBody() interface{} { - return m.Data + response := m.Message.(*ExportClusterUserResp) + return response.Data } var ( - pattern_Cluster_GetStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "cluster"}, "")) + pattern_Cluster_GetStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "cluster"}, "")) + pattern_Cluster_UpdateStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "cluster"}, "")) - pattern_Cluster_GetUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) - pattern_Cluster_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) - pattern_Cluster_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) - pattern_Cluster_ExportUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "cluster", "user", "export"}, "")) - pattern_Cluster_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "cluster", "user", "user_entity"}, "")) + + pattern_Cluster_GetUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) + + pattern_Cluster_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) + + pattern_Cluster_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "cluster", "user"}, "")) + + pattern_Cluster_ExportUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "cluster", "user", "export"}, "")) + + pattern_Cluster_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "cluster", "user", "user_entity"}, "")) + pattern_Cluster_SearchConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "cluster", "config", "search"}, "")) ) var ( - forward_Cluster_GetStatus_0 = runtime.ForwardResponseMessage + forward_Cluster_GetStatus_0 = runtime.ForwardResponseMessage + forward_Cluster_UpdateStatus_0 = runtime.ForwardResponseMessage - forward_Cluster_GetUsers_0 = runtime.ForwardResponseMessage - forward_Cluster_UpdateUser_0 = runtime.ForwardResponseMessage - forward_Cluster_CreateUser_0 = runtime.ForwardResponseMessage - forward_Cluster_ExportUser_0 = runtime.ForwardResponseMessage - forward_Cluster_DeleteUser_0 = runtime.ForwardResponseMessage + + forward_Cluster_GetUsers_0 = runtime.ForwardResponseMessage + + forward_Cluster_UpdateUser_0 = runtime.ForwardResponseMessage + + forward_Cluster_CreateUser_0 = runtime.ForwardResponseMessage + + forward_Cluster_ExportUser_0 = runtime.ForwardResponseMessage + + forward_Cluster_DeleteUser_0 = runtime.ForwardResponseMessage + forward_Cluster_SearchConfig_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/cluster_grpc.pb.go b/api/gen/grpc/go/cluster_grpc.pb.go index 7a40fce..f7ad676 100644 --- a/api/gen/grpc/go/cluster_grpc.pb.go +++ b/api/gen/grpc/go/cluster_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: cluster.proto @@ -16,8 +16,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( Cluster_GetStatus_FullMethodName = "/ceph.Cluster/GetStatus" @@ -55,9 +55,8 @@ func NewClusterClient(cc grpc.ClientConnInterface) ClusterClient { } func (c *clusterClient) GetStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ClusterStatus, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ClusterStatus) - err := c.cc.Invoke(ctx, Cluster_GetStatus_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_GetStatus_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -65,9 +64,8 @@ func (c *clusterClient) GetStatus(ctx context.Context, in *emptypb.Empty, opts . } func (c *clusterClient) UpdateStatus(ctx context.Context, in *ClusterStatus, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Cluster_UpdateStatus_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_UpdateStatus_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -75,9 +73,8 @@ func (c *clusterClient) UpdateStatus(ctx context.Context, in *ClusterStatus, opt } func (c *clusterClient) GetUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ClusterUsers, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ClusterUsers) - err := c.cc.Invoke(ctx, Cluster_GetUsers_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_GetUsers_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -85,9 +82,8 @@ func (c *clusterClient) GetUsers(ctx context.Context, in *emptypb.Empty, opts .. } func (c *clusterClient) UpdateUser(ctx context.Context, in *UpdateClusterUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Cluster_UpdateUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_UpdateUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -95,9 +91,8 @@ func (c *clusterClient) UpdateUser(ctx context.Context, in *UpdateClusterUserReq } func (c *clusterClient) CreateUser(ctx context.Context, in *CreateClusterUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Cluster_CreateUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_CreateUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -105,9 +100,8 @@ func (c *clusterClient) CreateUser(ctx context.Context, in *CreateClusterUserReq } func (c *clusterClient) ExportUser(ctx context.Context, in *ExportClusterUserReq, opts ...grpc.CallOption) (*ExportClusterUserResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ExportClusterUserResp) - err := c.cc.Invoke(ctx, Cluster_ExportUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_ExportUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -115,9 +109,8 @@ func (c *clusterClient) ExportUser(ctx context.Context, in *ExportClusterUserReq } func (c *clusterClient) DeleteUser(ctx context.Context, in *DeleteClusterUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Cluster_DeleteUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_DeleteUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -125,9 +118,8 @@ func (c *clusterClient) DeleteUser(ctx context.Context, in *DeleteClusterUserReq } func (c *clusterClient) SearchConfig(ctx context.Context, in *SearchConfigRequest, opts ...grpc.CallOption) (*SearchConfigResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(SearchConfigResponse) - err := c.cc.Invoke(ctx, Cluster_SearchConfig_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Cluster_SearchConfig_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -136,7 +128,7 @@ func (c *clusterClient) SearchConfig(ctx context.Context, in *SearchConfigReques // ClusterServer is the server API for Cluster service. // All implementations should embed UnimplementedClusterServer -// for forward compatibility. +// for forward compatibility type ClusterServer interface { // Get cluster status GetStatus(context.Context, *emptypb.Empty) (*ClusterStatus, error) @@ -150,12 +142,9 @@ type ClusterServer interface { SearchConfig(context.Context, *SearchConfigRequest) (*SearchConfigResponse, error) } -// UnimplementedClusterServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedClusterServer struct{} +// UnimplementedClusterServer should be embedded to have forward compatible implementations. +type UnimplementedClusterServer struct { +} func (UnimplementedClusterServer) GetStatus(context.Context, *emptypb.Empty) (*ClusterStatus, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") @@ -181,7 +170,6 @@ func (UnimplementedClusterServer) DeleteUser(context.Context, *DeleteClusterUser func (UnimplementedClusterServer) SearchConfig(context.Context, *SearchConfigRequest) (*SearchConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SearchConfig not implemented") } -func (UnimplementedClusterServer) testEmbeddedByValue() {} // UnsafeClusterServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ClusterServer will @@ -191,13 +179,6 @@ type UnsafeClusterServer interface { } func RegisterClusterServer(s grpc.ServiceRegistrar, srv ClusterServer) { - // If the following call pancis, it indicates UnimplementedClusterServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&Cluster_ServiceDesc, srv) } diff --git a/api/gen/grpc/go/crush_rule.pb.gw.go b/api/gen/grpc/go/crush_rule.pb.gw.go index c080869..10cef0f 100644 --- a/api/gen/grpc/go/crush_rule.pb.gw.go +++ b/api/gen/grpc/go/crush_rule.pb.gw.go @@ -10,7 +10,6 @@ package pb import ( "context" - "errors" "io" "net/http" @@ -26,143 +25,176 @@ import ( ) // Suppress "imported and not used" errors -var ( - _ codes.Code - _ io.Reader - _ status.Status - _ = errors.New - _ = runtime.String - _ = utilities.NewDoubleArray - _ = metadata.Join -) +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join func request_CrushRule_CreateRule_0(ctx context.Context, marshaler runtime.Marshaler, client CrushRuleClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateRuleRequest - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateRuleRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CreateRule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_CrushRule_CreateRule_0(ctx context.Context, marshaler runtime.Marshaler, server CrushRuleServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateRuleRequest - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateRuleRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CreateRule(ctx, &protoReq) return msg, metadata, err + } func request_CrushRule_DeleteRule_0(ctx context.Context, marshaler runtime.Marshaler, client CrushRuleClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRuleRequest + var metadata runtime.ServerMetadata + var ( - protoReq DeleteRuleRequest - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := client.DeleteRule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_CrushRule_DeleteRule_0(ctx context.Context, marshaler runtime.Marshaler, server CrushRuleServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRuleRequest + var metadata runtime.ServerMetadata + var ( - protoReq DeleteRuleRequest - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := server.DeleteRule(ctx, &protoReq) return msg, metadata, err + } func request_CrushRule_GetRule_0(ctx context.Context, marshaler runtime.Marshaler, client CrushRuleClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRuleRequest + var metadata runtime.ServerMetadata + var ( - protoReq GetRuleRequest - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := client.GetRule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_CrushRule_GetRule_0(ctx context.Context, marshaler runtime.Marshaler, server CrushRuleServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRuleRequest + var metadata runtime.ServerMetadata + var ( - protoReq GetRuleRequest - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := server.GetRule(ctx, &protoReq) return msg, metadata, err + } func request_CrushRule_ListRules_0(ctx context.Context, marshaler runtime.Marshaler, client CrushRuleClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.ListRules(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_CrushRule_ListRules_0(ctx context.Context, marshaler runtime.Marshaler, server CrushRuleServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.ListRules(ctx, &protoReq) return msg, metadata, err + } // RegisterCrushRuleHandlerServer registers the http handlers for service CrushRule to "mux". // UnaryRPC :call CrushRuleServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterCrushRuleHandlerFromEndpoint instead. -// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, server CrushRuleServer) error { - mux.Handle(http.MethodPost, pattern_CrushRule_CreateRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_CrushRule_CreateRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/CreateRule", runtime.WithHTTPPathPattern("/api/crush_rule")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/CreateRule", runtime.WithHTTPPathPattern("/api/crush_rule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -174,15 +206,20 @@ func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_CreateRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_CrushRule_DeleteRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_CrushRule_DeleteRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/DeleteRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/DeleteRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -194,15 +231,20 @@ func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_DeleteRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_CrushRule_GetRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_CrushRule_GetRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/GetRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/GetRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -214,15 +256,20 @@ func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_GetRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_CrushRule_ListRules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_CrushRule_ListRules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/ListRules", runtime.WithHTTPPathPattern("/api/crush_rule")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.CrushRule/ListRules", runtime.WithHTTPPathPattern("/api/crush_rule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -234,7 +281,9 @@ func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_CrushRule_ListRules_0(annotatedContext, mux, outboundMarshaler, w, req, response_CrushRule_ListRules_0{resp.(*ListRulesResponse)}, mux.GetForwardResponseOptions()...) + + forward_CrushRule_ListRules_0(annotatedContext, mux, outboundMarshaler, w, req, response_CrushRule_ListRules_0{resp}, mux.GetForwardResponseOptions()...) + }) return nil @@ -243,24 +292,25 @@ func RegisterCrushRuleHandlerServer(ctx context.Context, mux *runtime.ServeMux, // RegisterCrushRuleHandlerFromEndpoint is same as RegisterCrushRuleHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterCrushRuleHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.NewClient(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } }() }() + return RegisterCrushRuleHandler(ctx, mux, conn) } @@ -274,13 +324,16 @@ func RegisterCrushRuleHandler(ctx context.Context, mux *runtime.ServeMux, conn * // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "CrushRuleClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "CrushRuleClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "CrushRuleClient" to call the correct interceptors. This client ignores the HTTP middlewares. +// "CrushRuleClient" to call the correct interceptors. func RegisterCrushRuleHandlerClient(ctx context.Context, mux *runtime.ServeMux, client CrushRuleClient) error { - mux.Handle(http.MethodPost, pattern_CrushRule_CreateRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_CrushRule_CreateRule_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/CreateRule", runtime.WithHTTPPathPattern("/api/crush_rule")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/CreateRule", runtime.WithHTTPPathPattern("/api/crush_rule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -291,13 +344,18 @@ func RegisterCrushRuleHandlerClient(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_CreateRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_CrushRule_DeleteRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_CrushRule_DeleteRule_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/DeleteRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/DeleteRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -308,13 +366,18 @@ func RegisterCrushRuleHandlerClient(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_DeleteRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_CrushRule_GetRule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_CrushRule_GetRule_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/GetRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/GetRule", runtime.WithHTTPPathPattern("/api/crush_rule/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -325,13 +388,18 @@ func RegisterCrushRuleHandlerClient(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_CrushRule_GetRule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_CrushRule_ListRules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_CrushRule_ListRules_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/ListRules", runtime.WithHTTPPathPattern("/api/crush_rule")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.CrushRule/ListRules", runtime.WithHTTPPathPattern("/api/crush_rule")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -342,29 +410,39 @@ func RegisterCrushRuleHandlerClient(ctx context.Context, mux *runtime.ServeMux, runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_CrushRule_ListRules_0(annotatedContext, mux, outboundMarshaler, w, req, response_CrushRule_ListRules_0{resp.(*ListRulesResponse)}, mux.GetForwardResponseOptions()...) + + forward_CrushRule_ListRules_0(annotatedContext, mux, outboundMarshaler, w, req, response_CrushRule_ListRules_0{resp}, mux.GetForwardResponseOptions()...) + }) + return nil } type response_CrushRule_ListRules_0 struct { - *ListRulesResponse + proto.Message } func (m response_CrushRule_ListRules_0) XXX_ResponseBody() interface{} { - return m.Rules + response := m.Message.(*ListRulesResponse) + return response.Rules } var ( pattern_CrushRule_CreateRule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "crush_rule"}, "")) + pattern_CrushRule_DeleteRule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "crush_rule", "name"}, "")) - pattern_CrushRule_GetRule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "crush_rule", "name"}, "")) - pattern_CrushRule_ListRules_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "crush_rule"}, "")) + + pattern_CrushRule_GetRule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "crush_rule", "name"}, "")) + + pattern_CrushRule_ListRules_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "crush_rule"}, "")) ) var ( forward_CrushRule_CreateRule_0 = runtime.ForwardResponseMessage + forward_CrushRule_DeleteRule_0 = runtime.ForwardResponseMessage - forward_CrushRule_GetRule_0 = runtime.ForwardResponseMessage - forward_CrushRule_ListRules_0 = runtime.ForwardResponseMessage + + forward_CrushRule_GetRule_0 = runtime.ForwardResponseMessage + + forward_CrushRule_ListRules_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/crush_rule_grpc.pb.go b/api/gen/grpc/go/crush_rule_grpc.pb.go index 24edb82..d29fc3e 100644 --- a/api/gen/grpc/go/crush_rule_grpc.pb.go +++ b/api/gen/grpc/go/crush_rule_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: crush_rule.proto @@ -16,8 +16,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( CrushRule_CreateRule_FullMethodName = "/ceph.CrushRule/CreateRule" @@ -45,9 +45,8 @@ func NewCrushRuleClient(cc grpc.ClientConnInterface) CrushRuleClient { } func (c *crushRuleClient) CreateRule(ctx context.Context, in *CreateRuleRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, CrushRule_CreateRule_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, CrushRule_CreateRule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -55,9 +54,8 @@ func (c *crushRuleClient) CreateRule(ctx context.Context, in *CreateRuleRequest, } func (c *crushRuleClient) DeleteRule(ctx context.Context, in *DeleteRuleRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, CrushRule_DeleteRule_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, CrushRule_DeleteRule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -65,9 +63,8 @@ func (c *crushRuleClient) DeleteRule(ctx context.Context, in *DeleteRuleRequest, } func (c *crushRuleClient) GetRule(ctx context.Context, in *GetRuleRequest, opts ...grpc.CallOption) (*Rule, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Rule) - err := c.cc.Invoke(ctx, CrushRule_GetRule_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, CrushRule_GetRule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -75,9 +72,8 @@ func (c *crushRuleClient) GetRule(ctx context.Context, in *GetRuleRequest, opts } func (c *crushRuleClient) ListRules(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListRulesResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListRulesResponse) - err := c.cc.Invoke(ctx, CrushRule_ListRules_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, CrushRule_ListRules_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -86,7 +82,7 @@ func (c *crushRuleClient) ListRules(ctx context.Context, in *emptypb.Empty, opts // CrushRuleServer is the server API for CrushRule service. // All implementations should embed UnimplementedCrushRuleServer -// for forward compatibility. +// for forward compatibility type CrushRuleServer interface { CreateRule(context.Context, *CreateRuleRequest) (*emptypb.Empty, error) DeleteRule(context.Context, *DeleteRuleRequest) (*emptypb.Empty, error) @@ -94,12 +90,9 @@ type CrushRuleServer interface { ListRules(context.Context, *emptypb.Empty) (*ListRulesResponse, error) } -// UnimplementedCrushRuleServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedCrushRuleServer struct{} +// UnimplementedCrushRuleServer should be embedded to have forward compatible implementations. +type UnimplementedCrushRuleServer struct { +} func (UnimplementedCrushRuleServer) CreateRule(context.Context, *CreateRuleRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateRule not implemented") @@ -113,7 +106,6 @@ func (UnimplementedCrushRuleServer) GetRule(context.Context, *GetRuleRequest) (* func (UnimplementedCrushRuleServer) ListRules(context.Context, *emptypb.Empty) (*ListRulesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRules not implemented") } -func (UnimplementedCrushRuleServer) testEmbeddedByValue() {} // UnsafeCrushRuleServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CrushRuleServer will @@ -123,13 +115,6 @@ type UnsafeCrushRuleServer interface { } func RegisterCrushRuleServer(s grpc.ServiceRegistrar, srv CrushRuleServer) { - // If the following call pancis, it indicates UnimplementedCrushRuleServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&CrushRule_ServiceDesc, srv) } diff --git a/api/gen/grpc/go/status.pb.gw.go b/api/gen/grpc/go/status.pb.gw.go index ed6efb8..5d004e9 100644 --- a/api/gen/grpc/go/status.pb.gw.go +++ b/api/gen/grpc/go/status.pb.gw.go @@ -10,7 +10,6 @@ package pb import ( "context" - "errors" "io" "net/http" @@ -26,101 +25,100 @@ import ( ) // Suppress "imported and not used" errors -var ( - _ codes.Code - _ io.Reader - _ status.Status - _ = errors.New - _ = runtime.String - _ = utilities.NewDoubleArray - _ = metadata.Join -) +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join func request_Status_GetCephStatus_0(ctx context.Context, marshaler runtime.Marshaler, client StatusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetCephStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Status_GetCephStatus_0(ctx context.Context, marshaler runtime.Marshaler, server StatusServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetCephStatus(ctx, &protoReq) return msg, metadata, err + } func request_Status_GetCephMonDump_0(ctx context.Context, marshaler runtime.Marshaler, client StatusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetCephMonDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Status_GetCephMonDump_0(ctx context.Context, marshaler runtime.Marshaler, server StatusServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetCephMonDump(ctx, &protoReq) return msg, metadata, err + } func request_Status_GetCephOsdDump_0(ctx context.Context, marshaler runtime.Marshaler, client StatusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetCephOsdDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Status_GetCephOsdDump_0(ctx context.Context, marshaler runtime.Marshaler, server StatusServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetCephOsdDump(ctx, &protoReq) return msg, metadata, err + } func request_Status_GetCephReport_0(ctx context.Context, marshaler runtime.Marshaler, client StatusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.GetCephReport(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Status_GetCephReport_0(ctx context.Context, marshaler runtime.Marshaler, server StatusServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.GetCephReport(ctx, &protoReq) return msg, metadata, err + } // RegisterStatusHandlerServer registers the http handlers for service Status to "mux". // UnaryRPC :call StatusServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterStatusHandlerFromEndpoint instead. -// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, server StatusServer) error { - mux.Handle(http.MethodGet, pattern_Status_GetCephStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephStatus", runtime.WithHTTPPathPattern("/api/status/ceph")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephStatus", runtime.WithHTTPPathPattern("/api/status/ceph")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -132,15 +130,20 @@ func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephMonDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephMonDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephMonDump", runtime.WithHTTPPathPattern("/api/status/mon_dump")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephMonDump", runtime.WithHTTPPathPattern("/api/status/mon_dump")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -152,15 +155,20 @@ func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephMonDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephOsdDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephOsdDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephOsdDump", runtime.WithHTTPPathPattern("/api/status/osd_dump")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephOsdDump", runtime.WithHTTPPathPattern("/api/status/osd_dump")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -172,15 +180,20 @@ func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephOsdDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephReport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephReport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephReport", runtime.WithHTTPPathPattern("/api/status/report")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Status/GetCephReport", runtime.WithHTTPPathPattern("/api/status/report")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -192,7 +205,9 @@ func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephReport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil @@ -201,24 +216,25 @@ func RegisterStatusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser // RegisterStatusHandlerFromEndpoint is same as RegisterStatusHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterStatusHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.NewClient(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } }() }() + return RegisterStatusHandler(ctx, mux, conn) } @@ -232,13 +248,16 @@ func RegisterStatusHandler(ctx context.Context, mux *runtime.ServeMux, conn *grp // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "StatusClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "StatusClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "StatusClient" to call the correct interceptors. This client ignores the HTTP middlewares. +// "StatusClient" to call the correct interceptors. func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, client StatusClient) error { - mux.Handle(http.MethodGet, pattern_Status_GetCephStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephStatus_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephStatus", runtime.WithHTTPPathPattern("/api/status/ceph")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephStatus", runtime.WithHTTPPathPattern("/api/status/ceph")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -249,13 +268,18 @@ func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephMonDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephMonDump_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephMonDump", runtime.WithHTTPPathPattern("/api/status/mon_dump")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephMonDump", runtime.WithHTTPPathPattern("/api/status/mon_dump")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -266,13 +290,18 @@ func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephMonDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephOsdDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephOsdDump_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephOsdDump", runtime.WithHTTPPathPattern("/api/status/osd_dump")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephOsdDump", runtime.WithHTTPPathPattern("/api/status/osd_dump")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -283,13 +312,18 @@ func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephOsdDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Status_GetCephReport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Status_GetCephReport_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephReport", runtime.WithHTTPPathPattern("/api/status/report")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Status/GetCephReport", runtime.WithHTTPPathPattern("/api/status/report")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -300,21 +334,30 @@ func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Status_GetCephReport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } var ( - pattern_Status_GetCephStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "ceph"}, "")) + pattern_Status_GetCephStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "ceph"}, "")) + pattern_Status_GetCephMonDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "mon_dump"}, "")) + pattern_Status_GetCephOsdDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "osd_dump"}, "")) - pattern_Status_GetCephReport_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "report"}, "")) + + pattern_Status_GetCephReport_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "status", "report"}, "")) ) var ( - forward_Status_GetCephStatus_0 = runtime.ForwardResponseMessage + forward_Status_GetCephStatus_0 = runtime.ForwardResponseMessage + forward_Status_GetCephMonDump_0 = runtime.ForwardResponseMessage + forward_Status_GetCephOsdDump_0 = runtime.ForwardResponseMessage - forward_Status_GetCephReport_0 = runtime.ForwardResponseMessage + + forward_Status_GetCephReport_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/status_grpc.pb.go b/api/gen/grpc/go/status_grpc.pb.go index 19d0528..0c553e4 100644 --- a/api/gen/grpc/go/status_grpc.pb.go +++ b/api/gen/grpc/go/status_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: status.proto @@ -17,8 +17,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( Status_GetCephStatus_FullMethodName = "/ceph.Status/GetCephStatus" @@ -53,9 +53,8 @@ func NewStatusClient(cc grpc.ClientConnInterface) StatusClient { } func (c *statusClient) GetCephStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetCephStatusResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetCephStatusResponse) - err := c.cc.Invoke(ctx, Status_GetCephStatus_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Status_GetCephStatus_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -63,9 +62,8 @@ func (c *statusClient) GetCephStatus(ctx context.Context, in *emptypb.Empty, opt } func (c *statusClient) GetCephMonDump(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CephMonDumpResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CephMonDumpResponse) - err := c.cc.Invoke(ctx, Status_GetCephMonDump_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Status_GetCephMonDump_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -73,9 +71,8 @@ func (c *statusClient) GetCephMonDump(ctx context.Context, in *emptypb.Empty, op } func (c *statusClient) GetCephOsdDump(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetCephOsdDumpResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetCephOsdDumpResponse) - err := c.cc.Invoke(ctx, Status_GetCephOsdDump_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Status_GetCephOsdDump_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -83,9 +80,8 @@ func (c *statusClient) GetCephOsdDump(ctx context.Context, in *emptypb.Empty, op } func (c *statusClient) GetCephPgDump(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetCephPgDumpResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetCephPgDumpResponse) - err := c.cc.Invoke(ctx, Status_GetCephPgDump_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Status_GetCephPgDump_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -93,9 +89,8 @@ func (c *statusClient) GetCephPgDump(ctx context.Context, in *emptypb.Empty, opt } func (c *statusClient) GetCephReport(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*structpb.Struct, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(structpb.Struct) - err := c.cc.Invoke(ctx, Status_GetCephReport_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Status_GetCephReport_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -104,7 +99,7 @@ func (c *statusClient) GetCephReport(ctx context.Context, in *emptypb.Empty, opt // StatusServer is the server API for Status service. // All implementations should embed UnimplementedStatusServer -// for forward compatibility. +// for forward compatibility type StatusServer interface { // command: ceph status GetCephStatus(context.Context, *emptypb.Empty) (*GetCephStatusResponse, error) @@ -118,12 +113,9 @@ type StatusServer interface { GetCephReport(context.Context, *emptypb.Empty) (*structpb.Struct, error) } -// UnimplementedStatusServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedStatusServer struct{} +// UnimplementedStatusServer should be embedded to have forward compatible implementations. +type UnimplementedStatusServer struct { +} func (UnimplementedStatusServer) GetCephStatus(context.Context, *emptypb.Empty) (*GetCephStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCephStatus not implemented") @@ -140,7 +132,6 @@ func (UnimplementedStatusServer) GetCephPgDump(context.Context, *emptypb.Empty) func (UnimplementedStatusServer) GetCephReport(context.Context, *emptypb.Empty) (*structpb.Struct, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCephReport not implemented") } -func (UnimplementedStatusServer) testEmbeddedByValue() {} // UnsafeStatusServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to StatusServer will @@ -150,13 +141,6 @@ type UnsafeStatusServer interface { } func RegisterStatusServer(s grpc.ServiceRegistrar, srv StatusServer) { - // If the following call pancis, it indicates UnimplementedStatusServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&Status_ServiceDesc, srv) } diff --git a/api/gen/grpc/go/users.pb.gw.go b/api/gen/grpc/go/users.pb.gw.go index 543cbee..aa95256 100644 --- a/api/gen/grpc/go/users.pb.gw.go +++ b/api/gen/grpc/go/users.pb.gw.go @@ -10,7 +10,6 @@ package pb import ( "context" - "errors" "io" "net/http" @@ -26,433 +25,574 @@ import ( ) // Suppress "imported and not used" errors -var ( - _ codes.Code - _ io.Reader - _ status.Status - _ = errors.New - _ = runtime.String - _ = utilities.NewDoubleArray - _ = metadata.Join -) +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join func request_Users_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.ListUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.ListUsers(ctx, &protoReq) return msg, metadata, err + } func request_Users_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserReq + var metadata runtime.ServerMetadata + var ( - protoReq GetUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["username"] + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserReq + var metadata runtime.ServerMetadata + var ( - protoReq GetUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["username"] + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := server.GetUser(ctx, &protoReq) return msg, metadata, err + } func request_Users_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateUserReq - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CreateUser(ctx, &protoReq) return msg, metadata, err + } func request_Users_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserReq + var metadata runtime.ServerMetadata + var ( - protoReq GetUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["username"] + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserReq + var metadata runtime.ServerMetadata + var ( - protoReq GetUserReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["username"] + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := server.DeleteUser(ctx, &protoReq) return msg, metadata, err + } func request_Users_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateUserReq - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["username"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := client.UpdateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq CreateUserReq - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq CreateUserReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["username"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := server.UpdateUser(ctx, &protoReq) return msg, metadata, err + } func request_Users_UserChangePassword_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq UserChangePasswordReq - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq UserChangePasswordReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["username"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := client.UserChangePassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_UserChangePassword_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq UserChangePasswordReq - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq UserChangePasswordReq + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["username"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["username"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") } + protoReq.Username, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) } + msg, err := server.UserChangePassword(ctx, &protoReq) return msg, metadata, err + } func request_Users_ListRoles_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := client.ListRoles(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_ListRoles_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq emptypb.Empty - metadata runtime.ServerMetadata - ) + var protoReq emptypb.Empty + var metadata runtime.ServerMetadata + msg, err := server.ListRoles(ctx, &protoReq) return msg, metadata, err + } func request_Users_GetRole_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq GetRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := client.GetRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_GetRole_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq GetRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := server.GetRole(ctx, &protoReq) return msg, metadata, err + } func request_Users_CreateRole_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq Role - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq Role + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CreateRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_CreateRole_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq Role - metadata runtime.ServerMetadata - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq Role + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CreateRole(ctx, &protoReq) return msg, metadata, err + } func request_Users_DeleteRole_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq GetRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := client.DeleteRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_DeleteRole_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq GetRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := server.DeleteRole(ctx, &protoReq) return msg, metadata, err + } func request_Users_UpdateRole_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq Role - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq Role + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["name"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := client.UpdateRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_UpdateRole_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var ( - protoReq Role - metadata runtime.ServerMetadata - err error - ) - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { + var protoReq Role + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - val, ok := pathParams["name"] + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + msg, err := server.UpdateRole(ctx, &protoReq) return msg, metadata, err + } -var filter_Users_CloneRole_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +var ( + filter_Users_CloneRole_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) func request_Users_CloneRole_0(ctx context.Context, marshaler runtime.Marshaler, client UsersClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CloneRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq CloneRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Users_CloneRole_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := client.CloneRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err + } func local_request_Users_CloneRole_0(ctx context.Context, marshaler runtime.Marshaler, server UsersServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CloneRoleReq + var metadata runtime.ServerMetadata + var ( - protoReq CloneRoleReq - metadata runtime.ServerMetadata - err error + val string + ok bool + err error + _ = err ) - val, ok := pathParams["name"] + + val, ok = pathParams["name"] if !ok { return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } + protoReq.Name, err = runtime.String(val) if err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Users_CloneRole_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } + msg, err := server.CloneRole(ctx, &protoReq) return msg, metadata, err + } // RegisterUsersHandlerServer registers the http handlers for service Users to "mux". // UnaryRPC :call UsersServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterUsersHandlerFromEndpoint instead. -// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, server UsersServer) error { - mux.Handle(http.MethodGet, pattern_Users_ListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_ListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/ListUsers", runtime.WithHTTPPathPattern("/api/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/ListUsers", runtime.WithHTTPPathPattern("/api/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -464,15 +604,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Users_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListUsers_0{resp.(*UsersResp)}, mux.GetForwardResponseOptions()...) + + forward_Users_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListUsers_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/GetUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/GetUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -484,15 +629,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CreateUser", runtime.WithHTTPPathPattern("/api/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CreateUser", runtime.WithHTTPPathPattern("/api/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -504,15 +654,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Users_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Users_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/DeleteUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/DeleteUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -524,15 +679,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Users_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Users_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UpdateUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UpdateUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -544,15 +704,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_UserChangePassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_UserChangePassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UserChangePassword", runtime.WithHTTPPathPattern("/api/user/{username}/change_password")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UserChangePassword", runtime.WithHTTPPathPattern("/api/user/{username}/change_password")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -564,15 +729,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UserChangePassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_ListRoles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_ListRoles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/ListRoles", runtime.WithHTTPPathPattern("/api/role")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/ListRoles", runtime.WithHTTPPathPattern("/api/role")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -584,15 +754,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Users_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListRoles_0{resp.(*RolesResp)}, mux.GetForwardResponseOptions()...) + + forward_Users_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListRoles_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_GetRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_GetRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/GetRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/GetRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -604,15 +779,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_GetRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_CreateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_CreateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CreateRole", runtime.WithHTTPPathPattern("/api/role")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CreateRole", runtime.WithHTTPPathPattern("/api/role")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -624,15 +804,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CreateRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Users_DeleteRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Users_DeleteRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/DeleteRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/DeleteRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -644,15 +829,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_DeleteRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Users_UpdateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Users_UpdateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UpdateRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/UpdateRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -664,15 +854,20 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UpdateRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_CloneRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_CloneRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CloneRole", runtime.WithHTTPPathPattern("/api/user/{name}/clone")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ceph.Users/CloneRole", runtime.WithHTTPPathPattern("/api/user/{name}/clone")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -684,7 +879,9 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CloneRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil @@ -693,24 +890,25 @@ func RegisterUsersHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv // RegisterUsersHandlerFromEndpoint is same as RegisterUsersHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterUsersHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.NewClient(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } defer func() { if err != nil { if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } return } go func() { <-ctx.Done() if cerr := conn.Close(); cerr != nil { - grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) } }() }() + return RegisterUsersHandler(ctx, mux, conn) } @@ -724,13 +922,16 @@ func RegisterUsersHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "UsersClient". // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "UsersClient" // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "UsersClient" to call the correct interceptors. This client ignores the HTTP middlewares. +// "UsersClient" to call the correct interceptors. func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, client UsersClient) error { - mux.Handle(http.MethodGet, pattern_Users_ListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_ListUsers_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/ListUsers", runtime.WithHTTPPathPattern("/api/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/ListUsers", runtime.WithHTTPPathPattern("/api/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -741,13 +942,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Users_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListUsers_0{resp.(*UsersResp)}, mux.GetForwardResponseOptions()...) + + forward_Users_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListUsers_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_GetUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/GetUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/GetUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -758,13 +964,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_CreateUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CreateUser", runtime.WithHTTPPathPattern("/api/user")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CreateUser", runtime.WithHTTPPathPattern("/api/user")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -775,13 +986,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Users_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Users_DeleteUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/DeleteUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/DeleteUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -792,13 +1008,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Users_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Users_UpdateUser_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UpdateUser", runtime.WithHTTPPathPattern("/api/user/{username}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UpdateUser", runtime.WithHTTPPathPattern("/api/user/{username}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -809,13 +1030,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_UserChangePassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_UserChangePassword_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UserChangePassword", runtime.WithHTTPPathPattern("/api/user/{username}/change_password")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UserChangePassword", runtime.WithHTTPPathPattern("/api/user/{username}/change_password")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -826,13 +1052,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UserChangePassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_ListRoles_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/ListRoles", runtime.WithHTTPPathPattern("/api/role")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/ListRoles", runtime.WithHTTPPathPattern("/api/role")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -843,13 +1074,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_Users_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListRoles_0{resp.(*RolesResp)}, mux.GetForwardResponseOptions()...) + + forward_Users_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, response_Users_ListRoles_0{resp}, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_GetRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/GetRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/GetRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -860,13 +1096,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_GetRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPost, pattern_Users_CreateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("POST", pattern_Users_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CreateRole", runtime.WithHTTPPathPattern("/api/role")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CreateRole", runtime.WithHTTPPathPattern("/api/role")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -877,13 +1118,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CreateRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodDelete, pattern_Users_DeleteRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("DELETE", pattern_Users_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/DeleteRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/DeleteRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -894,13 +1140,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_DeleteRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodPut, pattern_Users_UpdateRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("PUT", pattern_Users_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UpdateRole", runtime.WithHTTPPathPattern("/api/role/{name}")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/UpdateRole", runtime.WithHTTPPathPattern("/api/role/{name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -911,13 +1162,18 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_UpdateRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) - mux.Handle(http.MethodGet, pattern_Users_CloneRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + + mux.Handle("GET", pattern_Users_CloneRole_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) - annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CloneRole", runtime.WithHTTPPathPattern("/api/user/{name}/clone")) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ceph.Users/CloneRole", runtime.WithHTTPPathPattern("/api/user/{name}/clone")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -928,53 +1184,80 @@ func RegisterUsersHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } + forward_Users_CloneRole_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } type response_Users_ListUsers_0 struct { - *UsersResp + proto.Message } func (m response_Users_ListUsers_0) XXX_ResponseBody() interface{} { - return m.Users + response := m.Message.(*UsersResp) + return response.Users } type response_Users_ListRoles_0 struct { - *RolesResp + proto.Message } func (m response_Users_ListRoles_0) XXX_ResponseBody() interface{} { - return m.Roles + response := m.Message.(*RolesResp) + return response.Roles } var ( - pattern_Users_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "user"}, "")) - pattern_Users_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) - pattern_Users_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "user"}, "")) - pattern_Users_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) - pattern_Users_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) + pattern_Users_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "user"}, "")) + + pattern_Users_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) + + pattern_Users_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "user"}, "")) + + pattern_Users_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) + + pattern_Users_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "user", "username"}, "")) + pattern_Users_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"api", "user", "username", "change_password"}, "")) - pattern_Users_ListRoles_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "role"}, "")) - pattern_Users_GetRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) - pattern_Users_CreateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "role"}, "")) - pattern_Users_DeleteRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) - pattern_Users_UpdateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) - pattern_Users_CloneRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"api", "user", "name", "clone"}, "")) + + pattern_Users_ListRoles_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "role"}, "")) + + pattern_Users_GetRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) + + pattern_Users_CreateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"api", "role"}, "")) + + pattern_Users_DeleteRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) + + pattern_Users_UpdateRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"api", "role", "name"}, "")) + + pattern_Users_CloneRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"api", "user", "name", "clone"}, "")) ) var ( - forward_Users_ListUsers_0 = runtime.ForwardResponseMessage - forward_Users_GetUser_0 = runtime.ForwardResponseMessage - forward_Users_CreateUser_0 = runtime.ForwardResponseMessage - forward_Users_DeleteUser_0 = runtime.ForwardResponseMessage - forward_Users_UpdateUser_0 = runtime.ForwardResponseMessage + forward_Users_ListUsers_0 = runtime.ForwardResponseMessage + + forward_Users_GetUser_0 = runtime.ForwardResponseMessage + + forward_Users_CreateUser_0 = runtime.ForwardResponseMessage + + forward_Users_DeleteUser_0 = runtime.ForwardResponseMessage + + forward_Users_UpdateUser_0 = runtime.ForwardResponseMessage + forward_Users_UserChangePassword_0 = runtime.ForwardResponseMessage - forward_Users_ListRoles_0 = runtime.ForwardResponseMessage - forward_Users_GetRole_0 = runtime.ForwardResponseMessage - forward_Users_CreateRole_0 = runtime.ForwardResponseMessage - forward_Users_DeleteRole_0 = runtime.ForwardResponseMessage - forward_Users_UpdateRole_0 = runtime.ForwardResponseMessage - forward_Users_CloneRole_0 = runtime.ForwardResponseMessage + + forward_Users_ListRoles_0 = runtime.ForwardResponseMessage + + forward_Users_GetRole_0 = runtime.ForwardResponseMessage + + forward_Users_CreateRole_0 = runtime.ForwardResponseMessage + + forward_Users_DeleteRole_0 = runtime.ForwardResponseMessage + + forward_Users_UpdateRole_0 = runtime.ForwardResponseMessage + + forward_Users_CloneRole_0 = runtime.ForwardResponseMessage ) diff --git a/api/gen/grpc/go/users_grpc.pb.go b/api/gen/grpc/go/users_grpc.pb.go index 5ff44c0..03ce86c 100644 --- a/api/gen/grpc/go/users_grpc.pb.go +++ b/api/gen/grpc/go/users_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: users.proto @@ -16,8 +16,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( Users_ListUsers_FullMethodName = "/ceph.Users/ListUsers" @@ -61,9 +61,8 @@ func NewUsersClient(cc grpc.ClientConnInterface) UsersClient { } func (c *usersClient) ListUsers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*UsersResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UsersResp) - err := c.cc.Invoke(ctx, Users_ListUsers_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_ListUsers_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -71,9 +70,8 @@ func (c *usersClient) ListUsers(ctx context.Context, in *emptypb.Empty, opts ... } func (c *usersClient) GetUser(ctx context.Context, in *GetUserReq, opts ...grpc.CallOption) (*User, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(User) - err := c.cc.Invoke(ctx, Users_GetUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_GetUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -81,9 +79,8 @@ func (c *usersClient) GetUser(ctx context.Context, in *GetUserReq, opts ...grpc. } func (c *usersClient) CreateUser(ctx context.Context, in *CreateUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_CreateUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_CreateUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -91,9 +88,8 @@ func (c *usersClient) CreateUser(ctx context.Context, in *CreateUserReq, opts .. } func (c *usersClient) DeleteUser(ctx context.Context, in *GetUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_DeleteUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_DeleteUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -101,9 +97,8 @@ func (c *usersClient) DeleteUser(ctx context.Context, in *GetUserReq, opts ...gr } func (c *usersClient) UpdateUser(ctx context.Context, in *CreateUserReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_UpdateUser_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_UpdateUser_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -111,9 +106,8 @@ func (c *usersClient) UpdateUser(ctx context.Context, in *CreateUserReq, opts .. } func (c *usersClient) UserChangePassword(ctx context.Context, in *UserChangePasswordReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_UserChangePassword_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_UserChangePassword_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -121,9 +115,8 @@ func (c *usersClient) UserChangePassword(ctx context.Context, in *UserChangePass } func (c *usersClient) ListRoles(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*RolesResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RolesResp) - err := c.cc.Invoke(ctx, Users_ListRoles_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_ListRoles_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -131,9 +124,8 @@ func (c *usersClient) ListRoles(ctx context.Context, in *emptypb.Empty, opts ... } func (c *usersClient) GetRole(ctx context.Context, in *GetRoleReq, opts ...grpc.CallOption) (*Role, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Role) - err := c.cc.Invoke(ctx, Users_GetRole_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_GetRole_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -141,9 +133,8 @@ func (c *usersClient) GetRole(ctx context.Context, in *GetRoleReq, opts ...grpc. } func (c *usersClient) CreateRole(ctx context.Context, in *Role, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_CreateRole_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_CreateRole_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -151,9 +142,8 @@ func (c *usersClient) CreateRole(ctx context.Context, in *Role, opts ...grpc.Cal } func (c *usersClient) DeleteRole(ctx context.Context, in *GetRoleReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_DeleteRole_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_DeleteRole_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -161,9 +151,8 @@ func (c *usersClient) DeleteRole(ctx context.Context, in *GetRoleReq, opts ...gr } func (c *usersClient) UpdateRole(ctx context.Context, in *Role, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_UpdateRole_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_UpdateRole_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -171,9 +160,8 @@ func (c *usersClient) UpdateRole(ctx context.Context, in *Role, opts ...grpc.Cal } func (c *usersClient) CloneRole(ctx context.Context, in *CloneRoleReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Users_CloneRole_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, Users_CloneRole_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -182,7 +170,7 @@ func (c *usersClient) CloneRole(ctx context.Context, in *CloneRoleReq, opts ...g // UsersServer is the server API for Users service. // All implementations should embed UnimplementedUsersServer -// for forward compatibility. +// for forward compatibility type UsersServer interface { ListUsers(context.Context, *emptypb.Empty) (*UsersResp, error) GetUser(context.Context, *GetUserReq) (*User, error) @@ -198,12 +186,9 @@ type UsersServer interface { CloneRole(context.Context, *CloneRoleReq) (*emptypb.Empty, error) } -// UnimplementedUsersServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedUsersServer struct{} +// UnimplementedUsersServer should be embedded to have forward compatible implementations. +type UnimplementedUsersServer struct { +} func (UnimplementedUsersServer) ListUsers(context.Context, *emptypb.Empty) (*UsersResp, error) { return nil, status.Errorf(codes.Unimplemented, "method ListUsers not implemented") @@ -241,7 +226,6 @@ func (UnimplementedUsersServer) UpdateRole(context.Context, *Role) (*emptypb.Emp func (UnimplementedUsersServer) CloneRole(context.Context, *CloneRoleReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CloneRole not implemented") } -func (UnimplementedUsersServer) testEmbeddedByValue() {} // UnsafeUsersServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to UsersServer will @@ -251,13 +235,6 @@ type UnsafeUsersServer interface { } func RegisterUsersServer(s grpc.ServiceRegistrar, srv UsersServer) { - // If the following call pancis, it indicates UnimplementedUsersServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } s.RegisterService(&Users_ServiceDesc, srv) } diff --git a/api/http.yaml b/api/http.yaml index 316dca4..491f297 100644 --- a/api/http.yaml +++ b/api/http.yaml @@ -60,13 +60,13 @@ http: get: /api/user/{name}/clone # Auth - selector: ceph.Auth.Login - post: /api/auth + post: /api/v1/auth/login body: "*" - selector: ceph.Auth.Logout - post: /api/auth/logout + post: /api/v1/auth/logout body: "*" - selector: ceph.Auth.Check - post: /api/auth/check + post: /api/v1/auth/check body: "*" - selector: ceph.Auth.Whoami get: /api/v1/auth/whoami diff --git a/api/openapi/ceph-api.swagger.json b/api/openapi/ceph-api.swagger.json index 78dae4b..8f403c4 100644 --- a/api/openapi/ceph-api.swagger.json +++ b/api/openapi/ceph-api.swagger.json @@ -40,104 +40,6 @@ "application/json" ], "paths": { - "/api/auth": { - "post": { - "operationId": "Auth_Login", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/cephLoginResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/cephLoginReq" - } - } - ], - "tags": [ - "Auth" - ] - } - }, - "/api/auth/check": { - "post": { - "operationId": "Auth_Check", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/cephTokenCheckResp" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/cephTokenCheckReq" - } - } - ], - "tags": [ - "Auth" - ] - } - }, - "/api/auth/logout": { - "post": { - "operationId": "Auth_Logout", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "type": "object", - "properties": {} - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/googlerpcStatus" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "type": "object", - "properties": {} - } - } - ], - "tags": [ - "Auth" - ] - } - }, "/api/cluster": { "get": { "summary": "Get cluster status", @@ -1162,6 +1064,104 @@ ] } }, + "/api/v1/auth/check": { + "post": { + "operationId": "Auth_Check", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/cephTokenCheckResp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/cephTokenCheckReq" + } + } + ], + "tags": [ + "Auth" + ] + } + }, + "/api/v1/auth/login": { + "post": { + "operationId": "Auth_Login", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/cephLoginResp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/cephLoginReq" + } + } + ], + "tags": [ + "Auth" + ] + } + }, + "/api/v1/auth/logout": { + "post": { + "operationId": "Auth_Logout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": {} + } + } + ], + "tags": [ + "Auth" + ] + } + }, "/api/v1/auth/whoami": { "get": { "operationId": "Auth_Whoami", @@ -2082,9 +2082,6 @@ "description": { "type": "string" }, - "owner": { - "type": "string" - }, "clusterId": { "type": "string" }, diff --git a/pkg/api/auth_api_handlers.go b/pkg/api/auth_api_handlers.go index cf4652d..0bf1512 100644 --- a/pkg/api/auth_api_handlers.go +++ b/pkg/api/auth_api_handlers.go @@ -114,7 +114,6 @@ func apiKeyToPB(in auth.APIKeyRecord) *pb.APIKeyResp { Id: in.ID, Name: in.Name, Description: in.Description, - Owner: in.Owner, ClusterId: in.ClusterID, Enabled: in.Enabled, RevokedAt: timeToPB(in.RevokedAt), diff --git a/pkg/app/start.go b/pkg/app/start.go index 83a340e..2350c18 100644 --- a/pkg/app/start.go +++ b/pkg/app/start.go @@ -102,11 +102,10 @@ func Start(ctx context.Context, conf config.Config, build config.Build) error { } apiKeyStore := auth.NewAPIKeyStore(radosSvc) - authServer, err := auth.NewServer(conf.Auth, userSvc, signingKey, signingKID, globalSecret) + authServer, err := auth.NewServer(conf.Auth, userSvc, signingKey, signingKID, apiKeyStore, globalSecret) if err != nil { return err } - authServer.SetAPIKeyStore(apiKeyStore) authAPI := api.NewAuthAPI(authServer) server := util.NewServer() diff --git a/pkg/auth/apikey.go b/pkg/auth/apikey.go index 57ed458..189cab1 100644 --- a/pkg/auth/apikey.go +++ b/pkg/auth/apikey.go @@ -24,7 +24,6 @@ type APIKeyRecord struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` - Owner string `json:"owner"` ClusterID string `json:"cluster_id"` SecretHash string `json:"secret_hash"` Enabled bool `json:"enabled"` diff --git a/pkg/auth/apikey_auth.go b/pkg/auth/apikey_auth.go index c2e3933..d2fef98 100644 --- a/pkg/auth/apikey_auth.go +++ b/pkg/auth/apikey_auth.go @@ -23,7 +23,7 @@ func authenticateAPIKey(ctx context.Context, tokenStr string, store *APIKeyStore } rec, err := store.Get(ctx, parsed.ID) if err != nil { - zerolog.Ctx(ctx).Err(err).Str("api_key_id", parsed.ID).Msg("API key not found") + zerolog.Ctx(ctx).Debug().Err(err).Str("api_key_id", parsed.ID).Msg("API key not found") return nil, unauthenticated(types.ErrUnauthenticated) } if !rec.Enabled || rec.RevokedAt != nil { diff --git a/pkg/auth/apikey_handler.go b/pkg/auth/apikey_handler.go index 70b04f7..839291c 100644 --- a/pkg/auth/apikey_handler.go +++ b/pkg/auth/apikey_handler.go @@ -15,10 +15,6 @@ type CreateAPIKeyRequest struct { ExpiresAt *time.Time } -func (s *Server) SetAPIKeyStore(store *APIKeyStore) { - s.apiKeyStore = store -} - func (s *Server) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (APIKeyRecord, string, error) { if err := requireJWTAdministrator(ctx); err != nil { return APIKeyRecord{}, "", err @@ -45,7 +41,6 @@ func (s *Server) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (API ID: id, Name: req.Name, Description: req.Description, - Owner: "user:" + username, SecretHash: hashAPIKeySecret(secret), Enabled: true, CreatedAt: now, diff --git a/pkg/auth/apikey_store.go b/pkg/auth/apikey_store.go index f974c44..1a9df19 100644 --- a/pkg/auth/apikey_store.go +++ b/pkg/auth/apikey_store.go @@ -11,6 +11,7 @@ import ( "time" "github.com/clyso/ceph-api/pkg/types" + "github.com/rs/zerolog" ) const apiKeyConfigPrefix = "ceph-api/auth/apikeys/" @@ -65,7 +66,7 @@ func (s *APIKeyStore) List(ctx context.Context) ([]APIKeyRecord, error) { if err != nil { return nil, err } - records, err := decodeConfigKeyDump(raw) + records, err := decodeConfigKeyDump(ctx, raw) if err != nil { return nil, err } @@ -160,7 +161,7 @@ func decodeAPIKeyRecord(id string, raw []byte) (APIKeyRecord, error) { return rec, nil } -func decodeConfigKeyDump(raw []byte) ([]APIKeyRecord, error) { +func decodeConfigKeyDump(ctx context.Context, raw []byte) ([]APIKeyRecord, error) { var dumped map[string]json.RawMessage if err := json.Unmarshal(raw, &dumped); err != nil { return nil, fmt.Errorf("decode config-key dump: %w", err) @@ -170,13 +171,16 @@ func decodeConfigKeyDump(raw []byte) ([]APIKeyRecord, error) { if !strings.HasPrefix(key, apiKeyConfigPrefix) { continue } + // Real monitors return config-key dump values as strings, while some tests + // and fixtures use the direct JSON shape. Accept both envelope shapes. var value string if err := json.Unmarshal(val, &value); err == nil { val = json.RawMessage([]byte(value)) } rec, err := decodeAPIKeyRecord(strings.TrimPrefix(key, apiKeyConfigPrefix), val) if err != nil { - return nil, err + zerolog.Ctx(ctx).Warn().Err(err).Str("config_key", key).Msg("skip invalid API key record from config-key dump") + continue } records = append(records, rec) } diff --git a/pkg/auth/apikey_test.go b/pkg/auth/apikey_test.go index e703a8a..c1b3fe6 100644 --- a/pkg/auth/apikey_test.go +++ b/pkg/auth/apikey_test.go @@ -2,6 +2,7 @@ package auth import ( "context" + "encoding/json" "strings" "testing" "time" @@ -32,6 +33,26 @@ func TestAPIKeyTokenHashAndParse(t *testing.T) { } } +func TestParseAPIKeyTokenRejectsMalformedTokens(t *testing.T) { + for _, token := range []string{ + "", + "ak_test.secret", + apiKeyTokenPrefix, + apiKeyTokenPrefix + "ak_test", + apiKeyTokenPrefix + ".secret", + apiKeyTokenPrefix + "ak_test.", + apiKeyTokenPrefix + "bad.secret", + apiKeyTokenPrefix + "ak_bad/id.secret", + apiKeyTokenPrefix + "ak_test.secret.extra", + } { + t.Run(token, func(t *testing.T) { + if _, err := parseAPIKeyToken(token); err == nil { + t.Fatal("parseAPIKeyToken() succeeded, want error") + } + }) + } +} + func TestAPIKeyStoreCreateListAndRevoke(t *testing.T) { ctx := context.Background() store := NewAPIKeyStore(newFakeMonCommander()) @@ -39,7 +60,6 @@ func TestAPIKeyStoreCreateListAndRevoke(t *testing.T) { rec := APIKeyRecord{ ID: "ak_test", Name: "test-key", - Owner: "user:admin", SecretHash: hashAPIKeySecret("secret"), Enabled: true, CreatedAt: now, @@ -84,7 +104,6 @@ func TestAPIKeyStoreTouchLastUsedDebouncesWrites(t *testing.T) { rec := APIKeyRecord{ ID: "ak_test", Name: "test-key", - Owner: "user:admin", SecretHash: hashAPIKeySecret("secret"), Enabled: true, CreatedAt: now, @@ -114,6 +133,103 @@ func TestAPIKeyStoreTouchLastUsedDebouncesWrites(t *testing.T) { } } +func TestDecodeConfigKeyDumpAcceptsStringAndDirectEnvelopeValues(t *testing.T) { + now := time.Now().UTC() + direct := APIKeyRecord{ + ID: "ak_direct", + Name: "direct", + SecretHash: hashAPIKeySecret("direct"), + Enabled: true, + CreatedAt: now, + CreatedBy: "user:admin", + } + wrapped := APIKeyRecord{ + ID: "ak_wrapped", + Name: "wrapped", + SecretHash: hashAPIKeySecret("wrapped"), + Enabled: true, + CreatedAt: now, + CreatedBy: "user:admin", + } + directEnvelope := mustAPIKeyEnvelope(t, direct) + wrappedEnvelope := mustAPIKeyEnvelope(t, wrapped) + wrappedString, err := json.Marshal(string(wrappedEnvelope)) + if err != nil { + t.Fatalf("marshal wrapped string: %v", err) + } + dump, err := json.Marshal(map[string]json.RawMessage{ + apiKeyConfigKey(direct.ID): directEnvelope, + apiKeyConfigKey(wrapped.ID): wrappedString, + "unrelated": directEnvelope, + }) + if err != nil { + t.Fatalf("marshal dump: %v", err) + } + + records, err := decodeConfigKeyDump(context.Background(), dump) + if err != nil { + t.Fatalf("decodeConfigKeyDump() error = %v", err) + } + if len(records) != 2 { + t.Fatalf("records len = %d, want 2: %+v", len(records), records) + } + seen := map[string]bool{} + for _, rec := range records { + seen[rec.ID] = true + } + if !seen[direct.ID] || !seen[wrapped.ID] { + t.Fatalf("records = %+v, want direct and wrapped ids", records) + } +} + +func TestDecodeConfigKeyDumpSkipsInvalidRecords(t *testing.T) { + valid := APIKeyRecord{ + ID: "ak_valid", + Name: "valid", + SecretHash: hashAPIKeySecret("valid"), + Enabled: true, + CreatedAt: time.Now().UTC(), + CreatedBy: "user:admin", + } + wrongID := APIKeyRecord{ + ID: "ak_wrong", + Name: "wrong", + SecretHash: hashAPIKeySecret("wrong"), + Enabled: true, + CreatedAt: time.Now().UTC(), + CreatedBy: "user:admin", + } + dump, err := json.Marshal(map[string]json.RawMessage{ + apiKeyConfigKey(valid.ID): mustAPIKeyEnvelope(t, valid), + apiKeyConfigKey("ak_mismatched"): mustAPIKeyEnvelope(t, wrongID), + apiKeyConfigKey("ak_corrupt"): json.RawMessage(`{"version":1}`), + }) + if err != nil { + t.Fatalf("marshal dump: %v", err) + } + + records, err := decodeConfigKeyDump(context.Background(), dump) + if err != nil { + t.Fatalf("decodeConfigKeyDump() error = %v", err) + } + if len(records) != 1 || records[0].ID != valid.ID { + t.Fatalf("records = %+v, want only valid record", records) + } +} + +func mustAPIKeyEnvelope(t *testing.T, rec APIKeyRecord) json.RawMessage { + t.Helper() + value, err := json.Marshal(rec) + if err != nil { + t.Fatalf("marshal record: %v", err) + } + envelope, err := json.Marshal(keyStoreEnvelope{Version: 1, Value: value}) + if err != nil { + t.Fatalf("marshal envelope: %v", err) + } + return envelope +} + func TestAPIKeyStoreShouldTouchLastUsedDebouncesInMemory(t *testing.T) { store := NewAPIKeyStore(newFakeMonCommander()) now := time.Now().UTC() @@ -141,7 +257,6 @@ func TestAuthenticateAPIKeySetsContextMetadata(t *testing.T) { if err := store.Create(ctx, APIKeyRecord{ ID: id, Name: "test-key", - Owner: "user:admin", SecretHash: hashAPIKeySecret(secret), Enabled: true, CreatedAt: time.Now().UTC(), diff --git a/pkg/auth/discovery_handler.go b/pkg/auth/discovery_handler.go index 3344552..ce421e3 100644 --- a/pkg/auth/discovery_handler.go +++ b/pkg/auth/discovery_handler.go @@ -21,11 +21,13 @@ type discoveryDocument struct { } type discoveryAuth struct { - Issuer string `json:"issuer"` - Audience string `json:"audience"` - TokenEndpoint string `json:"token_endpoint"` - RevokeEndpoint string `json:"revoke_endpoint"` - Modes []string `json:"modes"` + Issuer string `json:"issuer"` + Audience string `json:"audience"` + TokenEndpoint string `json:"token_endpoint"` + RevokeEndpoint string `json:"revoke_endpoint"` + Modes []string `json:"modes"` + APIKeyPrefix string `json:"api_key_prefix,omitempty"` + APIKeyHeaderFormat string `json:"api_key_header_format,omitempty"` } type jwksDocument struct { @@ -43,17 +45,21 @@ type jwk struct { func (s *Server) DiscoveryEndpoint(w http.ResponseWriter, r *http.Request) { modes := []string{"password"} + auth := discoveryAuth{ + Issuer: s.issuer, + Audience: s.clientID, + TokenEndpoint: tokenEndpoint, + RevokeEndpoint: revokeEndpoint, + Modes: modes, + } if s.apiKeyStore != nil { modes = append(modes, "api_key") + auth.Modes = modes + auth.APIKeyPrefix = apiKeyTokenPrefix + auth.APIKeyHeaderFormat = "Authorization: Bearer capi_v1_." } writeJSON(w, discoveryDocument{ - Auth: discoveryAuth{ - Issuer: s.issuer, - Audience: s.clientID, - TokenEndpoint: tokenEndpoint, - RevokeEndpoint: revokeEndpoint, - Modes: modes, - }, + Auth: auth, JWKSURI: jwksURI, }) } diff --git a/pkg/auth/discovery_handler_test.go b/pkg/auth/discovery_handler_test.go index d4f9212..94ced5e 100644 --- a/pkg/auth/discovery_handler_test.go +++ b/pkg/auth/discovery_handler_test.go @@ -45,6 +45,32 @@ func TestDiscoveryEndpoint(t *testing.T) { if len(doc.Auth.Modes) != 1 || doc.Auth.Modes[0] != "password" { t.Fatalf("modes = %v", doc.Auth.Modes) } + if doc.Auth.APIKeyPrefix != "" || doc.Auth.APIKeyHeaderFormat != "" { + t.Fatalf("api key fields = %q %q, want empty without API-key store", doc.Auth.APIKeyPrefix, doc.Auth.APIKeyHeaderFormat) + } +} + +func TestDiscoveryEndpointAdvertisesAPIKeyFormat(t *testing.T) { + server := newTestServer(t) + server.apiKeyStore = NewAPIKeyStore(newFakeMonCommander()) + recorder := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, "/.well-known/ceph-api", nil) + + server.DiscoveryEndpoint(recorder, req) + + var doc discoveryDocument + if err := json.Unmarshal(recorder.Body.Bytes(), &doc); err != nil { + t.Fatalf("decode response: %v", err) + } + if len(doc.Auth.Modes) != 2 || doc.Auth.Modes[0] != "password" || doc.Auth.Modes[1] != "api_key" { + t.Fatalf("modes = %v", doc.Auth.Modes) + } + if doc.Auth.APIKeyPrefix != apiKeyTokenPrefix { + t.Fatalf("api key prefix = %q, want %q", doc.Auth.APIKeyPrefix, apiKeyTokenPrefix) + } + if doc.Auth.APIKeyHeaderFormat != "Authorization: Bearer capi_v1_." { + t.Fatalf("api key header format = %q", doc.Auth.APIKeyHeaderFormat) + } } func TestJWKSEndpoint(t *testing.T) { @@ -94,7 +120,7 @@ func newTestServer(t *testing.T) *Server { t.Fatalf("compute kid: %v", err) } globalSecret := []byte("0123456789abcdef0123456789abcdef") - server, err := NewServer(Config{ClientID: "ceph-api", Issuer: "http://issuer.example"}, nil, priv, kid, globalSecret) + server, err := NewServer(Config{ClientID: "ceph-api", Issuer: "http://issuer.example"}, nil, priv, kid, nil, globalSecret) if err != nil { t.Fatalf("NewServer() error = %v", err) } diff --git a/pkg/auth/keystore_test.go b/pkg/auth/keystore_test.go index 4cf3060..3eee293 100644 --- a/pkg/auth/keystore_test.go +++ b/pkg/auth/keystore_test.go @@ -86,7 +86,7 @@ func TestNewServerUsesProvidedKID(t *testing.T) { t.Fatalf("LoadOrCreateGlobalSecret() error = %v", err) } - server, err := NewServer(Config{ClientID: "ceph-api", Issuer: "test"}, nil, priv, kid, globalSecret) + server, err := NewServer(Config{ClientID: "ceph-api", Issuer: "test"}, nil, priv, kid, nil, globalSecret) if err != nil { t.Fatalf("NewServer() error = %v", err) } diff --git a/pkg/auth/oauth_adapter.go b/pkg/auth/oauth_adapter.go index f3b1a02..2fbcc62 100644 --- a/pkg/auth/oauth_adapter.go +++ b/pkg/auth/oauth_adapter.go @@ -21,7 +21,7 @@ func (s *Server) Login(ctx context.Context, username, password string) (*LoginRe "password": {password}, "client_id": {s.clientID}, } - req, err := http.NewRequest("POST", "http://localhost:80/api/auth", strings.NewReader(v.Encode())) + req, err := http.NewRequest("POST", "http://localhost:80"+tokenEndpoint, strings.NewReader(v.Encode())) if err != nil { return nil, err } @@ -66,7 +66,7 @@ func (s *Server) Logout(ctx context.Context) error { "token": []string{token}, "token_type_hint": []string{"access_token"}, } - req, err := http.NewRequest("POST", "http://localhost:80/api/auth", strings.NewReader(v.Encode())) + req, err := http.NewRequest("POST", "http://localhost:80"+revokeEndpoint, strings.NewReader(v.Encode())) if err != nil { return err } diff --git a/pkg/auth/oauth_server.go b/pkg/auth/oauth_server.go index d884c2e..938541e 100644 --- a/pkg/auth/oauth_server.go +++ b/pkg/auth/oauth_server.go @@ -33,7 +33,7 @@ type Server struct { apiKeyStore *APIKeyStore } -func NewServer(config Config, userSvc *user.Service, privateKey *rsa.PrivateKey, kid string, globalSecret []byte) (*Server, error) { +func NewServer(config Config, userSvc *user.Service, privateKey *rsa.PrivateKey, kid string, apiKeyStore *APIKeyStore, globalSecret []byte) (*Server, error) { if privateKey == nil { return nil, fmt.Errorf("JWT signing key is required") } @@ -99,6 +99,7 @@ func NewServer(config Config, userSvc *user.Service, privateKey *rsa.PrivateKey, refreshTokenStrategy: strategy, accessTokenStrategy: strategy, userSvc: userSvc, + apiKeyStore: apiKeyStore, }, nil } From e7bce5b7e2e07f24d49581a2684a9f36cbaee184 Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Thu, 14 May 2026 00:54:12 +0000 Subject: [PATCH 3/6] cli: add interface to create an api key through CLI auth api-key create to create an API key with all admin perms Signed-off-by: Joshua Blanch --- cmd/ceph-api/auth.go | 153 ++++++++++++++++++++++++++++++++++++++ cmd/ceph-api/auth_test.go | 96 ++++++++++++++++++++++++ cmd/ceph-api/root.go | 1 + 3 files changed, 250 insertions(+) create mode 100644 cmd/ceph-api/auth.go create mode 100644 cmd/ceph-api/auth_test.go diff --git a/cmd/ceph-api/auth.go b/cmd/ceph-api/auth.go new file mode 100644 index 0000000..cb76221 --- /dev/null +++ b/cmd/ceph-api/auth.go @@ -0,0 +1,153 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" + + "github.com/spf13/cobra" +) + +const apiKeyCreatePath = "/api/v1/auth/api-keys" + +type authAPIKeyCreateOptions struct { + endpoint string + token string + name string + description string + expiresAt string + output string +} + +func newAuthCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "auth", + Short: "Authenticate and manage credentials", + } + cmd.AddCommand(newAuthAPIKeyCmd()) + return cmd +} + +func newAuthAPIKeyCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "api-key", + Short: "Manage API keys", + } + cmd.AddCommand(newAuthAPIKeyCreateCmd()) + return cmd +} + +func newAuthAPIKeyCreateCmd() *cobra.Command { + opts := &authAPIKeyCreateOptions{} + cmd := &cobra.Command{ + Use: "create", + Short: "Create an API key", + RunE: func(cmd *cobra.Command, args []string) error { + return runAuthAPIKeyCreate(cmd.Context(), cmd.InOrStdin(), cmd.OutOrStdout(), opts) + }, + } + cmd.Flags().StringVar(&opts.endpoint, "endpoint", "http://localhost:9969", "ceph-api base URL") + cmd.Flags().StringVar(&opts.token, "token", "", "administrator JWT; use '-' to read from stdin, or CEPH_API_TOKEN") + cmd.Flags().StringVar(&opts.name, "name", "", "API key name") + cmd.Flags().StringVar(&opts.description, "description", "", "API key description") + cmd.Flags().StringVar(&opts.expiresAt, "expires-at", "", "API key expiration as RFC3339 timestamp") + cmd.Flags().StringVarP(&opts.output, "output", "o", "token", "output format: token or json") + _ = cmd.MarkFlagRequired("name") + return cmd +} + +func runAuthAPIKeyCreate(ctx context.Context, stdin io.Reader, stdout io.Writer, opts *authAPIKeyCreateOptions) error { + token, err := resolveToken(stdin, opts.token) + if err != nil { + return err + } + endpoint := normalizeEndpoint(opts.endpoint) + if endpoint == "" { + return fmt.Errorf("endpoint is required") + } + if opts.output != "token" && opts.output != "json" { + return fmt.Errorf("unsupported output format %q", opts.output) + } + + body := map[string]any{ + "name": opts.name, + } + if opts.description != "" { + body["description"] = opts.description + } + if opts.expiresAt != "" { + expiresAt, err := time.Parse(time.RFC3339, opts.expiresAt) + if err != nil { + return fmt.Errorf("parse --expires-at as RFC3339: %w", err) + } + body["expires_at"] = expiresAt.Format(time.RFC3339) + } + + reqBody, err := json.Marshal(body) + if err != nil { + return err + } + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint+apiKeyCreatePath, bytes.NewReader(reqBody)) + if err != nil { + return err + } + req.Header.Set("Authorization", "Bearer "+token) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return fmt.Errorf("create API key: %s: %s", resp.Status, strings.TrimSpace(string(respBody))) + } + + var createResp struct { + Token string `json:"token"` + } + if err := json.Unmarshal(respBody, &createResp); err != nil { + return fmt.Errorf("decode create API key response: %w", err) + } + if createResp.Token == "" { + return fmt.Errorf("create API key response did not include token") + } + if opts.output == "json" { + _, err = fmt.Fprintln(stdout, string(respBody)) + return err + } + _, err = fmt.Fprintln(stdout, createResp.Token) + return err +} + +func resolveToken(stdin io.Reader, flagToken string) (string, error) { + token := strings.TrimSpace(flagToken) + if token == "-" { + raw, err := io.ReadAll(stdin) + if err != nil { + return "", err + } + token = strings.TrimSpace(string(raw)) + } else if token == "" { + token = strings.TrimSpace(os.Getenv("CEPH_API_TOKEN")) + } + if token == "" { + return "", fmt.Errorf("token is required via --token, --token -, or CEPH_API_TOKEN") + } + return token, nil +} + +func normalizeEndpoint(endpoint string) string { + return strings.TrimRight(strings.TrimSpace(endpoint), "/") +} diff --git a/cmd/ceph-api/auth_test.go b/cmd/ceph-api/auth_test.go new file mode 100644 index 0000000..dca681b --- /dev/null +++ b/cmd/ceph-api/auth_test.go @@ -0,0 +1,96 @@ +package main + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" +) + +func TestAuthAPIKeyCreateCommand(t *testing.T) { + var gotAuth string + var gotReq struct { + Name string `json:"name"` + Description string `json:"description"` + ExpiresAt string `json:"expires_at"` + } + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Fatalf("method = %s, want POST", r.Method) + } + if r.URL.Path != apiKeyCreatePath { + t.Fatalf("path = %s, want %s", r.URL.Path, apiKeyCreatePath) + } + gotAuth = r.Header.Get("Authorization") + if err := json.NewDecoder(r.Body).Decode(&gotReq); err != nil { + t.Fatalf("decode request: %v", err) + } + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"token":"capi_v1_ak_test.secret","key":{"id":"ak_test"}}`)) + })) + defer server.Close() + + cmd := newRootCmd() + out := new(bytes.Buffer) + cmd.SetOut(out) + cmd.SetArgs([]string{ + "auth", "api-key", "create", + "--endpoint", server.URL + "/", + "--token", "jwt-token", + "--name", "poc", + "--description", "business logic", + "--expires-at", "2027-05-13T00:00:00Z", + }) + + if err := cmd.Execute(); err != nil { + t.Fatalf("Execute() error = %v", err) + } + if gotAuth != "Bearer jwt-token" { + t.Fatalf("Authorization = %q, want bearer token", gotAuth) + } + if gotReq.Name != "poc" || gotReq.Description != "business logic" || gotReq.ExpiresAt != "2027-05-13T00:00:00Z" { + t.Fatalf("request = %+v", gotReq) + } + if got, want := out.String(), "capi_v1_ak_test.secret\n"; got != want { + t.Fatalf("output = %q, want %q", got, want) + } +} + +func TestAuthAPIKeyCreateCommandReadsTokenFromStdin(t *testing.T) { + var gotAuth string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotAuth = r.Header.Get("Authorization") + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"token":"capi_v1_ak_test.secret"}`)) + })) + defer server.Close() + + cmd := newRootCmd() + cmd.SetIn(bytes.NewBufferString("stdin-token\n")) + cmd.SetOut(new(bytes.Buffer)) + cmd.SetArgs([]string{ + "auth", "api-key", "create", + "--endpoint", server.URL, + "--token", "-", + "--name", "poc", + }) + + if err := cmd.Execute(); err != nil { + t.Fatalf("Execute() error = %v", err) + } + if gotAuth != "Bearer stdin-token" { + t.Fatalf("Authorization = %q, want stdin token", gotAuth) + } +} + +func TestAuthAPIKeyCreateCommandRequiresToken(t *testing.T) { + t.Setenv("CEPH_API_TOKEN", "") + cmd := newRootCmd() + cmd.SetOut(new(bytes.Buffer)) + cmd.SetArgs([]string{"auth", "api-key", "create", "--name", "poc"}) + + if err := cmd.Execute(); err == nil { + t.Fatal("Execute() succeeded, want token error") + } +} diff --git a/cmd/ceph-api/root.go b/cmd/ceph-api/root.go index a0def6a..6c859ac 100644 --- a/cmd/ceph-api/root.go +++ b/cmd/ceph-api/root.go @@ -24,6 +24,7 @@ func newRootCmd() *cobra.Command { cmd.PersistentFlags().StringVar(&opts.configOverridePath, "config-override", "", "set path to config override directory") cmd.AddCommand(newServeCmd(opts)) + cmd.AddCommand(newAuthCmd()) cmd.AddCommand(newVersionCmd()) return cmd From 59da31e523eecc60f3457293d3fa251783ab69c5 Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Thu, 14 May 2026 00:55:56 +0000 Subject: [PATCH 4/6] pkg/rados: fix up logging errors when doing a key check we call config-key get to make sure this key doesn't exist yet but this existence check is a bit noisy since it logs as an ERR Signed-off-by: Joshua Blanch --- pkg/rados/service.go | 20 ++++++++++++++++++++ pkg/rados/service_test.go | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 pkg/rados/service_test.go diff --git a/pkg/rados/service.go b/pkg/rados/service.go index 62c5ef4..945ecf5 100644 --- a/pkg/rados/service.go +++ b/pkg/rados/service.go @@ -2,7 +2,10 @@ package rados import ( "context" + "encoding/json" + "errors" + cephrados "github.com/ceph/go-ceph/rados" "github.com/rs/zerolog" ) @@ -20,6 +23,10 @@ func (s *Svc) ExecMon(ctx context.Context, cmd string) ([]byte, error) { logger.Debug().Msg("executing mon command") cmdRes, cmdStatus, err := s.conn.MonCommand([]byte(cmd)) if err != nil { + if isConfigKeyGetNotFound(cmd, err) { + logger.Debug().Err(err).Str("cmd_status", cmdStatus).Msg("config-key not found") + return nil, err + } logger.Err(err).Str("cmd_status", cmdStatus).Msg("mon command executed with error") return nil, err } @@ -65,3 +72,16 @@ func (s *Svc) ExecMgr(ctx context.Context, cmd string) ([]byte, error) { func (s *Svc) Close() { s.conn.Shutdown() } + +func isConfigKeyGetNotFound(cmd string, err error) bool { + if !errors.Is(err, cephrados.ErrNotFound) { + return false + } + var req struct { + Prefix string `json:"prefix"` + } + if json.Unmarshal([]byte(cmd), &req) != nil { + return false + } + return req.Prefix == "config-key get" +} diff --git a/pkg/rados/service_test.go b/pkg/rados/service_test.go new file mode 100644 index 0000000..aebd2d8 --- /dev/null +++ b/pkg/rados/service_test.go @@ -0,0 +1,20 @@ +package rados + +import ( + "errors" + "testing" + + cephrados "github.com/ceph/go-ceph/rados" +) + +func TestIsConfigKeyGetNotFound(t *testing.T) { + if !isConfigKeyGetNotFound(`{"prefix":"config-key get","key":"ceph-api/auth/apikeys/ak_test"}`, cephrados.ErrNotFound) { + t.Fatal("config-key get not found was not recognized") + } + if isConfigKeyGetNotFound(`{"prefix":"config-key set","key":"ceph-api/auth/apikeys/ak_test"}`, cephrados.ErrNotFound) { + t.Fatal("config-key set not found was recognized as expected get miss") + } + if isConfigKeyGetNotFound(`{"prefix":"config-key get","key":"ceph-api/auth/apikeys/ak_test"}`, errors.New("boom")) { + t.Fatal("non-not-found error was recognized as expected get miss") + } +} From d5c22a966d84b596b2d312253ba71d0c671c3f7e Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Thu, 14 May 2026 19:23:25 +0000 Subject: [PATCH 5/6] Add inline scopes for API keys scope format: config-opt:read config-opt:read/update cli: ceph-api auth api-key create --scope config-opt:read --scope config-opt:update Signed-off-by: Joshua Blanch --- api/auth.proto | 2 + api/gen/grpc/go/auth.pb.go | 105 ++++++++++++++++++------------ api/openapi/ceph-api.swagger.json | 12 ++++ cmd/ceph-api/auth.go | 5 ++ cmd/ceph-api/auth_test.go | 12 +++- pkg/api/auth_api_handlers.go | 2 + pkg/auth/apikey.go | 1 + pkg/auth/apikey_auth.go | 9 ++- pkg/auth/apikey_handler.go | 9 ++- pkg/auth/apikey_test.go | 45 +++++++++++-- pkg/user/inline_scopes.go | 59 +++++++++++++++++ pkg/user/inline_scopes_test.go | 34 ++++++++++ 12 files changed, 241 insertions(+), 54 deletions(-) create mode 100644 pkg/user/inline_scopes.go create mode 100644 pkg/user/inline_scopes_test.go diff --git a/api/auth.proto b/api/auth.proto index 35e6f92..1f160be 100644 --- a/api/auth.proto +++ b/api/auth.proto @@ -58,6 +58,7 @@ message CreateAPIKeyReq{ string name =1; string description =2; optional google.protobuf.Timestamp expires_at =3; + repeated string scopes =4; } message CreateAPIKeyResp{ @@ -88,6 +89,7 @@ message APIKeyResp{ string created_by =8; optional google.protobuf.Timestamp expires_at =9; optional google.protobuf.Timestamp last_used_at =10; + repeated string scopes =11; } option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { diff --git a/api/gen/grpc/go/auth.pb.go b/api/gen/grpc/go/auth.pb.go index 07f0e27..529f8a5 100644 --- a/api/gen/grpc/go/auth.pb.go +++ b/api/gen/grpc/go/auth.pb.go @@ -379,6 +379,7 @@ type CreateAPIKeyReq struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + Scopes []string `protobuf:"bytes,4,rep,name=scopes,proto3" json:"scopes,omitempty"` } func (x *CreateAPIKeyReq) Reset() { @@ -434,6 +435,13 @@ func (x *CreateAPIKeyReq) GetExpiresAt() *timestamppb.Timestamp { return nil } +func (x *CreateAPIKeyReq) GetScopes() []string { + if x != nil { + return x.Scopes + } + return nil +} + type CreateAPIKeyResp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -645,6 +653,7 @@ type APIKeyResp struct { CreatedBy string `protobuf:"bytes,8,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_used_at,json=lastUsedAt,proto3,oneof" json:"last_used_at,omitempty"` + Scopes []string `protobuf:"bytes,11,rep,name=scopes,proto3" json:"scopes,omitempty"` } func (x *APIKeyResp) Reset() { @@ -749,6 +758,13 @@ func (x *APIKeyResp) GetLastUsedAt() *timestamppb.Timestamp { return nil } +func (x *APIKeyResp) GetScopes() []string { + if x != nil { + return x.Scopes + } + return nil +} + var File_auth_proto protoreflect.FileDescriptor var file_auth_proto_rawDesc = []byte{ @@ -834,7 +850,7 @@ var file_auth_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xae, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, @@ -843,48 +859,51 @@ var file_auth_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 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, 0x48, 0x00, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x22, 0x4c, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, - 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x37, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, - 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x25, - 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, - 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x28, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, - 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, - 0xeb, 0x03, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, - 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, - 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 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, 0x48, 0x01, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x3e, 0x0a, 0x0a, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x09, 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, 0x48, 0x02, 0x52, 0x09, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 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, 0x48, 0x03, - 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, + 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, + 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x22, + 0x4c, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x37, 0x0a, + 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x24, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x63, 0x65, 0x70, 0x68, 0x2e, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x25, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x50, 0x49, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x28, 0x0a, + 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, + 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x83, 0x04, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, + 0x5f, 0x61, 0x74, 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, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, + 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x07, 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, 0x48, 0x01, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x42, 0x79, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x61, 0x74, 0x18, 0x09, 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, 0x48, 0x02, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 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, 0x48, 0x03, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, + 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, + 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x42, 0x0f, 0x0a, 0x0d, diff --git a/api/openapi/ceph-api.swagger.json b/api/openapi/ceph-api.swagger.json index 8f403c4..9e17d8d 100644 --- a/api/openapi/ceph-api.swagger.json +++ b/api/openapi/ceph-api.swagger.json @@ -2106,6 +2106,12 @@ "lastUsedAt": { "type": "string", "format": "date-time" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } } } }, @@ -2562,6 +2568,12 @@ "expiresAt": { "type": "string", "format": "date-time" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/cmd/ceph-api/auth.go b/cmd/ceph-api/auth.go index cb76221..9625b72 100644 --- a/cmd/ceph-api/auth.go +++ b/cmd/ceph-api/auth.go @@ -22,6 +22,7 @@ type authAPIKeyCreateOptions struct { name string description string expiresAt string + scopes []string output string } @@ -57,6 +58,7 @@ func newAuthAPIKeyCreateCmd() *cobra.Command { cmd.Flags().StringVar(&opts.name, "name", "", "API key name") cmd.Flags().StringVar(&opts.description, "description", "", "API key description") cmd.Flags().StringVar(&opts.expiresAt, "expires-at", "", "API key expiration as RFC3339 timestamp") + cmd.Flags().StringArrayVar(&opts.scopes, "scope", nil, "API key inline scope, e.g. config-opt:read or config-opt:read/update; repeatable") cmd.Flags().StringVarP(&opts.output, "output", "o", "token", "output format: token or json") _ = cmd.MarkFlagRequired("name") return cmd @@ -88,6 +90,9 @@ func runAuthAPIKeyCreate(ctx context.Context, stdin io.Reader, stdout io.Writer, } body["expires_at"] = expiresAt.Format(time.RFC3339) } + if len(opts.scopes) != 0 { + body["scopes"] = opts.scopes + } reqBody, err := json.Marshal(body) if err != nil { diff --git a/cmd/ceph-api/auth_test.go b/cmd/ceph-api/auth_test.go index dca681b..9add269 100644 --- a/cmd/ceph-api/auth_test.go +++ b/cmd/ceph-api/auth_test.go @@ -11,9 +11,10 @@ import ( func TestAuthAPIKeyCreateCommand(t *testing.T) { var gotAuth string var gotReq struct { - Name string `json:"name"` - Description string `json:"description"` - ExpiresAt string `json:"expires_at"` + Name string `json:"name"` + Description string `json:"description"` + ExpiresAt string `json:"expires_at"` + Scopes []string `json:"scopes"` } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { @@ -41,6 +42,8 @@ func TestAuthAPIKeyCreateCommand(t *testing.T) { "--name", "poc", "--description", "business logic", "--expires-at", "2027-05-13T00:00:00Z", + "--scope", "config-opt:read", + "--scope", "config-opt:update", }) if err := cmd.Execute(); err != nil { @@ -52,6 +55,9 @@ func TestAuthAPIKeyCreateCommand(t *testing.T) { if gotReq.Name != "poc" || gotReq.Description != "business logic" || gotReq.ExpiresAt != "2027-05-13T00:00:00Z" { t.Fatalf("request = %+v", gotReq) } + if len(gotReq.Scopes) != 2 || gotReq.Scopes[0] != "config-opt:read" || gotReq.Scopes[1] != "config-opt:update" { + t.Fatalf("scopes = %v, want config-opt read/update", gotReq.Scopes) + } if got, want := out.String(), "capi_v1_ak_test.secret\n"; got != want { t.Fatalf("output = %q, want %q", got, want) } diff --git a/pkg/api/auth_api_handlers.go b/pkg/api/auth_api_handlers.go index 0bf1512..ed35941 100644 --- a/pkg/api/auth_api_handlers.go +++ b/pkg/api/auth_api_handlers.go @@ -75,6 +75,7 @@ func (a *authAPI) CreateAPIKey(ctx context.Context, req *pb.CreateAPIKeyReq) (*p Name: req.GetName(), Description: req.GetDescription(), ExpiresAt: expiresAt, + Scopes: req.GetScopes(), }) if err != nil { return nil, err @@ -121,6 +122,7 @@ func apiKeyToPB(in auth.APIKeyRecord) *pb.APIKeyResp { CreatedBy: in.CreatedBy, ExpiresAt: timeToPB(in.ExpiresAt), LastUsedAt: timeToPB(in.LastUsedAt), + Scopes: append([]string(nil), in.Scopes...), } } diff --git a/pkg/auth/apikey.go b/pkg/auth/apikey.go index 189cab1..3ed36e7 100644 --- a/pkg/auth/apikey.go +++ b/pkg/auth/apikey.go @@ -26,6 +26,7 @@ type APIKeyRecord struct { Description string `json:"description"` ClusterID string `json:"cluster_id"` SecretHash string `json:"secret_hash"` + Scopes []string `json:"scopes"` Enabled bool `json:"enabled"` RevokedAt *time.Time `json:"revoked_at"` CreatedAt time.Time `json:"created_at"` diff --git a/pkg/auth/apikey_auth.go b/pkg/auth/apikey_auth.go index d2fef98..934fb0c 100644 --- a/pkg/auth/apikey_auth.go +++ b/pkg/auth/apikey_auth.go @@ -38,8 +38,13 @@ func authenticateAPIKey(ctx context.Context, tokenStr string, store *APIKeyStore subject := "apikey:" + rec.ID ctx = log.WithUsername(ctx, subject) - ctx = xctx.SetRoles(ctx, []string{"administrator"}) - ctx = xctx.SetPermissions(ctx, user.AdministratorPermissions()) + permissions, err := user.PermissionsFromInlineScopes(rec.Scopes) + if err != nil { + zerolog.Ctx(ctx).Warn().Err(err).Str("api_key_id", rec.ID).Msg("API key has invalid scopes") + return nil, unauthenticated(types.ErrUnauthenticated) + } + ctx = xctx.SetRoles(ctx, nil) + ctx = xctx.SetPermissions(ctx, permissions) ctx = xctx.SetAuthType(ctx, "api_key") ctx = xctx.SetAPIKeyID(ctx, rec.ID) diff --git a/pkg/auth/apikey_handler.go b/pkg/auth/apikey_handler.go index 839291c..b19f6c9 100644 --- a/pkg/auth/apikey_handler.go +++ b/pkg/auth/apikey_handler.go @@ -7,12 +7,14 @@ import ( xctx "github.com/clyso/ceph-api/pkg/ctx" "github.com/clyso/ceph-api/pkg/types" + "github.com/clyso/ceph-api/pkg/user" ) type CreateAPIKeyRequest struct { Name string Description string ExpiresAt *time.Time + Scopes []string } func (s *Server) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (APIKeyRecord, string, error) { @@ -35,13 +37,16 @@ func (s *Server) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (API } now := time.Now().UTC() username := xctx.GetUsername(ctx) - // API-key v1 intentionally issues administrator keys only. Scoped roles are - // deferred until role grants can be persisted and enforced end-to-end. + scopes, err := user.NormalizeInlineScopes(req.Scopes) + if err != nil { + return APIKeyRecord{}, "", err + } rec := APIKeyRecord{ ID: id, Name: req.Name, Description: req.Description, SecretHash: hashAPIKeySecret(secret), + Scopes: scopes, Enabled: true, CreatedAt: now, CreatedBy: "user:" + username, diff --git a/pkg/auth/apikey_test.go b/pkg/auth/apikey_test.go index c1b3fe6..04fa909 100644 --- a/pkg/auth/apikey_test.go +++ b/pkg/auth/apikey_test.go @@ -8,6 +8,7 @@ import ( "time" xctx "github.com/clyso/ceph-api/pkg/ctx" + "github.com/clyso/ceph-api/pkg/user" ) func TestAPIKeyTokenHashAndParse(t *testing.T) { @@ -61,6 +62,7 @@ func TestAPIKeyStoreCreateListAndRevoke(t *testing.T) { ID: "ak_test", Name: "test-key", SecretHash: hashAPIKeySecret("secret"), + Scopes: []string{"monitor:read"}, Enabled: true, CreatedAt: now, CreatedBy: "user:admin", @@ -73,7 +75,7 @@ func TestAPIKeyStoreCreateListAndRevoke(t *testing.T) { if err != nil { t.Fatalf("Get() error = %v", err) } - if got.ID != rec.ID || got.SecretHash != rec.SecretHash { + if got.ID != rec.ID || got.SecretHash != rec.SecretHash || len(got.Scopes) != 1 || got.Scopes[0] != "monitor:read" { t.Fatalf("Get() = %+v, want persisted record", got) } listed, err := store.List(ctx) @@ -258,6 +260,7 @@ func TestAuthenticateAPIKeySetsContextMetadata(t *testing.T) { ID: id, Name: "test-key", SecretHash: hashAPIKeySecret(secret), + Scopes: []string{"config-opt:read", "config-opt:update"}, Enabled: true, CreatedAt: time.Now().UTC(), CreatedBy: "user:admin", @@ -278,8 +281,39 @@ func TestAuthenticateAPIKeySetsContextMetadata(t *testing.T) { if got := xctx.GetUsername(gotCtx); got != "apikey:"+id { t.Fatalf("username = %q, want apikey subject", got) } - if len(xctx.GetPermissions(gotCtx)) == 0 { - t.Fatal("permissions are empty, want administrator permissions") + permissions := xctx.GetPermissions(gotCtx) + if got := xctx.GetRoles(gotCtx); len(got) != 0 { + t.Fatalf("roles = %v, want none for inline-scoped API key", got) + } + if err := user.HasPermissions(gotCtx, user.ScopeConfigOpt, user.PermRead, user.PermUpdate); err != nil { + t.Fatalf("HasPermissions(config-opt read/update) error = %v; permissions=%+v", err, permissions) + } + if permissions["monitor"] != nil { + t.Fatalf("monitor permissions = %v, want none", permissions["monitor"]) + } +} + +func TestAuthenticateAPIKeyRejectsInvalidPersistedScopes(t *testing.T) { + ctx := context.Background() + store := NewAPIKeyStore(newFakeMonCommander()) + id, secret, token, err := newAPIKeyToken() + if err != nil { + t.Fatalf("newAPIKeyToken() error = %v", err) + } + if err := store.Create(ctx, APIKeyRecord{ + ID: id, + Name: "test-key", + SecretHash: hashAPIKeySecret(secret), + Scopes: []string{"unknown:read"}, + Enabled: true, + CreatedAt: time.Now().UTC(), + CreatedBy: "user:admin", + }); err != nil { + t.Fatalf("Create() error = %v", err) + } + + if _, err := authenticateAPIKey(ctx, token, store); err == nil { + t.Fatal("authenticateAPIKey() succeeded with invalid persisted scopes, want error") } } @@ -290,13 +324,16 @@ func TestServerAPIKeyCRUDRequiresJWTAdministrator(t *testing.T) { ctx = xctx.SetRoles(ctx, []string{"administrator"}) server := &Server{apiKeyStore: NewAPIKeyStore(newFakeMonCommander())} - rec, token, err := server.CreateAPIKey(ctx, CreateAPIKeyRequest{Name: "terraform"}) + rec, token, err := server.CreateAPIKey(ctx, CreateAPIKeyRequest{Name: "terraform", Scopes: []string{"config-opt:read/update", "config-opt:read"}}) if err != nil { t.Fatalf("CreateAPIKey() error = %v", err) } if token == "" || rec.ID == "" || rec.SecretHash == "" { t.Fatalf("CreateAPIKey() returned incomplete key: rec=%+v token=%q", rec, token) } + if got, want := strings.Join(rec.Scopes, ","), "config-opt:read,config-opt:update"; got != want { + t.Fatalf("scopes = %q, want %q", got, want) + } listed, err := server.ListAPIKeys(ctx) if err != nil { diff --git a/pkg/user/inline_scopes.go b/pkg/user/inline_scopes.go new file mode 100644 index 0000000..bc18a25 --- /dev/null +++ b/pkg/user/inline_scopes.go @@ -0,0 +1,59 @@ +package user + +import ( + "fmt" + "slices" + "sort" + "strings" + + "github.com/clyso/ceph-api/pkg/types" +) + +// NormalizeInlineScopes validates and canonicalizes API-key inline scopes. +// Accepted forms are "scope:permission" and "scope:permission/permission". +func NormalizeInlineScopes(in []string) ([]string, error) { + permissions, err := PermissionsFromInlineScopes(in) + if err != nil { + return nil, err + } + + res := make([]string, 0, len(in)) + for scope, perms := range permissions { + for _, perm := range perms { + res = append(res, scope+":"+perm) + } + } + sort.Strings(res) + return res, nil +} + +func PermissionsFromInlineScopes(in []string) (map[string][]string, error) { + res := map[string][]string{} + for _, rawScope := range in { + scope, rawPerms, ok := strings.Cut(strings.TrimSpace(rawScope), ":") + if !ok || scope == "" || rawPerms == "" { + return nil, fmt.Errorf("%w: invalid scope %q, expected scope:permission", types.ErrInvalidArg, rawScope) + } + if _, ok := scopeSet[scope]; !ok { + return nil, fmt.Errorf("%w: unknown scope %q", types.ErrInvalidArg, scope) + } + + for _, rawPerm := range strings.Split(rawPerms, "/") { + perm := strings.TrimSpace(rawPerm) + if perm == "" { + return nil, fmt.Errorf("%w: invalid empty permission in scope %q", types.ErrInvalidArg, rawScope) + } + if _, ok := permissionSet[perm]; !ok { + return nil, fmt.Errorf("%w: unknown permission %q", types.ErrInvalidArg, perm) + } + if !slices.Contains(res[scope], perm) { + res[scope] = append(res[scope], perm) + } + } + } + + for scope := range res { + sort.Strings(res[scope]) + } + return res, nil +} diff --git a/pkg/user/inline_scopes_test.go b/pkg/user/inline_scopes_test.go new file mode 100644 index 0000000..1448d60 --- /dev/null +++ b/pkg/user/inline_scopes_test.go @@ -0,0 +1,34 @@ +package user + +import "testing" + +func TestNormalizeInlineScopes(t *testing.T) { + got, err := NormalizeInlineScopes([]string{"config-opt:update/read", "monitor:read", "config-opt:read"}) + if err != nil { + t.Fatalf("NormalizeInlineScopes() error = %v", err) + } + want := []string{"config-opt:read", "config-opt:update", "monitor:read"} + if len(got) != len(want) { + t.Fatalf("scopes = %v, want %v", got, want) + } + for i := range want { + if got[i] != want[i] { + t.Fatalf("scopes = %v, want %v", got, want) + } + } +} + +func TestNormalizeInlineScopesRejectsInvalidScopes(t *testing.T) { + for _, scopes := range [][]string{ + {"config-opt"}, + {"unknown:read"}, + {"config-opt:admin"}, + {"config-opt:read/"}, + } { + t.Run(scopes[0], func(t *testing.T) { + if _, err := NormalizeInlineScopes(scopes); err == nil { + t.Fatal("NormalizeInlineScopes() succeeded, want error") + } + }) + } +} From 770f5b4d4ce4070270c12909df8583ac2e642b98 Mon Sep 17 00:00:00 2001 From: Joshua Blanch Date: Thu, 14 May 2026 20:40:49 +0000 Subject: [PATCH 6/6] README: add instructions on scoped api-keys Signed-off-by: Joshua Blanch --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/README.md b/README.md index 8e2d867..268b1d2 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,53 @@ curl -X POST -u "ceph-api:yoursecretpass" \ http://localhost:9969/api/oauth/token ``` +## API keys + +### Create a scoped API key + +using the built in CLI, you will need the API Access token from previous step +``` +ceph-api auth api-key create \ + --endpoint http://localhost:9969 \ + --token "$CEPH_API_TOKEN" \ + --name github-actions-config \ + --description "CI key for GitOps config management" \ + --scope config-opt:read \ + --scope config-opt:create \ + --scope config-opt:update \ + --scope config-opt:delete +``` + +will return +``` +capi_v1_ak_.... +``` + +Via HTTP + +``` +curl -X POST http://localhost:9969/api/v1/auth/api-keys \ + -H "Authorization: Bearer $CEPH_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "github-actions-config", + "description": "CI key for GitOps config management", + "scopes": [ + "config-opt:read", + "config-opt:create", + "config-opt:update", + "config-opt:delete" + ] + }' +``` + +### Use the API Key + +``` +curl http://localhost:9969/api/v1/auth/whoami \ + -H "Authorization: Bearer $CEPH_API_KEY" +``` + ## Test Along with unit test project contains e2e test to run against real Ceph cluster.