From 2f908b5f0058cf3164e287d46e0082d11a19832e Mon Sep 17 00:00:00 2001 From: sgayangi Date: Tue, 4 Jun 2024 14:08:45 +0530 Subject: [PATCH] Address review comments --- .../ballerina/APIClient.bal | 70 ++--- .../ballerina/types.bal | 260 +++++++++++++++--- 2 files changed, 264 insertions(+), 66 deletions(-) diff --git a/runtime/config-deployer-service/ballerina/APIClient.bal b/runtime/config-deployer-service/ballerina/APIClient.bal index 23ea0ba4f..335b15be6 100644 --- a/runtime/config-deployer-service/ballerina/APIClient.bal +++ b/runtime/config-deployer-service/ballerina/APIClient.bal @@ -448,7 +448,7 @@ public class APIClient { sandboxRoutes.push(gqlRoute.metadata.name); } } - } else { + } else if apkConf.'type == API_TYPE_REST { foreach model:HTTPRoute httpRoute in apiArtifact.productionHttpRoutes { if httpRoute.spec.rules.length() > 0 { productionRoutes.push(httpRoute.metadata.name); @@ -538,7 +538,7 @@ public class APIClient { apiArtifact.sandboxGqlRoutes.push(gqlRoute); } } - } else { + } else if apkConf.'type == API_TYPE_REST { model:HTTPRoute httpRoute = { metadata: { @@ -558,6 +558,8 @@ public class APIClient { apiArtifact.sandboxHttpRoutes.push(httpRoute); } } + } else { + return e909018("Invalid API Type specified"); } return; @@ -784,18 +786,23 @@ public class APIClient { } else { return e909022("Provided Type currently not supported for GraphQL APIs.", error("Provided Type currently not supported for GraphQL APIs.")); } + } else if apkConf.'type == API_TYPE_REST { + { + model:HTTPRouteRule httpRouteRule = { + matches: self.retrieveHTTPMatches(apkConf, operation, organization), + backendRefs: self.retrieveGeneratedBackend(apkConf, endpointToUse, endpointType), + filters: self.generateFilters(apiArtifact, apkConf, endpointToUse, operation, endpointType, organization) + }; + return httpRouteRule; + } } else { - model:HTTPRouteRule httpRouteRule = { - matches: self.retrieveHTTPMatches(apkConf, operation, organization), - backendRefs: self.retrieveGeneratedBackend(apkConf, endpointToUse, endpointType), - filters: self.generateFilters(apiArtifact, apkConf, endpointToUse, operation, endpointType, organization) - }; - return httpRouteRule; + return e909018("Invalid API Type specified"); } } else { return (); } - } on fail var e { + } + on fail var e { log:printError("Internal Error occured", e); return e909022("Internal Error occured", e); } @@ -823,6 +830,7 @@ public class APIClient { if operationPoliciesToUse is APIOperationPolicies { APKOperationPolicy[]? requestPolicies = operationPoliciesToUse.request; APKOperationPolicy[]? responsePolicies = operationPoliciesToUse.response; + if requestPolicies is APKOperationPolicy[] && requestPolicies.length() > 0 { model:HTTPRouteFilter headerModifierFilter = {'type: "RequestHeaderModifier"}; headerModifierFilter.requestHeaderModifier = self.extractHttpHeaderFilterData(requestPolicies, organization); @@ -844,34 +852,36 @@ public class APIClient { foreach APKOperationPolicy policy in operationPolicy { if policy is HeaderModifierPolicy { HeaderModifierPolicyParameters policyParameters = policy.parameters; - if policy.policyName == "AddHeaders" { - ModifierHeader[] addHeaders = policyParameters.headers; - foreach ModifierHeader header in addHeaders { - addPolicies.push(header); + match policy.policyName { + AddHeaders => { + ModifierHeader[] addHeaders = policyParameters.headers; + foreach ModifierHeader header in addHeaders { + addPolicies.push(header); + } } - } - if policy.policyName == "SetHeaders" { - ModifierHeader[] setHeaders = policyParameters.headers; - foreach ModifierHeader header in setHeaders { - setPolicies.push(header); + SetHeaders => { + ModifierHeader[] setHeaders = policyParameters.headers; + foreach ModifierHeader header in setHeaders { + setPolicies.push(header); + } } - } - if policy.policyName == "RemoveHeaders" { - string[] removeHeaders = policyParameters.headers; - foreach string header in removeHeaders { - removePolicies.push(header); + RemoveHeaders => { + string[] removeHeaders = policyParameters.headers; + foreach string header in removeHeaders { + removePolicies.push(header); + } } } } } model:HTTPHeaderFilter headerModifier = {}; - if (addPolicies != []) { + if addPolicies != [] { headerModifier.add = addPolicies; } - if (setPolicies != []) { + if setPolicies != [] { headerModifier.set = setPolicies; } - if (removePolicies != []) { + if removePolicies != [] { headerModifier.remove = removePolicies; } return headerModifier; @@ -1236,7 +1246,7 @@ public class APIClient { foreach APKOperationPolicy policy in policies { string policyName = policy.policyName; if policy.parameters is record {} { - if (policyName == "Interceptor") { + if (policyName == Interceptor) { InterceptorPolicy interceptorPolicy = check policy.cloneWithType(InterceptorPolicy); InterceptorPolicy_parameters parameters = interceptorPolicy?.parameters; EndpointConfiguration endpointConfig = {endpoint: parameters.backendUrl ?: "", certificate: {secretName: parameters.tlsSecretName, secretKey: parameters.tlsSecretKey}}; @@ -1255,14 +1265,12 @@ public class APIClient { }; } policyReferences.push(interceptorReference); - } else if (policyName == "BackendJwt") { + } else if (policyName == BackendJwt) { BackendJWTPolicy backendJWTPolicy = check policy.cloneWithType(BackendJWTPolicy); model:BackendJWT backendJwt = self.retrieveBackendJWTPolicy(apkConf, apiArtifact, backendJWTPolicy, operations, organization); apiArtifact.backendJwt = backendJwt; policyReferences.push({name: backendJwt.metadata.name}); - } else if (policyName == "AddHeaders" || policyName == "SetHeaders" || policyName == "RemoveHeaders") { - - } else { + } else if policyName != AddHeaders && policyName != SetHeaders && policyName != RemoveHeaders { return e909052(error("Incorrect API Policy name provided.")); } } diff --git a/runtime/config-deployer-service/ballerina/types.bal b/runtime/config-deployer-service/ballerina/types.bal index 8685a1e03..1f59fd5d3 100644 --- a/runtime/config-deployer-service/ballerina/types.bal +++ b/runtime/config-deployer-service/ballerina/types.bal @@ -1,53 +1,85 @@ +import ballerina/constraint; // AUTO-GENERATED FILE. // This file is auto-generated by the Ballerina OpenAPI tool. - import ballerina/http; -import ballerina/constraint; +# Configuration for a successful response. +# +# + body - The body of the response containing any data. public type OkAnydata record {| *http:Ok; anydata body; |}; +# Configuration for a Not Found error response. +# +# + body - The body of the response containing error details. public type NotFoundError record {| *http:NotFound; Error body; |}; +# Configuration for a Bad Request error response. +# +# + body - The body of the response containing error details. public type BadRequestError record {| *http:BadRequest; Error body; |}; +# Configuration for an Accepted response. +# +# + body - The body of the response containing a string. public type AcceptedString record {| *http:Accepted; string body; |}; +# Configuration for Internal Server Error response. +# +# + body - The body of the response containing error details. public type InternalServerErrorError record {| *http:InternalServerError; Error body; |}; +# Configuration for a list of errors. +# +# + code - The code representing the error. +# + message - Description about individual errors occurred. +# + description - A detailed description about the error message. public type ErrorListItem record { string code; - # Description about individual errors occurred string message; - # A detail description about the error message. string description?; }; +# Configuration for Endpoint Security. +# +# + enabled - Indicates whether the endpoint security is enabled. +# + securityType - Configuration for the basic endpoint security. public type EndpointSecurity record { boolean enabled?; BasicEndpointSecurity securityType?; }; +# Configuration for Custom Claims. +# +# + claim - The name of the custom claim. +# + value - The value of the custom claim. +# + type - The type of the custom claim. public type CustomClaims record { string claim; string value; string 'type = "string"; }; +# Configuration for a K8s Service. +# +# + name - The name of the K8s service. +# + namespace - The namespace in which the service is defined. +# + port - The port on which the service is exposed. +# + protocol - The protocol used by the service (e.g., "TCP", "UDP"). public type K8sService record { string name?; string namespace?; @@ -55,23 +87,38 @@ public type K8sService record { string protocol?; }; +# Configuration for Rate Limiting. +# +# + requestsPerUnit - Number of requests allowed per specified unit of time. +# + unit - Unit of time for the rate limit. public type RateLimit record { - # Number of requests allowed per specified unit of time int requestsPerUnit; - # Unit of time string unit; }; +# Configuration for Basic Endpoint Security. +# +# + secretName - The name of the secret containing the credentials. +# + userNameKey - The key to retrieve the username from the secret. +# + passwordKey - The key to retrieve the password from the secret. public type BasicEndpointSecurity record { string secretName?; string userNameKey?; string passwordKey?; }; +# Configuration for APK Operations. +# +# + target - The target endpoint for the operation. +# + verb - The HTTP verb for the operation. +# + secured - Indicates if authentication is applied to the operation(true/false). +# + endpointConfigurations - Configuration for the endpoint. +# + operationPolicies - Policies to be applied for the operation. +# + rateLimit - Rate limiting configuration for the operation. +# + scopes - Scopes required for the operation. public type APKOperations record { string target?; string verb?; - # Authentication mode for resource (true/false) boolean secured?; EndpointConfigurations endpointConfigurations?; APIOperationPolicies operationPolicies?; @@ -79,31 +126,54 @@ public type APKOperations record { string[] scopes?; }; +# Common type for operation policies. public type APKOperationPolicy InterceptorPolicy|BackendJWTPolicy|HeaderModifierPolicy; +# Configuration for API deployment using the apk-conf file. +# +# + apkConfiguration - APK Configuration (apk-conf) file. +# + definitionFile - API definition (OAS/Graphql/WebSocket). public type DeployApiBody record { - # apk-configuration file record {byte[] fileContent; string fileName;} apkConfiguration?; - # api definition (OAS/Graphql/WebSocket) record {byte[] fileContent; string fileName;} definitionFile?; }; +# Configuration of APK Operation Policies. +# +# + request - List of policies to be applied on the request. +# + response - List of policies to be applied on the response. public type APIOperationPolicies record { APKOperationPolicy[] request?; APKOperationPolicy[] response?; }; +# Additional properties for APK configuration. +# +# + name - The name of the additional property. +# + value - The value of the additional property. public type APKConf_additionalProperties record { string name?; string value?; }; +# Configuration of Resiliency settings. +# +# + circuitBreaker - Configuration for the CircuitBreaker. +# + timeout - Configuration for the Timeout. +# + retryPolicy - Configuration for the RetryPolicy. public type Resiliency record { CircuitBreaker circuitBreaker?; Timeout timeout?; RetryPolicy retryPolicy?; }; +# Configuration of CircuitBreaker settings. +# +# + maxConnectionPools - The maximum number of connection pools allowed. +# + maxConnections - The maximum number of connections allowed. +# + maxPendingRequests - The maximum number of pending requests allowed. +# + maxRequests - The maximum number of requests allowed. +# + maxRetries - The maximum number of retries allowed. public type CircuitBreaker record { int maxConnectionPools?; int maxConnections?; @@ -112,13 +182,37 @@ public type CircuitBreaker record { int maxRetries?; }; +# Common type for all authentication types. public type AuthenticationRequest OAuth2Authentication|APIKeyAuthentication|MTLSAuthentication|JWTAuthentication; +# Configuration for production and sandbox endpoints. +# +# + production - Production endpoint. +# + sandbox - Sandbox endpoint. public type EndpointConfigurations record { EndpointConfiguration production?; EndpointConfiguration sandbox?; }; +# Configuration for production and sandbox endpoints. +# +# + endpoint - The endpoint which can be a string or a Kubernetes service. +# + endpointSecurity - The security configuration for the endpoint. +# + certificate - The certificate configuration for the endpoint. +# + resiliency - The resiliency configuration for the endpoint. +public type EndpointConfiguration record { + string|K8sService endpoint; + EndpointSecurity endpointSecurity?; + Certificate certificate?; + Resiliency resiliency?; +}; + +# Configuration of OAuth2 Authentication type. +# +# + required - Is OAuth2 authentication mandatory/optional. +# + sendTokenToUpstream - Enables sending the value to the upstream. +# + headerName - Header name for sending the OAuth2 value. +# + headerEnable - Enable sending OAuth2 as a header. public type OAuth2Authentication record {| *Authentication; string required = "mandatory"; @@ -127,6 +221,13 @@ public type OAuth2Authentication record {| boolean headerEnable = true; |}; +# Configuration of JWT Authentication type. +# +# + required - Is JWT authentication mandatory/optional. +# + sendTokenToUpstream - Enables sending the value to the upstream. +# + headerName - Header name for sending the JWT value. +# + headerEnable - Enable sending the JWT as a header. +# + audience - List of audiences for the JWT. public type JWTAuthentication record {| *Authentication; string required = "mandatory"; @@ -136,39 +237,49 @@ public type JWTAuthentication record {| string[] audience = []; |}; +# Configuration of timeout. +# +# + downstreamRequestIdleTimeout - field description +# + upstreamResponseTimeout - field description public type Timeout record { int downstreamRequestIdleTimeout?; int upstreamResponseTimeout?; }; +# Configuration needed to generate K8s resources. +# +# + apkConfiguration - APK Configuration (apk-conf) file. +# + definitionFile - API definition (OAS/Graphql/WebSocket) +# + apiType - Type of API. public type GenerateK8sResourcesBody record { - # apk-configuration file record {byte[] fileContent; string fileName;} apkConfiguration?; - # api definition (OAS/Graphql/WebSocket) record {byte[] fileContent; string fileName;} definitionFile?; - # Type of API string apiType?; }; +# Configuration of an error. +# +# + code - Error code. +# + message - Error message. +# + description - A detailed description about the error message. +# + moreInfo - Preferably a URL with more details about the error. +# + 'error - A list containing multiple errors if any. For example, list out validation errors by each field. public type Error record { int code; - # Error message. string message; - # A detail description about the error message. string description?; - # Preferably an url with more details about the error. string moreInfo?; - # If there are more than one error list them out. - # For example, list out validation errors by each field. ErrorListItem[] 'error?; }; +# Definition body of the API definition. +# +# + definition - API definition (OAS/Graphql/WebSocket). +# + url - URL of API definition. +# + apiType - Type of API. public type DefinitionBody record { - # api definition (OAS/Graphql/WebSocket) record {byte[] fileContent; string fileName;} definition?; - # url of api definition string url?; - # Type of API string apiType?; }; @@ -191,29 +302,70 @@ public type CORSConfiguration record { string[] accessControlExposeHeaders?; }; +# Common configuration of all policies. +# +# + policyName - Name of the policy. +# + policyVersion - Version of the policy. +# + policyId - ID of the policy. public type BaseOperationPolicy record { - string policyName; + PolicyName policyName; string policyVersion = "v1"; string policyId?; }; +# Enum for all possible policy types. +public enum PolicyName { + BackendJwt, + Interceptor, + AddHeaders, + SetHeaders, + RemoveHeaders +} + +# Configuration for authentication types. +# +# + authType - Type of authentication. +# + enabled - Enable/disable the specific authentication type. public type Authentication record {| string authType?; boolean enabled = true; |}; +# Header modification configuration for an operation. +# +# + parameters - Contains header name and value of the header. public type HeaderModifierPolicy record { *BaseOperationPolicy; HeaderModifierPolicyParameters parameters; }; +# Interceptor policy configuration for an operation. +# +# + parameters - Contains interceptor policy parameters public type InterceptorPolicy record { *BaseOperationPolicy; InterceptorPolicy_parameters parameters?; }; +# APK configuration for a given API +# +# + id - UUID of the API. +# + name - Name of the API. +# + basePath - Context of the API. +# + version - Version of the API. +# + 'type - Type of the API. ex: REST, GraphQL +# + definitionPath - Endpoint to expose API Definition. +# + defaultVersion - Is this the default version of the API. +# + subscriptionValidation - Is subscription validation enabled for the API. +# + environment - Environment of the API. +# + endpointConfigurations - Sandbox and production endpoint configurations of the API +# + operations - List of operations for this API. +# + apiPolicies - Policies like interceptor to be added to the entire API. +# + rateLimit - Rate limiting configuration for the API. +# + authentication - Authentication configuration for the API. +# + additionalProperties - Map of custom properties of API +# + corsConfiguration - CORS Configuration of API public type APKConf record { - # UUID of the API string id?; @constraint:String {maxLength: 60, minLength: 1} string name; @@ -222,40 +374,55 @@ public type APKConf record { @constraint:String {maxLength: 30, minLength: 1} string version; string 'type = API_TYPE_REST; - # Endpoint to expose API Definition string definitionPath?; - # Is this the default version of the API boolean defaultVersion = false; - # Is subscription validation enabled for the API boolean subscriptionValidation = false; - # Environment of the API string environment?; EndpointConfigurations endpointConfigurations?; APKOperations[] operations?; APIOperationPolicies apiPolicies?; RateLimit rateLimit?; AuthenticationRequest[] authentication?; - # Map of custom properties of API APKConf_additionalProperties[] additionalProperties?; - # CORS Configuration of API CORSConfiguration corsConfiguration?; }; +# Configuration for header modifiers as received from the apk-conf file. +# +# + headers - Headers to be added, set or removed. public type HeaderModifierPolicyParameters record {| ModifierHeader[]|string[] headers; |}; +# Configuration containing the different headers. +# +# + addHeaders - Headers to be added. +# + setHeaders - Headers to be set. +# + removeHeaders - Headers to be removed. public type HeaderModifierFilterParameters record {| ModifierHeader[] addHeaders; ModifierHeader[] setHeaders; string[] removeHeaders; |}; +# Configuration for headers. +# +# + name - The name of the header. +# + value - The value of the header. public type ModifierHeader record {| string name; string value; |}; +# Configuration for Interceptor Policy parameters. +# +# + backendUrl - Backend URL of the interceptor service. +# + headersEnabled - Indicates whether request/response headers should be sent to the interceptor service. +# + bodyEnabled - Indicates whether request/response body should be sent to the interceptor service. +# + trailersEnabled - Indicates whether request/response trailers should be sent to the interceptor service. +# + contextEnabled - Indicates whether context details should be sent to the interceptor service. +# + tlsSecretName - (Optional parameter) The reference name for K8s ConfigMap with TLS information. +# + tlsSecretKey - (Optional parameter)The TLS key name. public type InterceptorPolicy_parameters record {| string backendUrl?; boolean headersEnabled?; @@ -266,6 +433,13 @@ public type InterceptorPolicy_parameters record {| string tlsSecretKey?; |}; +# Configuration for Backend JWT Policy parameters. +# +# + encoding - The encoding method for the JWT. +# + signingAlgorithm - The algorithm used for signing the JWT. +# + header - The header used for the JWT. +# + tokenTTL - The time-to-live (TTL) for the token. +# + customClaims - Custom claims to be included in the JWT. public type BackendJWTPolicy_parameters record {| string encoding?; string signingAlgorithm?; @@ -274,24 +448,32 @@ public type BackendJWTPolicy_parameters record {| CustomClaims[] customClaims?; |}; -public type EndpointConfiguration record { - string|K8sService endpoint; - EndpointSecurity endpointSecurity?; - Certificate certificate?; - Resiliency resiliency?; -}; - +# Configuration for Backend JWT Policy. +# +# + parameters - The parameters for the backend JWT policy. public type BackendJWTPolicy record { *BaseOperationPolicy; BackendJWTPolicy_parameters parameters?; }; +# Configuration for Retry Policy. +# +# + count - The number of retry attempts. +# + baseIntervalMillis - The base interval between retries in milliseconds. +# + statusCodes - The status codes that trigger a retry. public type RetryPolicy record { int count?; int baseIntervalMillis?; int[] statusCodes?; }; +# Configuration for API Key Auth Type +# +# + sendTokenToUpstream - Enables sending the API Key to upstream. +# + headerName - Name of APIKey header. +# + queryParamName - Name of APIKey query parameter. +# + headerEnable - Enable sending API Key in header. +# + queryParamEnable - Enable sending API Key as a query param. public type APIKeyAuthentication record {| *Authentication; boolean sendTokenToUpstream = false; @@ -311,11 +493,19 @@ public type MTLSAuthentication record {| ConfigMapRef[] certificates; |}; +# Configuration for K8s Secret. +# +# + secretName - Name of Secret. +# + secretKey - Key containing the relevant value. public type Certificate record { string secretName?; string secretKey?; }; +# Configuration for K8s ConfigMap. +# +# + name - Name of ConfigMap. +# + key - Key containing the relevant value. public type ConfigMapRef record { string name; string key;