From 83da475722a0a0505f27e30b003453c3b5184dd0 Mon Sep 17 00:00:00 2001 From: CrowleyRajapakse Date: Sat, 22 Feb 2025 13:52:15 +0530 Subject: [PATCH] adding DP to CP flow for multi endpoints --- .../internal/controlplane/eventPublisher.go | 20 ++++++ .../operator/controllers/dp/api_controller.go | 70 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/adapter/internal/controlplane/eventPublisher.go b/adapter/internal/controlplane/eventPublisher.go index 044110211..6c1a84e1a 100644 --- a/adapter/internal/controlplane/eventPublisher.go +++ b/adapter/internal/controlplane/eventPublisher.go @@ -105,6 +105,7 @@ type API struct { APIHash string `json:"-"` SandAIRL *AIRL `json:"sandAIRL"` ProdAIRL *AIRL `json:"prodAIRL"` + MultiEndpoints APIEndpoints `json:"multiEndpoints"` } // AIRL holds AI ratelimit related data @@ -127,6 +128,25 @@ type EndpointSecurity struct { BasicPassword string `json:"basicPassword"` } +// EndpointConfig holds endpoint-specific settings. +type EndpointConfig struct { // "prod" or "sand" + URL string + SecurityType string + SecurityEnabled bool + APIKeyName string + APIKeyIn string + APIKeyValue string + BasicUsername string + BasicPassword string +} + +// APIEndpoints holds the common protocol and a list of endpoint configurations. +type APIEndpoints struct { + Protocol string + ProdEndpoints []EndpointConfig + SandEndpoints []EndpointConfig +} + // AIConfiguration holds the AI configuration type AIConfiguration struct { LLMProviderID string `json:"llmProviderID"` diff --git a/adapter/internal/operator/controllers/dp/api_controller.go b/adapter/internal/operator/controllers/dp/api_controller.go index 8dfefb71c..145c29d2c 100644 --- a/adapter/internal/operator/controllers/dp/api_controller.go +++ b/adapter/internal/operator/controllers/dp/api_controller.go @@ -3062,6 +3062,15 @@ func (apiReconciler *APIReconciler) convertAPIStateToAPICp(ctx context.Context, properties[val.Name] = val.Value } prodEndpoint, sandEndpoint, endpointProtocol, prodAPIKeyName, prodAPIKeyIn, prodAPIKeyValue, prodBasicUsername, prodBasicPassword, sandAPIKeyName, sandAPIKeyIn, sandAPIKeyValue, sandBasicUsername, sandBasicPassword, prodEndpointSecurityType, sandEndpointSecurityType, prodEndpointSecurityEnabled, sandEndpointSecurityEnabled := findProdSandEndpoints(&apiState) + apiEndpoints := controlplane.APIEndpoints{} + if apiState.AIProvider != nil { + if apiState.AIProvider.Spec.ProviderName != "" { + loggers.LoggerAPKOperator.Infof("AIProvider is found") + apiEndpoints = findProdSandEndpointsAIAPIs(&apiState) + loggers.LoggerAPKOperator.Infof("APIEndpoints: %+v", apiEndpoints) + } + } + corsPolicy := pickOneCorsForCP(&apiState) vhost := getProdVhost(&apiState) sandVhost := geSandVhost(&apiState) @@ -3173,7 +3182,9 @@ func (apiReconciler *APIReconciler) convertAPIStateToAPICp(ctx context.Context, SandAIRL: sandAIRLToAgent, ProdAIRL: prodAIRLToAgent, AIConfiguration: aiConfiguration, + MultiEndpoints: apiEndpoints, } + loggers.LoggerAPKOperator.Infof("CP API: %+v", api) apiCPEvent.API = api apiCPEvent.CRName = apiState.APIDefinition.ObjectMeta.Name apiCPEvent.CRNamespace = apiState.APIDefinition.ObjectMeta.Namespace @@ -3462,6 +3473,65 @@ func findProdSandEndpoints(apiState *synchronizer.APIState) (string, string, str return prodEndpoint, sandEndpoint, endpointProtocol, prodAPIKeyName, prodAPIKeyIn, prodAPIKeyValue, prodBasicUsername, prodBasicPassword, sandAPIKeyName, sandAPIKeyIn, sandAPIKeyValue, sandBasicUsername, sandBasicPassword, prodEndpointSecurityType, sandEndpointSecurityType, prodEndpointSecurityEnabled, sandEndpointSecurityEnabled } +func findProdSandEndpointsAIAPIs(apiState *synchronizer.APIState) controlplane.APIEndpoints { + + apiEndpoints := &controlplane.APIEndpoints{} + prodEndpoints := []controlplane.EndpointConfig{} + sandEndpoints := []controlplane.EndpointConfig{} + endpointProtocol := "" + + if apiState.ProdHTTPRoute != nil { + for _, backend := range apiState.ProdHTTPRoute.BackendMapping { + prodEndpoint := controlplane.EndpointConfig{} + if len(backend.Backend.Spec.Services) > 0 { + prodEndpoint.URL = fmt.Sprintf("%s:%d%s", backend.Backend.Spec.Services[0].Host, backend.Backend.Spec.Services[0].Port, backend.Backend.Spec.BasePath) + endpointProtocol = string(backend.Backend.Spec.Protocol) + } + if backend.Security.Basic.Username != "" && backend.Security.Basic.Password != "" { + prodEndpoint.SecurityEnabled = true + prodEndpoint.SecurityType = "basic" + prodEndpoint.BasicUsername = backend.Security.Basic.Username + prodEndpoint.BasicPassword = backend.Security.Basic.Password + } + if backend.Security.APIKey.Name != "" && backend.Security.APIKey.Value != "" && backend.Security.APIKey.In != "" { + prodEndpoint.SecurityEnabled = true + prodEndpoint.SecurityType = "apikey" + prodEndpoint.APIKeyName = backend.Security.APIKey.Name + prodEndpoint.APIKeyIn = string(backend.Security.APIKey.In) + prodEndpoint.APIKeyValue = backend.Security.APIKey.Value + } + prodEndpoints = append(prodEndpoints, prodEndpoint) + } + } + if apiState.SandHTTPRoute != nil { + for _, backend := range apiState.SandHTTPRoute.BackendMapping { + sandEndpoint := controlplane.EndpointConfig{} + if len(backend.Backend.Spec.Services) > 0 { + sandEndpoint.URL = fmt.Sprintf("%s:%d%s", backend.Backend.Spec.Services[0].Host, backend.Backend.Spec.Services[0].Port, backend.Backend.Spec.BasePath) + endpointProtocol = string(backend.Backend.Spec.Protocol) + } + if backend.Security.Basic.Username != "" && backend.Security.Basic.Password != "" { + sandEndpoint.SecurityEnabled = true + sandEndpoint.SecurityType = "basic" + sandEndpoint.BasicUsername = backend.Security.Basic.Username + sandEndpoint.BasicPassword = backend.Security.Basic.Password + } + if backend.Security.APIKey.Name != "" && backend.Security.APIKey.Value != "" && backend.Security.APIKey.In != "" { + sandEndpoint.SecurityEnabled = true + sandEndpoint.SecurityType = "apikey" + sandEndpoint.APIKeyName = backend.Security.APIKey.Name + sandEndpoint.APIKeyIn = string(backend.Security.APIKey.In) + sandEndpoint.APIKeyValue = backend.Security.APIKey.Value + } + sandEndpoints = append(sandEndpoints, sandEndpoint) + } + } + apiEndpoints.Protocol = endpointProtocol + apiEndpoints.ProdEndpoints = prodEndpoints + apiEndpoints.SandEndpoints = sandEndpoints + return *apiEndpoints +} + func pickOneCorsForCP(apiState *synchronizer.APIState) *controlplane.CORSPolicy { apiPolicies := []dpv1alpha4.APIPolicy{} for _, apiPolicy := range apiState.APIPolicies {