From 4349885abde539aa446386d391898de725e7f1eb Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 27 Feb 2025 11:16:53 +0000 Subject: [PATCH 1/8] [Feature] [Platform] Identity Endpoint --- CHANGELOG.md | 1 + README.md | 2 +- docs/api/ArangoDeployment.V1.md | 10 + docs/api/ArangoMLExtension.V1Beta1.md | 10 + docs/api/GraphAnalyticsEngine.V1Alpha1.md | 10 + docs/cli/arangodb_operator.md | 2 +- .../v1/definition/definition.pb.go | 245 ++++++++++++------ .../v1/definition/definition.pb.gw.go | 157 +++++++++++ .../v1/definition/definition.proto | 17 ++ .../v1/definition/definition_grpc.pb.go | 39 +++ integrations/authentication/v1/http_test.go | 123 +++++++++ .../authentication/v1/implementation.go | 47 +++- integrations/authentication/v1/logger.go | 25 ++ .../authentication/v1/service_test.go | 11 +- .../v1beta1/integration/integration.go | 17 +- .../integration/zz_generated.deepcopy.go | 5 + ...graphanalyticsengine.schema.generated.yaml | 3 + .../database-deployment.schema.generated.yaml | 6 + .../crds/ml-extension.schema.generated.yaml | 3 + .../resources/config_map_gateway.go | 16 ++ .../resources/gateway/gateway_config.go | 4 +- pkg/integrations/sidecar/integration.go | 4 +- pkg/util/constants/envoy.go | 5 + 23 files changed, 671 insertions(+), 91 deletions(-) create mode 100644 integrations/authentication/v1/definition/definition.pb.gw.go create mode 100644 integrations/authentication/v1/http_test.go create mode 100644 integrations/authentication/v1/logger.go diff --git a/CHANGELOG.md b/CHANGELOG.md index daa7375e1..a36956c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - (Bugfix) Use Profile Annotations - (Bugfix) Improve Wait Procedure on AF - (Feature) (Platform) Generate GRPC Gateway Code +- (Feature) (Platform) Identity Endpoint ## [1.2.46](https://github.com/arangodb/kube-arangodb/tree/1.2.46) (2025-02-24) - (Bugfix) Clean Phase change properly during upgrade diff --git a/README.md b/README.md index b614d5a01..f3e24e545 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Flags: --kubernetes.max-batch-size int Size of batch during objects read (default 256) --kubernetes.qps float32 Number of queries per second for k8s API (default 32) --log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty") - --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-config-v1, integration-envoy-auth-v3, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info]) + --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info]) --log.sampling If true, operator will try to minimize duplication of logging events (default true) --log.stdout If true, operator will log to the stdout (default true) --memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing diff --git a/docs/api/ArangoDeployment.V1.md b/docs/api/ArangoDeployment.V1.md index a7f04321a..3dc2f503c 100644 --- a/docs/api/ArangoDeployment.V1.md +++ b/docs/api/ArangoDeployment.V1.md @@ -4415,6 +4415,16 @@ Links: *** +### .spec.integration.sidecar.httpListenPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/integration/integration.go#L40) + +HTTPListenPort defines on which port the sidecar container will be listening for connections on http + +Default Value: `9203` + +*** + ### .spec.integration.sidecar.image Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) diff --git a/docs/api/ArangoMLExtension.V1Beta1.md b/docs/api/ArangoMLExtension.V1Beta1.md index 335aacbc6..c29b39bd1 100644 --- a/docs/api/ArangoMLExtension.V1Beta1.md +++ b/docs/api/ArangoMLExtension.V1Beta1.md @@ -852,6 +852,16 @@ Links: *** +### .spec.integrationSidecar.httpListenPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/integration/integration.go#L40) + +HTTPListenPort defines on which port the sidecar container will be listening for connections on http + +Default Value: `9203` + +*** + ### .spec.integrationSidecar.image Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) diff --git a/docs/api/GraphAnalyticsEngine.V1Alpha1.md b/docs/api/GraphAnalyticsEngine.V1Alpha1.md index 1c320ce32..f1e172de4 100644 --- a/docs/api/GraphAnalyticsEngine.V1Alpha1.md +++ b/docs/api/GraphAnalyticsEngine.V1Alpha1.md @@ -482,6 +482,16 @@ Links: *** +### .spec.integrationSidecar.httpListenPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/integration/integration.go#L40) + +HTTPListenPort defines on which port the sidecar container will be listening for connections on http + +Default Value: `9203` + +*** + ### .spec.integrationSidecar.image Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.46/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) diff --git a/docs/cli/arangodb_operator.md b/docs/cli/arangodb_operator.md index 24d73125d..24e32c233 100644 --- a/docs/cli/arangodb_operator.md +++ b/docs/cli/arangodb_operator.md @@ -83,7 +83,7 @@ Flags: --kubernetes.max-batch-size int Size of batch during objects read (default 256) --kubernetes.qps float32 Number of queries per second for k8s API (default 32) --log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty") - --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-config-v1, integration-envoy-auth-v3, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info]) + --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info]) --log.sampling If true, operator will try to minimize duplication of logging events (default true) --log.stdout If true, operator will log to the stdout (default true) --memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing diff --git a/integrations/authentication/v1/definition/definition.pb.go b/integrations/authentication/v1/definition/definition.pb.go index 9323b29f8..a42a0b8f8 100644 --- a/integrations/authentication/v1/definition/definition.pb.go +++ b/integrations/authentication/v1/definition/definition.pb.go @@ -27,6 +27,8 @@ package definition import ( + definition "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" @@ -157,6 +159,55 @@ func (x *ValidateResponse) GetDetails() *ValidateResponseDetails { return nil } +// IdentityResponse defines response for AuthenticationV1 Identity Request +type IdentityResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // user returns the User used in the Token. If a user is not specified, `root` is returned + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *IdentityResponse) Reset() { + *x = IdentityResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityResponse) ProtoMessage() {} + +func (x *IdentityResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityResponse.ProtoReflect.Descriptor instead. +func (*IdentityResponse) Descriptor() ([]byte, []int) { + return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{2} +} + +func (x *IdentityResponse) GetUser() string { + if x != nil { + return x.User + } + return "" +} + // ValidateResponseDetails defines optional response for AuthenticationV1 Validate Request. // Returned only if the Token provided in the request is valid. type ValidateResponseDetails struct { @@ -173,7 +224,7 @@ type ValidateResponseDetails struct { func (x *ValidateResponseDetails) Reset() { *x = ValidateResponseDetails{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -186,7 +237,7 @@ func (x *ValidateResponseDetails) String() string { func (*ValidateResponseDetails) ProtoMessage() {} func (x *ValidateResponseDetails) ProtoReflect() protoreflect.Message { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -199,7 +250,7 @@ func (x *ValidateResponseDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateResponseDetails.ProtoReflect.Descriptor instead. func (*ValidateResponseDetails) Descriptor() ([]byte, []int) { - return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{2} + return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{3} } func (x *ValidateResponseDetails) GetLifetime() *durationpb.Duration { @@ -231,7 +282,7 @@ type CreateTokenRequest struct { func (x *CreateTokenRequest) Reset() { *x = CreateTokenRequest{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -244,7 +295,7 @@ func (x *CreateTokenRequest) String() string { func (*CreateTokenRequest) ProtoMessage() {} func (x *CreateTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -257,7 +308,7 @@ func (x *CreateTokenRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTokenRequest.ProtoReflect.Descriptor instead. func (*CreateTokenRequest) Descriptor() ([]byte, []int) { - return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{3} + return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{4} } func (x *CreateTokenRequest) GetLifetime() *durationpb.Duration { @@ -291,7 +342,7 @@ type CreateTokenResponse struct { func (x *CreateTokenResponse) Reset() { *x = CreateTokenResponse{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -304,7 +355,7 @@ func (x *CreateTokenResponse) String() string { func (*CreateTokenResponse) ProtoMessage() {} func (x *CreateTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4] + mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -317,7 +368,7 @@ func (x *CreateTokenResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTokenResponse.ProtoReflect.Descriptor instead. func (*CreateTokenResponse) Descriptor() ([]byte, []int) { - return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{4} + return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{5} } func (x *CreateTokenResponse) GetLifetime() *durationpb.Duration { @@ -348,61 +399,75 @@ var file_integrations_authentication_v1_definition_definition_proto_rawDesc = [] 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x61, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x27, 0x0a, 0x0f, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9b, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, - 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x07, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x22, 0x64, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x35, - 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x69, 0x66, - 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x7f, 0x0a, 0x12, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3a, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x08, - 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x75, 0x73, 0x65, - 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, - 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x22, 0x76, 0x0a, 0x13, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, - 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x32, 0xbd, 0x01, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x4f, 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, - 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, + 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x27, 0x0a, 0x0f, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x9b, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x46, 0x0a, 0x07, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0x26, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x64, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x7f, + 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x17, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x69, + 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x76, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa3, 0x02, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x4f, 0x0a, 0x08, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, + 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, + 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x4d, 0x5a, + 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, + 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, + 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -417,26 +482,30 @@ func file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP return file_integrations_authentication_v1_definition_definition_proto_rawDescData } -var file_integrations_authentication_v1_definition_definition_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_integrations_authentication_v1_definition_definition_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_integrations_authentication_v1_definition_definition_proto_goTypes = []interface{}{ (*ValidateRequest)(nil), // 0: authentication.ValidateRequest (*ValidateResponse)(nil), // 1: authentication.ValidateResponse - (*ValidateResponseDetails)(nil), // 2: authentication.ValidateResponseDetails - (*CreateTokenRequest)(nil), // 3: authentication.CreateTokenRequest - (*CreateTokenResponse)(nil), // 4: authentication.CreateTokenResponse - (*durationpb.Duration)(nil), // 5: google.protobuf.Duration + (*IdentityResponse)(nil), // 2: authentication.IdentityResponse + (*ValidateResponseDetails)(nil), // 3: authentication.ValidateResponseDetails + (*CreateTokenRequest)(nil), // 4: authentication.CreateTokenRequest + (*CreateTokenResponse)(nil), // 5: authentication.CreateTokenResponse + (*durationpb.Duration)(nil), // 6: google.protobuf.Duration + (*definition.Empty)(nil), // 7: shared.Empty } var file_integrations_authentication_v1_definition_definition_proto_depIdxs = []int32{ - 2, // 0: authentication.ValidateResponse.details:type_name -> authentication.ValidateResponseDetails - 5, // 1: authentication.ValidateResponseDetails.lifetime:type_name -> google.protobuf.Duration - 5, // 2: authentication.CreateTokenRequest.lifetime:type_name -> google.protobuf.Duration - 5, // 3: authentication.CreateTokenResponse.lifetime:type_name -> google.protobuf.Duration + 3, // 0: authentication.ValidateResponse.details:type_name -> authentication.ValidateResponseDetails + 6, // 1: authentication.ValidateResponseDetails.lifetime:type_name -> google.protobuf.Duration + 6, // 2: authentication.CreateTokenRequest.lifetime:type_name -> google.protobuf.Duration + 6, // 3: authentication.CreateTokenResponse.lifetime:type_name -> google.protobuf.Duration 0, // 4: authentication.AuthenticationV1.Validate:input_type -> authentication.ValidateRequest - 3, // 5: authentication.AuthenticationV1.CreateToken:input_type -> authentication.CreateTokenRequest - 1, // 6: authentication.AuthenticationV1.Validate:output_type -> authentication.ValidateResponse - 4, // 7: authentication.AuthenticationV1.CreateToken:output_type -> authentication.CreateTokenResponse - 6, // [6:8] is the sub-list for method output_type - 4, // [4:6] is the sub-list for method input_type + 4, // 5: authentication.AuthenticationV1.CreateToken:input_type -> authentication.CreateTokenRequest + 7, // 6: authentication.AuthenticationV1.Identity:input_type -> shared.Empty + 1, // 7: authentication.AuthenticationV1.Validate:output_type -> authentication.ValidateResponse + 5, // 8: authentication.AuthenticationV1.CreateToken:output_type -> authentication.CreateTokenResponse + 2, // 9: authentication.AuthenticationV1.Identity:output_type -> authentication.IdentityResponse + 7, // [7:10] is the sub-list for method output_type + 4, // [4:7] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name 4, // [4:4] is the sub-list for extension extendee 0, // [0:4] is the sub-list for field type_name @@ -473,7 +542,7 @@ func file_integrations_authentication_v1_definition_definition_proto_init() { } } file_integrations_authentication_v1_definition_definition_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateResponseDetails); i { + switch v := v.(*IdentityResponse); i { case 0: return &v.state case 1: @@ -485,7 +554,7 @@ func file_integrations_authentication_v1_definition_definition_proto_init() { } } file_integrations_authentication_v1_definition_definition_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateTokenRequest); i { + switch v := v.(*ValidateResponseDetails); i { case 0: return &v.state case 1: @@ -497,6 +566,18 @@ func file_integrations_authentication_v1_definition_definition_proto_init() { } } file_integrations_authentication_v1_definition_definition_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_authentication_v1_definition_definition_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateTokenResponse); i { case 0: return &v.state @@ -510,14 +591,14 @@ func file_integrations_authentication_v1_definition_definition_proto_init() { } } file_integrations_authentication_v1_definition_definition_proto_msgTypes[1].OneofWrappers = []interface{}{} - file_integrations_authentication_v1_definition_definition_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_integrations_authentication_v1_definition_definition_proto_msgTypes[4].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_integrations_authentication_v1_definition_definition_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/integrations/authentication/v1/definition/definition.pb.gw.go b/integrations/authentication/v1/definition/definition.pb.gw.go new file mode 100644 index 000000000..edfed8e0a --- /dev/null +++ b/integrations/authentication/v1/definition/definition.pb.gw.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: integrations/authentication/v1/definition/definition.proto + +/* +Package definition is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package definition + +import ( + "context" + "io" + "net/http" + + definition_6 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_AuthenticationV1_Identity_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationV1Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq definition_6.Empty + var metadata runtime.ServerMetadata + + msg, err := client.Identity(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthenticationV1_Identity_0(ctx context.Context, marshaler runtime.Marshaler, server AuthenticationV1Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq definition_6.Empty + var metadata runtime.ServerMetadata + + msg, err := server.Identity(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterAuthenticationV1HandlerServer registers the http handlers for service AuthenticationV1 to "mux". +// UnaryRPC :call AuthenticationV1Server 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 RegisterAuthenticationV1HandlerFromEndpoint 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 RegisterAuthenticationV1HandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthenticationV1Server) error { + + mux.Handle("GET", pattern_AuthenticationV1_Identity_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/authentication.AuthenticationV1/Identity", runtime.WithHTTPPathPattern("/_integration/authn/v1/identity")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthenticationV1_Identity_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_AuthenticationV1_Identity_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterAuthenticationV1HandlerFromEndpoint is same as RegisterAuthenticationV1Handler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAuthenticationV1HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.NewClient(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) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAuthenticationV1Handler(ctx, mux, conn) +} + +// RegisterAuthenticationV1Handler registers the http handlers for service AuthenticationV1 to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAuthenticationV1Handler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAuthenticationV1HandlerClient(ctx, mux, NewAuthenticationV1Client(conn)) +} + +// RegisterAuthenticationV1HandlerClient registers the http handlers for service AuthenticationV1 +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthenticationV1Client". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthenticationV1Client" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AuthenticationV1Client" to call the correct interceptors. This client ignores the HTTP middlewares. +func RegisterAuthenticationV1HandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthenticationV1Client) error { + + mux.Handle("GET", pattern_AuthenticationV1_Identity_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/authentication.AuthenticationV1/Identity", runtime.WithHTTPPathPattern("/_integration/authn/v1/identity")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthenticationV1_Identity_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthenticationV1_Identity_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_AuthenticationV1_Identity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"_integration", "authn", "v1", "identity"}, "")) +) + +var ( + forward_AuthenticationV1_Identity_0 = runtime.ForwardResponseMessage +) diff --git a/integrations/authentication/v1/definition/definition.proto b/integrations/authentication/v1/definition/definition.proto index 478c86fe7..361ba0cdd 100644 --- a/integrations/authentication/v1/definition/definition.proto +++ b/integrations/authentication/v1/definition/definition.proto @@ -22,8 +22,12 @@ syntax = "proto3"; package authentication; +import "google/api/annotations.proto"; + import "google/protobuf/duration.proto"; +import "integrations/shared/v1/definition/empty.proto"; + option go_package = "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition"; // AuthenticationV1 define ServiceInterface for Authentication V1 @@ -33,6 +37,13 @@ service AuthenticationV1 { // CreateToken creates a token for the specified user rpc CreateToken (CreateTokenRequest) returns (CreateTokenResponse) {} + + // Identity extracts the identity from the request + rpc Identity (shared.Empty) returns (IdentityResponse) { + option (google.api.http) = { + get: "/_integration/authn/v1/identity" + }; + } } // ValidateRequest defines request for AuthenticationV1 Validate Request @@ -53,6 +64,12 @@ message ValidateResponse { optional ValidateResponseDetails details = 3; } +// IdentityResponse defines response for AuthenticationV1 Identity Request +message IdentityResponse { + // user returns the User used in the Token. If a user is not specified, `root` is returned + string user = 1; +} + // ValidateResponseDetails defines optional response for AuthenticationV1 Validate Request. // Returned only if the Token provided in the request is valid. message ValidateResponseDetails { diff --git a/integrations/authentication/v1/definition/definition_grpc.pb.go b/integrations/authentication/v1/definition/definition_grpc.pb.go index 220cc08a8..256ca8071 100644 --- a/integrations/authentication/v1/definition/definition_grpc.pb.go +++ b/integrations/authentication/v1/definition/definition_grpc.pb.go @@ -8,6 +8,7 @@ package definition import ( context "context" + definition "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -26,6 +27,8 @@ type AuthenticationV1Client interface { Validate(ctx context.Context, in *ValidateRequest, opts ...grpc.CallOption) (*ValidateResponse, error) // CreateToken creates a token for the specified user CreateToken(ctx context.Context, in *CreateTokenRequest, opts ...grpc.CallOption) (*CreateTokenResponse, error) + // Identity extracts the identity from the request + Identity(ctx context.Context, in *definition.Empty, opts ...grpc.CallOption) (*IdentityResponse, error) } type authenticationV1Client struct { @@ -54,6 +57,15 @@ func (c *authenticationV1Client) CreateToken(ctx context.Context, in *CreateToke return out, nil } +func (c *authenticationV1Client) Identity(ctx context.Context, in *definition.Empty, opts ...grpc.CallOption) (*IdentityResponse, error) { + out := new(IdentityResponse) + err := c.cc.Invoke(ctx, "/authentication.AuthenticationV1/Identity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AuthenticationV1Server is the server API for AuthenticationV1 service. // All implementations must embed UnimplementedAuthenticationV1Server // for forward compatibility @@ -62,6 +74,8 @@ type AuthenticationV1Server interface { Validate(context.Context, *ValidateRequest) (*ValidateResponse, error) // CreateToken creates a token for the specified user CreateToken(context.Context, *CreateTokenRequest) (*CreateTokenResponse, error) + // Identity extracts the identity from the request + Identity(context.Context, *definition.Empty) (*IdentityResponse, error) mustEmbedUnimplementedAuthenticationV1Server() } @@ -75,6 +89,9 @@ func (UnimplementedAuthenticationV1Server) Validate(context.Context, *ValidateRe func (UnimplementedAuthenticationV1Server) CreateToken(context.Context, *CreateTokenRequest) (*CreateTokenResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateToken not implemented") } +func (UnimplementedAuthenticationV1Server) Identity(context.Context, *definition.Empty) (*IdentityResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Identity not implemented") +} func (UnimplementedAuthenticationV1Server) mustEmbedUnimplementedAuthenticationV1Server() {} // UnsafeAuthenticationV1Server may be embedded to opt out of forward compatibility for this service. @@ -124,6 +141,24 @@ func _AuthenticationV1_CreateToken_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _AuthenticationV1_Identity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(definition.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthenticationV1Server).Identity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/authentication.AuthenticationV1/Identity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthenticationV1Server).Identity(ctx, req.(*definition.Empty)) + } + return interceptor(ctx, in, info, handler) +} + // AuthenticationV1_ServiceDesc is the grpc.ServiceDesc for AuthenticationV1 service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -139,6 +174,10 @@ var AuthenticationV1_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateToken", Handler: _AuthenticationV1_CreateToken_Handler, }, + { + MethodName: "Identity", + Handler: _AuthenticationV1_Identity_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "integrations/authentication/v1/definition/definition.proto", diff --git a/integrations/authentication/v1/http_test.go b/integrations/authentication/v1/http_test.go new file mode 100644 index 000000000..9f35942cf --- /dev/null +++ b/integrations/authentication/v1/http_test.go @@ -0,0 +1,123 @@ +// +// DISCLAIMER +// +// Copyright 2025 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package v1 + +import ( + "context" + "fmt" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/durationpb" + + pbAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition" + "github.com/arangodb/kube-arangodb/pkg/util" + ugrpc "github.com/arangodb/kube-arangodb/pkg/util/grpc" + operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http" + "github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc" +) + +func Test_Authentication_HTTP(t *testing.T) { + ctx, c := context.WithCancel(context.Background()) + defer c() + + directory, server := Server(t, ctx) + + grpcClient := tgrpc.NewGRPCClient(t, ctx, pbAuthenticationV1.NewAuthenticationV1Client, server.Address()) + + token1 := generateJWTToken() + + reSaveJWTTokens(t, directory, token1) + + client := operatorHTTP.NewHTTPClient() + + t.Run("Without header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress())) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With invalid header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("invalid", "") + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With empty header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", "") + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With missing prefix header", func(t *testing.T) { + tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }) + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", tokenResponse.Token) + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With header", func(t *testing.T) { + // Create token + tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }) + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) + }) + + data, err := resp.WithCode(http.StatusOK).Get() + require.NoError(t, err) + + require.EqualValues(t, DefaultUser, data.GetUser()) + }) + + t.Run("With multi header", func(t *testing.T) { + // Create token + tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }) + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) + }) + + resp.WithCode(http.StatusUnauthorized) + }) +} diff --git a/integrations/authentication/v1/implementation.go b/integrations/authentication/v1/implementation.go index efbf1bd21..e26b5eedc 100644 --- a/integrations/authentication/v1/implementation.go +++ b/integrations/authentication/v1/implementation.go @@ -22,14 +22,19 @@ package v1 import ( "context" + strings2 "strings" "sync" "time" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/durationpb" pbAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition" + pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/strings" @@ -81,7 +86,7 @@ func (i *implementation) Register(registrar *grpc.Server) { } func (i *implementation) Gateway(ctx context.Context, mux *runtime.ServeMux) error { - return nil + return pbAuthenticationV1.RegisterAuthenticationV1HandlerServer(ctx, mux, i) } func (i *implementation) Validate(ctx context.Context, request *pbAuthenticationV1.ValidateRequest) (*pbAuthenticationV1.ValidateResponse, error) { @@ -182,6 +187,46 @@ func (i *implementation) CreateToken(ctx context.Context, request *pbAuthenticat }, nil } +func (i *implementation) Identity(ctx context.Context, _ *pbSharedV1.Empty) (*pbAuthenticationV1.IdentityResponse, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil, status.Error(codes.Unauthenticated, "Unauthenticated") + } + + auth, ok := md["authorization"] + if !ok { + return nil, status.Error(codes.Unauthenticated, "Unauthenticated") + } + + if len(auth) != 1 { + return nil, status.Error(codes.Unauthenticated, "Unauthenticated") + } + + for _, a := range auth { + if !strings2.HasPrefix(a, "bearer ") { + continue + } + + a = strings2.TrimSpace(strings2.TrimPrefix(a, "bearer ")) + + resp, err := i.Validate(ctx, &pbAuthenticationV1.ValidateRequest{ + Token: a, + }) + if err != nil { + logger.Err(err).Warn("Error during identity fetch") + continue + } + + if !resp.IsValid { + continue + } + + return &pbAuthenticationV1.IdentityResponse{User: resp.GetDetails().GetUser()}, nil + } + + return nil, status.Error(codes.Unauthenticated, "Unauthenticated") +} + func (i *implementation) extractTokenDetails(cache *cache, t string) (string, time.Duration, error) { // Let's check if token is signed properly diff --git a/integrations/authentication/v1/logger.go b/integrations/authentication/v1/logger.go new file mode 100644 index 000000000..f39a43fad --- /dev/null +++ b/integrations/authentication/v1/logger.go @@ -0,0 +1,25 @@ +// +// DISCLAIMER +// +// Copyright 2025 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package v1 + +import "github.com/arangodb/kube-arangodb/pkg/logging" + +var logger = logging.Global().RegisterAndGetLogger("integration-authn-v1", logging.Info) diff --git a/integrations/authentication/v1/service_test.go b/integrations/authentication/v1/service_test.go index c3e26c033..116ba1de5 100644 --- a/integrations/authentication/v1/service_test.go +++ b/integrations/authentication/v1/service_test.go @@ -41,7 +41,7 @@ func Handler(t *testing.T, ctx context.Context, mods ...Mod) svc.Handler { return handler } -func Client(t *testing.T, ctx context.Context, mods ...Mod) (pbAuthenticationV1.AuthenticationV1Client, string) { +func Server(t *testing.T, ctx context.Context, mods ...Mod) (string, svc.ServiceStarter) { directory := t.TempDir() var currentMods []Mod @@ -55,10 +55,17 @@ func Client(t *testing.T, ctx context.Context, mods ...Mod) (pbAuthenticationV1. local, err := svc.NewService(svc.Configuration{ Address: "127.0.0.1:0", + Gateway: &svc.ConfigurationGateway{ + Address: "127.0.0.1:0", + }, }, Handler(t, ctx, currentMods...)) require.NoError(t, err) - start := local.Start(ctx) + return directory, local.Start(ctx) +} + +func Client(t *testing.T, ctx context.Context, mods ...Mod) (pbAuthenticationV1.AuthenticationV1Client, string) { + directory, start := Server(t, ctx, mods...) client := tgrpc.NewGRPCClient(t, ctx, pbAuthenticationV1.NewAuthenticationV1Client, start.Address()) diff --git a/pkg/apis/scheduler/v1beta1/integration/integration.go b/pkg/apis/scheduler/v1beta1/integration/integration.go index f793d35ff..685949233 100644 --- a/pkg/apis/scheduler/v1beta1/integration/integration.go +++ b/pkg/apis/scheduler/v1beta1/integration/integration.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,6 +35,10 @@ type Sidecar struct { // +doc/default: 9202 ControllerListenPort *uint16 `json:"controllerListenPort,omitempty"` + // HTTPListenPort defines on which port the sidecar container will be listening for connections on http + // +doc/default: 9203 + HTTPListenPort *uint16 `json:"httpListenPort,omitempty"` + // Container Keeps the information about Container configuration *schedulerContainerApi.Container `json:",inline"` } @@ -62,6 +66,10 @@ func (s *Sidecar) Validate() error { err = append(err, shared.PrefixResourceErrors("controllerListenPort", errors.Errorf("must be positive"))) } + if s.GetHTTPListenPort() < 1 { + err = append(err, shared.PrefixResourceErrors("httpListenPort", errors.Errorf("must be positive"))) + } + err = append(err, s.GetContainer().Validate()) return shared.WithErrors(err...) @@ -80,3 +88,10 @@ func (s *Sidecar) GetControllerListenPort() uint16 { } return *s.ControllerListenPort } + +func (s *Sidecar) GetHTTPListenPort() uint16 { + if s == nil || s.HTTPListenPort == nil { + return 9203 + } + return *s.HTTPListenPort +} diff --git a/pkg/apis/scheduler/v1beta1/integration/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/integration/zz_generated.deepcopy.go index 7d9ee1e90..7310cf1a3 100644 --- a/pkg/apis/scheduler/v1beta1/integration/zz_generated.deepcopy.go +++ b/pkg/apis/scheduler/v1beta1/integration/zz_generated.deepcopy.go @@ -42,6 +42,11 @@ func (in *Sidecar) DeepCopyInto(out *Sidecar) { *out = new(uint16) **out = **in } + if in.HTTPListenPort != nil { + in, out := &in.HTTPListenPort, &out.HTTPListenPort + *out = new(uint16) + **out = **in + } if in.Container != nil { in, out := &in.Container, &out.Container *out = new(container.Container) diff --git a/pkg/crd/crds/analytics-graphanalyticsengine.schema.generated.yaml b/pkg/crd/crds/analytics-graphanalyticsengine.schema.generated.yaml index e12545e28..b1e757d33 100644 --- a/pkg/crd/crds/analytics-graphanalyticsengine.schema.generated.yaml +++ b/pkg/crd/crds/analytics-graphanalyticsengine.schema.generated.yaml @@ -1771,6 +1771,9 @@ v1alpha1: type: object type: object type: array + httpListenPort: + format: int32 + type: integer image: type: string imagePullPolicy: diff --git a/pkg/crd/crds/database-deployment.schema.generated.yaml b/pkg/crd/crds/database-deployment.schema.generated.yaml index f89351ec7..46270d95f 100644 --- a/pkg/crd/crds/database-deployment.schema.generated.yaml +++ b/pkg/crd/crds/database-deployment.schema.generated.yaml @@ -9576,6 +9576,9 @@ v1: type: object type: object type: array + httpListenPort: + format: int32 + type: integer image: type: string imagePullPolicy: @@ -26627,6 +26630,9 @@ v2alpha1: type: object type: object type: array + httpListenPort: + format: int32 + type: integer image: type: string imagePullPolicy: diff --git a/pkg/crd/crds/ml-extension.schema.generated.yaml b/pkg/crd/crds/ml-extension.schema.generated.yaml index cb96b5c99..192d18d6d 100644 --- a/pkg/crd/crds/ml-extension.schema.generated.yaml +++ b/pkg/crd/crds/ml-extension.schema.generated.yaml @@ -16738,6 +16738,9 @@ v1beta1: type: object type: object type: array + httpListenPort: + format: int32 + type: integer image: type: string imagePullPolicy: diff --git a/pkg/deployment/resources/config_map_gateway.go b/pkg/deployment/resources/config_map_gateway.go index 79e69d913..23f9793c6 100644 --- a/pkg/deployment/resources/config_map_gateway.go +++ b/pkg/deployment/resources/config_map_gateway.go @@ -77,6 +77,22 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec }, } + cfg.Destinations[constants.EnvoyIdentityDestination] = gateway.ConfigDestination{ + Type: util.NewType(gateway.ConfigDestinationTypeHTTP), + AuthExtension: &gateway.ConfigAuthZExtension{ + AuthZExtension: map[string]string{ + pbImplEnvoyAuthV3.AuthConfigAuthRequiredKey: pbImplEnvoyAuthV3.AuthConfigKeywordFalse, + pbImplEnvoyAuthV3.AuthConfigAuthPassModeKey: string(networkingApi.ArangoRouteSpecAuthenticationPassModePass), + }, + }, + Targets: gateway.ConfigDestinationTargets{ + { + Host: "127.0.0.1", + Port: int32(r.context.GetSpec().Integration.GetSidecar().GetHTTPListenPort()), + }, + }, + } + gatewayCfgYaml, _, _, err := cfg.RenderYAML() if err != nil { return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config")) diff --git a/pkg/deployment/resources/gateway/gateway_config.go b/pkg/deployment/resources/gateway/gateway_config.go index be275013a..b2f155976 100644 --- a/pkg/deployment/resources/gateway/gateway_config.go +++ b/pkg/deployment/resources/gateway/gateway_config.go @@ -200,11 +200,11 @@ func (c Config) RenderClusters() ([]*clusterAPI.Cluster, error) { return nil, err } cluster := &clusterAPI.Cluster{ - Name: "integration_sidecar", + Name: constants.EnvoyIntegrationSidecarCluster, ConnectTimeout: durationpb.New(time.Second), LbPolicy: clusterAPI.Cluster_ROUND_ROBIN, LoadAssignment: &endpointAPI.ClusterLoadAssignment{ - ClusterName: "integration_sidecar", + ClusterName: constants.EnvoyIntegrationSidecarCluster, Endpoints: []*endpointAPI.LocalityLbEndpoints{ { LbEndpoints: []*endpointAPI.LbEndpoint{ diff --git a/pkg/integrations/sidecar/integration.go b/pkg/integrations/sidecar/integration.go index c67666b8c..2fd3bb389 100644 --- a/pkg/integrations/sidecar/integration.go +++ b/pkg/integrations/sidecar/integration.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-2025 ArangoDB GmbH, Cologne, Germany package sidecar @@ -133,6 +133,8 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc options.Addf("--services.address", "127.0.0.1:%d", integration.GetListenPort()) options.Addf("--health.address", "0.0.0.0:%d", integration.GetControllerListenPort()) + options.Addf("--services.gateway.address", "127.0.0.1:%d", integration.GetHTTPListenPort()) + options.Add("--services.gateway.enabled", true) // Envs diff --git a/pkg/util/constants/envoy.go b/pkg/util/constants/envoy.go index c12a9b6d4..3adc63732 100644 --- a/pkg/util/constants/envoy.go +++ b/pkg/util/constants/envoy.go @@ -24,6 +24,11 @@ const ( EnvoyRouteHeader = "arangodb-platform-route" EnvoyInventoryConfigDestination = "/_inventory" + EnvoyIdentityDestination = "/_identity" EnvoyIntegrationSidecarFilterName = "envoy.filters.http.ext_authz" + + EnvoyIntegrationSidecarCluster = "integration_sidecar" + + EnvoyIntegrationSidecarClusterHTTP = "integration_sidecar_http" ) From e633bcbfb2c50ecbe313e00cd2ca497c7bb2fa7e Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 27 Feb 2025 16:35:52 +0000 Subject: [PATCH 2/8] Iter --- docs/integration-sidecar.md | 6 + .../v1/definition/definition.pb.go | 47 +++-- .../v1/definition/definition.pb.gw.go | 154 +++++++++++++++ .../v1/definition/definition.proto | 14 +- integrations/authentication/v1/http_test.go | 179 +++++++++++------- pkg/integrations/sidecar/integration.go | 4 + pkg/util/grpc/http.go | 20 +- pkg/util/mod.go | 16 +- 8 files changed, 341 insertions(+), 99 deletions(-) diff --git a/docs/integration-sidecar.md b/docs/integration-sidecar.md index f2efc2e83..7f97efead 100644 --- a/docs/integration-sidecar.md +++ b/docs/integration-sidecar.md @@ -203,6 +203,12 @@ Integration Service API Address Example: `localhost:1234` +#### INTEGRATION_HTTP_ADDRESS + +Integration Service HTTP Address + +Example: `localhost:1234` + #### ARANGO_DEPLOYMENT_NAME ArangoDeployment name. diff --git a/integrations/authentication/v1/definition/definition.pb.go b/integrations/authentication/v1/definition/definition.pb.go index a42a0b8f8..b16aa3dbb 100644 --- a/integrations/authentication/v1/definition/definition.pb.go +++ b/integrations/authentication/v1/definition/definition.pb.go @@ -443,31 +443,36 @@ var file_integrations_authentication_v1_definition_definition_proto_rawDesc = [] 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa3, 0x02, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x4f, 0x0a, 0x08, + 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xfb, 0x02, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x79, 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, - 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x61, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x12, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x5f, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, - 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x4d, 0x5a, - 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, - 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, - 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, - 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x24, 0x22, 0x1f, 0x2f, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x85, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x22, 0x22, 0x2f, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2f, 0x76, 0x31, + 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x01, 0x2a, 0x12, + 0x64, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0d, 0x2e, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, + 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/integrations/authentication/v1/definition/definition.pb.gw.go b/integrations/authentication/v1/definition/definition.pb.gw.go index edfed8e0a..ba838d748 100644 --- a/integrations/authentication/v1/definition/definition.pb.gw.go +++ b/integrations/authentication/v1/definition/definition.pb.gw.go @@ -32,6 +32,58 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +func request_AuthenticationV1_Validate_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationV1Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateRequest + 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.Validate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthenticationV1_Validate_0(ctx context.Context, marshaler runtime.Marshaler, server AuthenticationV1Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateRequest + 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.Validate(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthenticationV1_CreateToken_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationV1Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateTokenRequest + 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.CreateToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthenticationV1_CreateToken_0(ctx context.Context, marshaler runtime.Marshaler, server AuthenticationV1Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateTokenRequest + 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.CreateToken(ctx, &protoReq) + return msg, metadata, err + +} + func request_AuthenticationV1_Identity_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationV1Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq definition_6.Empty var metadata runtime.ServerMetadata @@ -57,6 +109,56 @@ func local_request_AuthenticationV1_Identity_0(ctx context.Context, marshaler ru // 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 RegisterAuthenticationV1HandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthenticationV1Server) error { + mux.Handle("POST", pattern_AuthenticationV1_Validate_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/authentication.AuthenticationV1/Validate", runtime.WithHTTPPathPattern("/_integration/authn/v1/validate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthenticationV1_Validate_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_AuthenticationV1_Validate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthenticationV1_CreateToken_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/authentication.AuthenticationV1/CreateToken", runtime.WithHTTPPathPattern("/_integration/authn/v1/createToken")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthenticationV1_CreateToken_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_AuthenticationV1_CreateToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_AuthenticationV1_Identity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -123,6 +225,50 @@ func RegisterAuthenticationV1Handler(ctx context.Context, mux *runtime.ServeMux, // "AuthenticationV1Client" to call the correct interceptors. This client ignores the HTTP middlewares. func RegisterAuthenticationV1HandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthenticationV1Client) error { + mux.Handle("POST", pattern_AuthenticationV1_Validate_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/authentication.AuthenticationV1/Validate", runtime.WithHTTPPathPattern("/_integration/authn/v1/validate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthenticationV1_Validate_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthenticationV1_Validate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthenticationV1_CreateToken_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/authentication.AuthenticationV1/CreateToken", runtime.WithHTTPPathPattern("/_integration/authn/v1/createToken")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthenticationV1_CreateToken_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthenticationV1_CreateToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_AuthenticationV1_Identity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -149,9 +295,17 @@ func RegisterAuthenticationV1HandlerClient(ctx context.Context, mux *runtime.Ser } var ( + pattern_AuthenticationV1_Validate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"_integration", "authn", "v1", "validate"}, "")) + + pattern_AuthenticationV1_CreateToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"_integration", "authn", "v1", "createToken"}, "")) + pattern_AuthenticationV1_Identity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"_integration", "authn", "v1", "identity"}, "")) ) var ( + forward_AuthenticationV1_Validate_0 = runtime.ForwardResponseMessage + + forward_AuthenticationV1_CreateToken_0 = runtime.ForwardResponseMessage + forward_AuthenticationV1_Identity_0 = runtime.ForwardResponseMessage ) diff --git a/integrations/authentication/v1/definition/definition.proto b/integrations/authentication/v1/definition/definition.proto index 361ba0cdd..ca69aa7b9 100644 --- a/integrations/authentication/v1/definition/definition.proto +++ b/integrations/authentication/v1/definition/definition.proto @@ -33,10 +33,20 @@ option go_package = "github.com/arangodb/kube-arangodb/integrations/authenticati // AuthenticationV1 define ServiceInterface for Authentication V1 service AuthenticationV1 { // Validate and ensure that Authentication details are valid returns information about the user - rpc Validate (ValidateRequest) returns (ValidateResponse) {} + rpc Validate (ValidateRequest) returns (ValidateResponse) { + option (google.api.http) = { + post: "/_integration/authn/v1/validate" + body: "*" + }; + } // CreateToken creates a token for the specified user - rpc CreateToken (CreateTokenRequest) returns (CreateTokenResponse) {} + rpc CreateToken (CreateTokenRequest) returns (CreateTokenResponse) { + option (google.api.http) = { + post: "/_integration/authn/v1/createToken" + body: "*" + }; + } // Identity extracts the identity from the request rpc Identity (shared.Empty) returns (IdentityResponse) { diff --git a/integrations/authentication/v1/http_test.go b/integrations/authentication/v1/http_test.go index 9f35942cf..53d6200b2 100644 --- a/integrations/authentication/v1/http_test.go +++ b/integrations/authentication/v1/http_test.go @@ -34,7 +34,6 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util" ugrpc "github.com/arangodb/kube-arangodb/pkg/util/grpc" operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http" - "github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc" ) func Test_Authentication_HTTP(t *testing.T) { @@ -43,81 +42,127 @@ func Test_Authentication_HTTP(t *testing.T) { directory, server := Server(t, ctx) - grpcClient := tgrpc.NewGRPCClient(t, ctx, pbAuthenticationV1.NewAuthenticationV1Client, server.Address()) - token1 := generateJWTToken() reSaveJWTTokens(t, directory, token1) client := operatorHTTP.NewHTTPClient() - t.Run("Without header", func(t *testing.T) { - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress())) - - resp.WithCode(http.StatusUnauthorized) - }) - - t.Run("With invalid header", func(t *testing.T) { - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - in.Header.Add("invalid", "") - }) - - resp.WithCode(http.StatusUnauthorized) - }) - - t.Run("With empty header", func(t *testing.T) { - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - in.Header.Add("Authorization", "") - }) - - resp.WithCode(http.StatusUnauthorized) - }) - - t.Run("With missing prefix header", func(t *testing.T) { - tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ - Lifetime: durationpb.New(time.Minute), - User: util.NewType(DefaultUser), - }) + //t.Run("Without header", func(t *testing.T) { + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress())) + // + // resp.WithCode(http.StatusUnauthorized) + //}) + // + //t.Run("With invalid header", func(t *testing.T) { + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + // in.Header.Add("invalid", "") + // }) + // + // resp.WithCode(http.StatusUnauthorized) + //}) + // + //t.Run("With empty header", func(t *testing.T) { + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + // in.Header.Add("Authorization", "") + // }) + // + // resp.WithCode(http.StatusUnauthorized) + //}) + // + //t.Run("With missing prefix header", func(t *testing.T) { + // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + // ctx, + // client, + // &pbAuthenticationV1.CreateTokenRequest{ + // Lifetime: durationpb.New(time.Minute), + // User: util.NewType(DefaultUser), + // }, + // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + // ). + // WithCode(http.StatusOK). + // Get() + // require.NoError(t, err) + // + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + // in.Header.Add("Authorization", token.Token) + // }) + // + // resp.WithCode(http.StatusUnauthorized) + //}) + // + //t.Run("With header", func(t *testing.T) { + // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + // ctx, + // client, + // &pbAuthenticationV1.CreateTokenRequest{ + // Lifetime: durationpb.New(time.Minute), + // User: util.NewType(DefaultUser), + // }, + // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + // ). + // WithCode(http.StatusOK). + // Get() + // require.NoError(t, err) + // + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + // }) + // + // data, err := resp.WithCode(http.StatusOK).Get() + // require.NoError(t, err) + // + // require.EqualValues(t, DefaultUser, data.GetUser()) + //}) + // + //t.Run("With multi header", func(t *testing.T) { + // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + // ctx, + // client, + // &pbAuthenticationV1.CreateTokenRequest{ + // Lifetime: durationpb.New(time.Minute), + // User: util.NewType(DefaultUser), + // }, + // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + // ). + // WithCode(http.StatusOK). + // Get() + // require.NoError(t, err) + // + // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + // }) + // + // resp.WithCode(http.StatusUnauthorized) + //}) + + t.Run("Validate", func(t *testing.T) { + token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + ctx, + client, + &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }, + fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + ). + WithCode(http.StatusOK). + Get() require.NoError(t, err) - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - in.Header.Add("Authorization", tokenResponse.Token) - }) - - resp.WithCode(http.StatusUnauthorized) - }) - - t.Run("With header", func(t *testing.T) { - // Create token - tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ - Lifetime: durationpb.New(time.Minute), - User: util.NewType(DefaultUser), - }) - require.NoError(t, err) - - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) - }) - - data, err := resp.WithCode(http.StatusOK).Get() + validate, err := ugrpc.Post[*pbAuthenticationV1.ValidateRequest, *pbAuthenticationV1.ValidateResponse]( + ctx, + client, + &pbAuthenticationV1.ValidateRequest{ + Token: token.Token, + }, + fmt.Sprintf("http://%s/_integration/authn/v1/validate", server.HTTPAddress()), + ). + WithCode(http.StatusOK). + Get() require.NoError(t, err) - require.EqualValues(t, DefaultUser, data.GetUser()) - }) - - t.Run("With multi header", func(t *testing.T) { - // Create token - tokenResponse, err := grpcClient.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{ - Lifetime: durationpb.New(time.Minute), - User: util.NewType(DefaultUser), - }) - require.NoError(t, err) - - resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) - in.Header.Add("Authorization", fmt.Sprintf("bearer %s", tokenResponse.Token)) - }) - - resp.WithCode(http.StatusUnauthorized) + require.True(t, validate.GetIsValid()) }) } diff --git a/pkg/integrations/sidecar/integration.go b/pkg/integrations/sidecar/integration.go index 2fd3bb389..d67a32048 100644 --- a/pkg/integrations/sidecar/integration.go +++ b/pkg/integrations/sidecar/integration.go @@ -147,6 +147,10 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc Name: "INTEGRATION_SERVICE_ADDRESS", Value: fmt.Sprintf("127.0.0.1:%d", integration.GetListenPort()), }, + { + Name: "INTEGRATION_HTTP_ADDRESS", + Value: fmt.Sprintf("127.0.0.1:%d", integration.GetHTTPListenPort()), + }, } c := schedulerContainerApi.Container{ diff --git a/pkg/util/grpc/http.go b/pkg/util/grpc/http.go index e53c16d3b..15693634a 100644 --- a/pkg/util/grpc/http.go +++ b/pkg/util/grpc/http.go @@ -21,6 +21,7 @@ package grpc import ( + "bytes" "context" "io" "net/http" @@ -69,18 +70,16 @@ func (h httpResponse[T]) Get() (T, error) { return Unmarshal[T](h.data) } -func Get[T proto.Message](ctx context.Context, client operatorHTTP.HTTPClient, url string, mods ...util.Mod[http.Request]) HTTPResponse[T] { +func request[T proto.Message](ctx context.Context, client operatorHTTP.HTTPClient, method, url string, body io.Reader, mods ...util.Mod[http.Request]) HTTPResponse[T] { if client == nil { client = http.DefaultClient } - req, err := http.NewRequest(http.MethodGet, url, nil) + req, err := http.NewRequestWithContext(ctx, method, url, body) if err != nil { return httpErrorResponse[T]{err: err} } - req = req.WithContext(ctx) - util.ApplyMods(req, mods...) resp, err := client.Do(req) @@ -100,3 +99,16 @@ func Get[T proto.Message](ctx context.Context, client operatorHTTP.HTTPClient, u data: nData, } } + +func Get[T proto.Message](ctx context.Context, client operatorHTTP.HTTPClient, url string, mods ...util.Mod[http.Request]) HTTPResponse[T] { + return request[T](ctx, client, http.MethodGet, url, nil, mods...) +} + +func Post[IN, T proto.Message](ctx context.Context, client operatorHTTP.HTTPClient, in IN, url string, mods ...util.Mod[http.Request]) HTTPResponse[T] { + data, err := Marshal(in) + if err != nil { + return httpErrorResponse[T]{err: err} + } + + return request[T](ctx, client, http.MethodPost, url, bytes.NewReader(data), mods...) +} diff --git a/pkg/util/mod.go b/pkg/util/mod.go index d2b2d3b38..de452cf65 100644 --- a/pkg/util/mod.go +++ b/pkg/util/mod.go @@ -34,7 +34,9 @@ func (m Mod[T]) Optional() Mod[T] { func ApplyMods[T any](in *T, mods ...Mod[T]) { for _, mod := range mods { - mod(in) + if mod != nil { + mod(in) + } } } @@ -54,8 +56,10 @@ func (m ModE[T]) Optional() ModE[T] { func ApplyModsE[T any](in *T, mods ...ModE[T]) error { for _, mod := range mods { - if err := mod(in); err != nil { - return err + if mod != nil { + if err := mod(in); err != nil { + return err + } } } @@ -78,8 +82,10 @@ func (m ModEP1[T, P1]) Optional() ModEP1[T, P1] { func ApplyModsEP1[T, P1 any](in *T, p1 P1, mods ...ModEP1[T, P1]) error { for _, mod := range mods { - if err := mod(in, p1); err != nil { - return err + if mod != nil { + if err := mod(in, p1); err != nil { + return err + } } } From d662425cb2b60b71fe96a73b805f5fc4b7385763 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 27 Feb 2025 16:36:30 +0000 Subject: [PATCH 3/8] Iter --- pkg/util/mod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/util/mod.go b/pkg/util/mod.go index de452cf65..0b28663d1 100644 --- a/pkg/util/mod.go +++ b/pkg/util/mod.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From c50166e7b400d0814a4dc1d0c51f8118b18f9dbe Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Fri, 28 Feb 2025 08:16:55 +0000 Subject: [PATCH 4/8] Iter --- .../shutdown/v1/definition/shutdown.pb.go | 31 ++-- .../shutdown/v1/definition/shutdown.pb.gw.go | 157 ++++++++++++++++++ .../shutdown/v1/definition/shutdown.proto | 8 +- integrations/shutdown/v1/impl.go | 3 +- 4 files changed, 183 insertions(+), 16 deletions(-) create mode 100644 integrations/shutdown/v1/definition/shutdown.pb.gw.go diff --git a/integrations/shutdown/v1/definition/shutdown.pb.go b/integrations/shutdown/v1/definition/shutdown.pb.go index 665f6d7ef..fa4587274 100644 --- a/integrations/shutdown/v1/definition/shutdown.pb.go +++ b/integrations/shutdown/v1/definition/shutdown.pb.go @@ -28,6 +28,7 @@ package definition import ( definition "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -46,19 +47,23 @@ var file_integrations_shutdown_v1_definition_shutdown_proto_rawDesc = []byte{ 0x0a, 0x32, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x1a, 0x2d, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x38, 0x0a, - 0x0a, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x56, 0x31, 0x12, 0x2a, 0x0a, 0x08, 0x53, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, - 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, - 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, + 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x62, 0x0a, 0x0a, 0x53, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x56, 0x31, 0x12, 0x54, 0x0a, 0x08, 0x53, 0x68, 0x75, + 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, + 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x42, + 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, + 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, + 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_integrations_shutdown_v1_definition_shutdown_proto_goTypes = []interface{}{ diff --git a/integrations/shutdown/v1/definition/shutdown.pb.gw.go b/integrations/shutdown/v1/definition/shutdown.pb.gw.go new file mode 100644 index 000000000..f01a42bd9 --- /dev/null +++ b/integrations/shutdown/v1/definition/shutdown.pb.gw.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: integrations/shutdown/v1/definition/shutdown.proto + +/* +Package definition is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package definition + +import ( + "context" + "io" + "net/http" + + definition_6 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_ShutdownV1_Shutdown_0(ctx context.Context, marshaler runtime.Marshaler, client ShutdownV1Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq definition_6.Empty + var metadata runtime.ServerMetadata + + msg, err := client.Shutdown(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ShutdownV1_Shutdown_0(ctx context.Context, marshaler runtime.Marshaler, server ShutdownV1Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq definition_6.Empty + var metadata runtime.ServerMetadata + + msg, err := server.Shutdown(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterShutdownV1HandlerServer registers the http handlers for service ShutdownV1 to "mux". +// UnaryRPC :call ShutdownV1Server 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 RegisterShutdownV1HandlerFromEndpoint 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 RegisterShutdownV1HandlerServer(ctx context.Context, mux *runtime.ServeMux, server ShutdownV1Server) error { + + mux.Handle("GET", pattern_ShutdownV1_Shutdown_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/shutdown.ShutdownV1/Shutdown", runtime.WithHTTPPathPattern("/_integration/shutdown/v1/shutdown")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ShutdownV1_Shutdown_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_ShutdownV1_Shutdown_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterShutdownV1HandlerFromEndpoint is same as RegisterShutdownV1Handler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterShutdownV1HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.NewClient(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) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterShutdownV1Handler(ctx, mux, conn) +} + +// RegisterShutdownV1Handler registers the http handlers for service ShutdownV1 to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterShutdownV1Handler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterShutdownV1HandlerClient(ctx, mux, NewShutdownV1Client(conn)) +} + +// RegisterShutdownV1HandlerClient registers the http handlers for service ShutdownV1 +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ShutdownV1Client". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ShutdownV1Client" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ShutdownV1Client" to call the correct interceptors. This client ignores the HTTP middlewares. +func RegisterShutdownV1HandlerClient(ctx context.Context, mux *runtime.ServeMux, client ShutdownV1Client) error { + + mux.Handle("GET", pattern_ShutdownV1_Shutdown_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/shutdown.ShutdownV1/Shutdown", runtime.WithHTTPPathPattern("/_integration/shutdown/v1/shutdown")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ShutdownV1_Shutdown_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ShutdownV1_Shutdown_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_ShutdownV1_Shutdown_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"_integration", "shutdown", "v1"}, "")) +) + +var ( + forward_ShutdownV1_Shutdown_0 = runtime.ForwardResponseMessage +) diff --git a/integrations/shutdown/v1/definition/shutdown.proto b/integrations/shutdown/v1/definition/shutdown.proto index f850cc986..5ce85c362 100644 --- a/integrations/shutdown/v1/definition/shutdown.proto +++ b/integrations/shutdown/v1/definition/shutdown.proto @@ -22,6 +22,8 @@ syntax = "proto3"; package shutdown; +import "google/api/annotations.proto"; + import "integrations/shared/v1/definition/empty.proto"; option go_package = "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition"; @@ -29,5 +31,9 @@ option go_package = "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/ // ShutdownV1 Service implementation service ShutdownV1 { // ShutdownServer sends the shutdown request - rpc Shutdown (shared.Empty) returns (shared.Empty) {} + rpc Shutdown (shared.Empty) returns (shared.Empty) { + option (google.api.http) = { + get: "/_integration/shutdown/v1/shutdown" + }; + } } diff --git a/integrations/shutdown/v1/impl.go b/integrations/shutdown/v1/impl.go index 718b80ce8..00178a071 100644 --- a/integrations/shutdown/v1/impl.go +++ b/integrations/shutdown/v1/impl.go @@ -58,8 +58,7 @@ func (i *impl) Register(registrar *grpc.Server) { } func (i *impl) Gateway(ctx context.Context, mux *runtime.ServeMux) error { - //TODO implement me - panic("implement me") + return pbShutdownV1.RegisterShutdownV1HandlerServer(ctx, mux, i) } func (i *impl) Shutdown(ctx context.Context, empty *pbSharedV1.Empty) (*pbSharedV1.Empty, error) { From 35e0e658c72c71e434228eff01ac2ff9d4f79071 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Sun, 2 Mar 2025 15:48:44 +0000 Subject: [PATCH 5/8] Match type extension --- .../resources/config_map_gateway.go | 4 +- .../gateway/gateway_config_destination.go | 10 +-- pkg/deployment/resources/gateway/path.go | 72 +++++++++++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 pkg/deployment/resources/gateway/path.go diff --git a/pkg/deployment/resources/config_map_gateway.go b/pkg/deployment/resources/config_map_gateway.go index 23f9793c6..6bfe8d86d 100644 --- a/pkg/deployment/resources/config_map_gateway.go +++ b/pkg/deployment/resources/config_map_gateway.go @@ -78,7 +78,9 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec } cfg.Destinations[constants.EnvoyIdentityDestination] = gateway.ConfigDestination{ - Type: util.NewType(gateway.ConfigDestinationTypeHTTP), + Type: util.NewType(gateway.ConfigDestinationTypeHTTP), + Match: util.NewType(gateway.ConfigMatchPath), + Path: util.NewType("/_integration/authn/v1/identity"), AuthExtension: &gateway.ConfigAuthZExtension{ AuthZExtension: map[string]string{ pbImplEnvoyAuthV3.AuthConfigAuthRequiredKey: pbImplEnvoyAuthV3.AuthConfigKeywordFalse, diff --git a/pkg/deployment/resources/gateway/gateway_config_destination.go b/pkg/deployment/resources/gateway/gateway_config_destination.go index 13b5683ec..572de07e2 100644 --- a/pkg/deployment/resources/gateway/gateway_config_destination.go +++ b/pkg/deployment/resources/gateway/gateway_config_destination.go @@ -66,6 +66,8 @@ type ConfigDestination struct { Protocol *ConfigDestinationProtocol `json:"protocol,omitempty"` + Match *ConfigMatch `json:"match,omitempty"` + Path *string `json:"path,omitempty"` AuthExtension *ConfigAuthZExtension `json:"authExtension,omitempty"` @@ -91,6 +93,7 @@ func (c *ConfigDestination) Validate() error { return shared.WithErrors( shared.PrefixResourceError("type", c.Type.Validate()), shared.PrefixResourceError("path", shared.ValidateAPIPath(c.GetPath())), + shared.PrefixResourceError("pathType", shared.ValidateOptionalInterface(c.Match)), shared.PrefixResourceError("authExtension", c.AuthExtension.Validate()), shared.PrefixResourceError("static", shared.ValidateRequiredInterface(c.Static)), ) @@ -101,6 +104,7 @@ func (c *ConfigDestination) Validate() error { shared.PrefixResourceError("protocol", c.Protocol.Validate()), shared.PrefixResourceError("tls", c.TLS.Validate()), shared.PrefixResourceError("path", shared.ValidateAPIPath(c.GetPath())), + shared.PrefixResourceError("pathType", shared.ValidateOptionalInterface(c.Match)), shared.PrefixResourceError("authExtension", c.AuthExtension.Validate()), shared.PrefixResourceError("upgradeConfigs", c.UpgradeConfigs.Validate()), shared.PrefixResourceErrorFunc("timeout", func() error { @@ -159,11 +163,7 @@ func (c *ConfigDestination) RenderRoute(name, prefix string) (*routeAPI.Route, e } r := &routeAPI.Route{ - Match: &routeAPI.RouteMatch{ - PathSpecifier: &routeAPI.RouteMatch_Prefix{ - Prefix: prefix, - }, - }, + Match: c.Match.Match(prefix), ResponseHeadersToAdd: headers, TypedPerFilterConfig: tc, diff --git a/pkg/deployment/resources/gateway/path.go b/pkg/deployment/resources/gateway/path.go new file mode 100644 index 000000000..fa02989d6 --- /dev/null +++ b/pkg/deployment/resources/gateway/path.go @@ -0,0 +1,72 @@ +// +// DISCLAIMER +// +// Copyright 2025 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package gateway + +import ( + routeAPI "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + "github.com/pkg/errors" +) + +type ConfigMatch int + +const ( + ConfigMatchPrefix ConfigMatch = iota + ConfigMatchPath +) + +func (c *ConfigMatch) Get() ConfigMatch { + if c == nil { + return ConfigMatchPrefix + } + + switch v := *c; v { + case ConfigMatchPrefix, ConfigMatchPath: + return v + default: + return ConfigMatchPrefix + } +} + +func (c *ConfigMatch) Validate() error { + switch c.Get() { + case ConfigMatchPrefix, ConfigMatchPath: + return nil + default: + return errors.Errorf("Invalid path type") + } +} + +func (c *ConfigMatch) Match(path string) *routeAPI.RouteMatch { + switch c.Get() { + case ConfigMatchPath: + return &routeAPI.RouteMatch{ + PathSpecifier: &routeAPI.RouteMatch_Path{ + Path: path, + }, + } + default: + return &routeAPI.RouteMatch{ + PathSpecifier: &routeAPI.RouteMatch_Prefix{ + Prefix: path, + }, + } + } +} From 202b051b064c04e7be74358dbda3b0084934fc46 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Sun, 2 Mar 2025 15:49:11 +0000 Subject: [PATCH 6/8] Match type extension --- pkg/deployment/resources/config_map_gateway.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/deployment/resources/config_map_gateway.go b/pkg/deployment/resources/config_map_gateway.go index 6bfe8d86d..910f7ecbc 100644 --- a/pkg/deployment/resources/config_map_gateway.go +++ b/pkg/deployment/resources/config_map_gateway.go @@ -58,7 +58,8 @@ func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspec } cfg.Destinations[constants.EnvoyInventoryConfigDestination] = gateway.ConfigDestination{ - Type: util.NewType(gateway.ConfigDestinationTypeStatic), + Type: util.NewType(gateway.ConfigDestinationTypeStatic), + Match: util.NewType(gateway.ConfigMatchPath), AuthExtension: &gateway.ConfigAuthZExtension{ AuthZExtension: map[string]string{ pbImplEnvoyAuthV3.AuthConfigAuthRequiredKey: pbImplEnvoyAuthV3.AuthConfigKeywordTrue, From 28c50a863083a2168995cd37ea3af66456479aac Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:49:26 +0000 Subject: [PATCH 7/8] Match type extension --- .../resources/gateway/gateway_config.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/deployment/resources/gateway/gateway_config.go b/pkg/deployment/resources/gateway/gateway_config.go index b2f155976..491ff8cfb 100644 --- a/pkg/deployment/resources/gateway/gateway_config.go +++ b/pkg/deployment/resources/gateway/gateway_config.go @@ -260,8 +260,22 @@ func (c Config) RenderRoutes() ([]*routeAPI.Route, error) { routes = append(routes, c) } - sort.Slice(routes, func(i, j int) bool { - return routes[i].GetMatch().GetPrefix() > routes[j].GetMatch().GetPrefix() + sort.SliceStable(routes, func(i, j int) bool { + iPath := routes[i].GetMatch().GetPath() + iPrefix := routes[i].GetMatch().GetPrefix() + + jPath := routes[j].GetMatch().GetPath() + jPrefix := routes[j].GetMatch().GetPrefix() + + if iPath != "" && jPath != "" { + return iPath > jPath + } else if iPath == "" && jPath != "" { + return false + } else if iPath != "" && jPath == "" { + return true + } else { + return iPrefix > jPrefix + } }) return routes, nil From 6a405fc8683ddfdf183221a3f1494c811a81d5ea Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Mon, 3 Mar 2025 08:00:15 +0000 Subject: [PATCH 8/8] Match type extension --- integrations/authentication/v1/http_test.go | 176 ++++++++++---------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/integrations/authentication/v1/http_test.go b/integrations/authentication/v1/http_test.go index 53d6200b2..3ad18824a 100644 --- a/integrations/authentication/v1/http_test.go +++ b/integrations/authentication/v1/http_test.go @@ -48,94 +48,94 @@ func Test_Authentication_HTTP(t *testing.T) { client := operatorHTTP.NewHTTPClient() - //t.Run("Without header", func(t *testing.T) { - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress())) - // - // resp.WithCode(http.StatusUnauthorized) - //}) - // - //t.Run("With invalid header", func(t *testing.T) { - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - // in.Header.Add("invalid", "") - // }) - // - // resp.WithCode(http.StatusUnauthorized) - //}) - // - //t.Run("With empty header", func(t *testing.T) { - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - // in.Header.Add("Authorization", "") - // }) - // - // resp.WithCode(http.StatusUnauthorized) - //}) - // - //t.Run("With missing prefix header", func(t *testing.T) { - // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( - // ctx, - // client, - // &pbAuthenticationV1.CreateTokenRequest{ - // Lifetime: durationpb.New(time.Minute), - // User: util.NewType(DefaultUser), - // }, - // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), - // ). - // WithCode(http.StatusOK). - // Get() - // require.NoError(t, err) - // - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - // in.Header.Add("Authorization", token.Token) - // }) - // - // resp.WithCode(http.StatusUnauthorized) - //}) - // - //t.Run("With header", func(t *testing.T) { - // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( - // ctx, - // client, - // &pbAuthenticationV1.CreateTokenRequest{ - // Lifetime: durationpb.New(time.Minute), - // User: util.NewType(DefaultUser), - // }, - // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), - // ). - // WithCode(http.StatusOK). - // Get() - // require.NoError(t, err) - // - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) - // }) - // - // data, err := resp.WithCode(http.StatusOK).Get() - // require.NoError(t, err) - // - // require.EqualValues(t, DefaultUser, data.GetUser()) - //}) - // - //t.Run("With multi header", func(t *testing.T) { - // token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( - // ctx, - // client, - // &pbAuthenticationV1.CreateTokenRequest{ - // Lifetime: durationpb.New(time.Minute), - // User: util.NewType(DefaultUser), - // }, - // fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), - // ). - // WithCode(http.StatusOK). - // Get() - // require.NoError(t, err) - // - // resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { - // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) - // in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) - // }) - // - // resp.WithCode(http.StatusUnauthorized) - //}) + t.Run("Without header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress())) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With invalid header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("invalid", "") + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With empty header", func(t *testing.T) { + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", "") + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With missing prefix header", func(t *testing.T) { + token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + ctx, + client, + &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }, + fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + ). + WithCode(http.StatusOK). + Get() + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", token.Token) + }) + + resp.WithCode(http.StatusUnauthorized) + }) + + t.Run("With header", func(t *testing.T) { + token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + ctx, + client, + &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }, + fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + ). + WithCode(http.StatusOK). + Get() + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + }) + + data, err := resp.WithCode(http.StatusOK).Get() + require.NoError(t, err) + + require.EqualValues(t, DefaultUser, data.GetUser()) + }) + + t.Run("With multi header", func(t *testing.T) { + token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse]( + ctx, + client, + &pbAuthenticationV1.CreateTokenRequest{ + Lifetime: durationpb.New(time.Minute), + User: util.NewType(DefaultUser), + }, + fmt.Sprintf("http://%s/_integration/authn/v1/createToken", server.HTTPAddress()), + ). + WithCode(http.StatusOK). + Get() + require.NoError(t, err) + + resp := ugrpc.Get[*pbAuthenticationV1.IdentityResponse](ctx, client, fmt.Sprintf("http://%s/_integration/authn/v1/identity", server.HTTPAddress()), func(in *http.Request) { + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + in.Header.Add("Authorization", fmt.Sprintf("bearer %s", token.Token)) + }) + + resp.WithCode(http.StatusUnauthorized) + }) t.Run("Validate", func(t *testing.T) { token, err := ugrpc.Post[*pbAuthenticationV1.CreateTokenRequest, *pbAuthenticationV1.CreateTokenResponse](