Skip to content

Commit

Permalink
Merge pull request #1770 from pubudu538/apk-envs
Browse files Browse the repository at this point in the history
Adding multi environment support for APK
  • Loading branch information
Krishanx92 committed Oct 23, 2023
2 parents dfd7de7 + c3b9896 commit 1c472b0
Show file tree
Hide file tree
Showing 157 changed files with 5,277 additions and 1,003 deletions.
1 change: 1 addition & 0 deletions adapter/api/proto/wso2/discovery/api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ message Api {
bool systemAPI = 24;
BackendJWTTokenInfo backendJWTTokenInfo = 25;
bytes apiDefinitionFile = 26;
string environment = 27;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ message JWTIssuer {
string consumerKeyClaim = 6;
string scopesClaim = 7;
map<string, string> claimMapping = 8;
repeated string environments = 9;
}
message Certificate {
string certificate = 1;
Expand Down
1 change: 1 addition & 0 deletions adapter/config/default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var defaultConfig = &Config{
Operator: operator{
Namespaces: nil,
},
Environment: "Default",
},
Envoy: envoy{
ListenerCodecType: "AUTO",
Expand Down
2 changes: 2 additions & 0 deletions adapter/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ type adapter struct {
SoapErrorInXMLEnabled bool
// Operator represents the operator related configurations
Operator operator
// Environment of the Adapter
Environment string
}

// Envoy Listener Component related configurations.
Expand Down
2 changes: 2 additions & 0 deletions adapter/internal/interceptor/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type InvocationContext struct {
Vhost string
ClusterName string
APIProperties string
Environment string
}

var (
Expand All @@ -89,6 +90,7 @@ var (
organizationId = "{{.Context.OrganizationID}}",
basePath = "{{.Context.BasePath}}",
supportedMethods = "{{.Context.SupportedMethods}}",
environment = "{{.Context.Environment}}",
apiName = "{{.Context.APIName}}",
apiVersion = "{{.Context.APIVersion}}",
pathTemplate = "{{.Context.PathTemplate}}",
Expand Down
1 change: 1 addition & 0 deletions adapter/internal/oasparser/config_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func GetEnforcerAPI(adapterInternalAPI model.AdapterInternalAPI, vhost string) *
// GraphqlComplexityInfo: adapterInternalAPI.GraphQLComplexities.Data.List,
SystemAPI: adapterInternalAPI.IsSystemAPI,
ApiDefinitionFile: adapterInternalAPI.GetAPIDefinitionFile(),
Environment: adapterInternalAPI.GetEnvironment(),
}
}

Expand Down
9 changes: 6 additions & 3 deletions adapter/internal/oasparser/envoyconf/internal_dtos.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package envoyconf

import (
"github.com/wso2/apk/adapter/internal/oasparser/model"
dpv1alpha1 "github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha1"
dpv1alpha2 "github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha2"
)

// routeCreateParams is the DTO used to provide information to the envoy route create function
Expand All @@ -42,13 +42,16 @@ type routeCreateParams struct {
isDefaultVersion bool
createDefaultPath bool
apiLevelRateLimitPolicy *model.RateLimitPolicy
apiProperties []dpv1alpha1.Property
apiProperties []dpv1alpha2.Property
environment string
envType string
}

// RatelimitCriteria criterias of rate limiting
type ratelimitCriteria struct {
level string
organizationID string
vHost string
basePathForRLService string
environment string
envType string
}
10 changes: 8 additions & 2 deletions adapter/internal/oasparser/envoyconf/routes_configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
logger "github.com/wso2/apk/adapter/internal/loggers"
"github.com/wso2/apk/adapter/internal/oasparser/constants"
"github.com/wso2/apk/adapter/internal/oasparser/model"
opConstants "github.com/wso2/apk/adapter/internal/operator/constants"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
Expand Down Expand Up @@ -112,6 +113,11 @@ func generateRouteAction(apiType string, routeConfig *model.EndpointConfig, rate

func generateRateLimitPolicy(ratelimitCriteria *ratelimitCriteria) []*routev3.RateLimit {

environmentValue := ratelimitCriteria.environment
if ratelimitCriteria.level != RateLimitPolicyAPILevel && ratelimitCriteria.envType == opConstants.Sandbox {
environmentValue += "_sandbox"
}

rateLimit := routev3.RateLimit{
Actions: []*routev3.RateLimit_Action{
{
Expand All @@ -125,8 +131,8 @@ func generateRateLimitPolicy(ratelimitCriteria *ratelimitCriteria) []*routev3.Ra
{
ActionSpecifier: &routev3.RateLimit_Action_GenericKey_{
GenericKey: &routev3.RateLimit_Action_GenericKey{
DescriptorKey: DescriptorKeyForVhost,
DescriptorValue: ratelimitCriteria.vHost,
DescriptorKey: DescriptorKeyForEnvironment,
DescriptorValue: environmentValue,
},
},
},
Expand Down
12 changes: 8 additions & 4 deletions adapter/internal/oasparser/envoyconf/routes_with_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ import (
logging "github.com/wso2/apk/adapter/internal/logging"
"github.com/wso2/apk/adapter/internal/oasparser/constants"
"github.com/wso2/apk/adapter/internal/oasparser/model"
dpv1alpha2 "github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha2"
"github.com/wso2/apk/adapter/internal/svcdiscovery"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/any"
"github.com/golang/protobuf/ptypes/wrappers"
dpv1alpha1 "github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha1"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
)

Expand All @@ -77,7 +77,7 @@ type CombinedTemplateValues struct {
const (
DescriptorKeyForOrg = "org"
OrgMetadataKey = "customorg"
DescriptorKeyForVhost = "vhost"
DescriptorKeyForEnvironment = "environment"
DescriptorKeyForPath = "path"
DescriptorKeyForMethod = "method"
DescriptorValueForAPIMethod = "ALL"
Expand Down Expand Up @@ -766,6 +766,7 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error
Vhost: contextExtensions[vHostContextExtension],
ClusterName: contextExtensions[clusterNameContextExtension],
APIProperties: getAPIProperties(params.apiProperties),
Environment: params.environment,
}
luaPerFilterConfig = lua.LuaPerRoute{
Override: &lua.LuaPerRoute_SourceCode{
Expand Down Expand Up @@ -816,8 +817,9 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error
rateLimitPolicyCriteria = &ratelimitCriteria{
level: rateLimitPolicyLevel,
organizationID: params.organizationID,
vHost: vHost,
basePathForRLService: basePathForRLService,
environment: params.environment,
envType: params.envType,
}
}
var (
Expand Down Expand Up @@ -1447,7 +1449,7 @@ func getUpgradeConfig(apiType string) []*routev3.RouteAction_UpgradeConfig {
return upgradeConfig
}

func getAPIProperties(apiPropertiesConfig []dpv1alpha1.Property) string {
func getAPIProperties(apiPropertiesConfig []dpv1alpha2.Property) string {
var apiProperties = make(map[string]string)
for _, val := range apiPropertiesConfig {
apiProperties[val.Name] = val.Value
Expand Down Expand Up @@ -1528,6 +1530,8 @@ func genRouteCreateParams(swagger *model.AdapterInternalAPI, resource *model.Res
apiProperties: swagger.APIProperties,
routeConfig: resource.GetEndpoints().Config,
createDefaultPath: createDefaultPath,
environment: swagger.GetEnvironment(),
envType: swagger.EnvType,
}
return params
}
Expand Down
147 changes: 117 additions & 30 deletions adapter/internal/oasparser/envoyconf/routes_with_clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

envoy "github.com/wso2/apk/adapter/internal/oasparser/envoyconf"
"github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha1"
"github.com/wso2/apk/adapter/internal/operator/apis/dp/v1alpha2"
"github.com/wso2/apk/adapter/internal/operator/constants"
"github.com/wso2/apk/adapter/internal/operator/synchronizer"
operatorutils "github.com/wso2/apk/adapter/internal/operator/utils"
Expand All @@ -34,16 +35,16 @@ import (

func TestCreateRoutesWithClustersWithExactAndRegularExpressionRules(t *testing.T) {
apiState := synchronizer.APIState{}
apiDefinition := v1alpha1.API{
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "test-api-2",
},
Spec: v1alpha1.APISpec{
APIName: "test-api-2",
APIVersion: "2.0.0",
BasePath: "/test-api/2.0.0",
Production: []v1alpha1.EnvConfig{
Spec: v1alpha2.APISpec{
APIName: "test-api-2",
APIVersion: "2.0.0",
BasePath: "/test-api/2.0.0",
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
"test-api-2-prod-http-route",
Expand Down Expand Up @@ -156,19 +157,105 @@ func TestCreateRoutesWithClustersWithExactAndRegularExpressionRules(t *testing.T
"The route regex for the two paths should not be the same")
}

func TestGenerateAdapterInternalAPIForDefaultCase(t *testing.T) {

apiState := generateSampleAPI("test-api-1", "1.0.0", "/test-api/1.0.0")
httpRouteState := synchronizer.HTTPRouteState{}
httpRouteState = *apiState.ProdHTTPRoute

adapterInternalAPI, err := synchronizer.GenerateAdapterInternalAPI(apiState, &httpRouteState, constants.Production)
assert.Nil(t, err, "Error should not be present when apiState is converted to a AdapterInternalAPI object")
assert.Equal(t, "Default", adapterInternalAPI.GetEnvironment(), "Environment is incorrect.")
}

func TestGenerateAdapterInternalAPIForSpecificEnvironment(t *testing.T) {

apiState := generateSampleAPI("test-api-2", "1.0.0", "/test-api2/1.0.0")
httpRouteState := synchronizer.HTTPRouteState{}
httpRouteState = *apiState.ProdHTTPRoute
apiState.APIDefinition.Spec.Environment = "dev"

adapterInternalAPI, err := synchronizer.GenerateAdapterInternalAPI(apiState, &httpRouteState, constants.Production)
assert.Nil(t, err, "Error should not be present when apiState is converted to a AdapterInternalAPI object")
assert.Equal(t, "dev", adapterInternalAPI.GetEnvironment(), "Environment is incorrect.")
}

func generateSampleAPI(apiName string, apiVersion string, basePath string) synchronizer.APIState {

apiState := synchronizer.APIState{}
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: apiName,
},
Spec: v1alpha2.APISpec{
APIName: apiName,
APIVersion: apiVersion,
BasePath: basePath,
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
apiName + "-prod-http-route",
},
},
},
},
}
apiState.APIDefinition = &apiDefinition
httpRouteState := synchronizer.HTTPRouteState{}
methodTypeGet := gwapiv1b1.HTTPMethodGet

httpRoute := gwapiv1b1.HTTPRoute{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: apiName + "-prod-http-route",
},
Spec: gwapiv1b1.HTTPRouteSpec{
Hostnames: []gwapiv1b1.Hostname{"prod.gw.wso2.com"},
CommonRouteSpec: createDefaultCommonRouteSpec(),
Rules: []gwapiv1b1.HTTPRouteRule{
{
Matches: []gwapiv1b1.HTTPRouteMatch{
{
Path: &gwapiv1b1.HTTPPathMatch{
Type: operatorutils.PathMatchTypePtr(gwapiv1b1.PathMatchExact),
Value: operatorutils.StringPtr("/exact-path-api/2.0.0/(.*)/exact-path"),
},
Method: &methodTypeGet,
},
},
BackendRefs: []gwapiv1b1.HTTPBackendRef{
createDefaultBackendRef(apiName + "backend-1"),
},
},
},
},
}

httpRouteState.HTTPRouteCombined = &httpRoute

backendMapping := make(map[string]*v1alpha1.ResolvedBackend)
backendMapping[k8types.NamespacedName{Namespace: "default", Name: apiName + "backend-1"}.String()] =
&v1alpha1.ResolvedBackend{Services: []v1alpha1.Service{{Host: "test-service-1.default", Port: 7001}}, Protocol: v1alpha1.HTTPProtocol}
httpRouteState.BackendMapping = backendMapping

apiState.ProdHTTPRoute = &httpRouteState
return apiState
}

// TODO: Fix this test case
func TestCreateRoutesWithClustersWithMultiplePathPrefixRules(t *testing.T) {
apiState := synchronizer.APIState{}
apiDefinition := v1alpha1.API{
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "test-api-1",
},
Spec: v1alpha1.APISpec{
APIName: "test-api",
APIVersion: "1.0.0",
BasePath: "/test-api/1.0.0",
Production: []v1alpha1.EnvConfig{
Spec: v1alpha2.APISpec{
APIName: "test-api",
APIVersion: "1.0.0",
BasePath: "/test-api/1.0.0",
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
"test-api-1-prod-http-route",
Expand Down Expand Up @@ -306,16 +393,16 @@ func TestCreateRoutesWithClustersWithMultiplePathPrefixRules(t *testing.T) {

func TestCreateRoutesWithClustersWithBackendTLSConfigs(t *testing.T) {
apiState := synchronizer.APIState{}
apiDefinition := v1alpha1.API{
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "test-api-3",
},
Spec: v1alpha1.APISpec{
APIName: "test-api-3",
APIVersion: "1.0.0",
BasePath: "/test-api-3/1.0.0",
Production: []v1alpha1.EnvConfig{
Spec: v1alpha2.APISpec{
APIName: "test-api-3",
APIVersion: "1.0.0",
BasePath: "/test-api-3/1.0.0",
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
"test-api-3-prod-http-route",
Expand Down Expand Up @@ -612,16 +699,16 @@ func TestCreateHealthEndpoint(t *testing.T) {

func TestCreateRoutesWithClustersDifferentBackendRefs(t *testing.T) {
apiState := synchronizer.APIState{}
apiDefinition := v1alpha1.API{
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "test-api-different-backendrefs",
},
Spec: v1alpha1.APISpec{
APIName: "test-api-different-backendrefs",
APIVersion: "1.0.0",
BasePath: "/test-api-different-backendrefs/1.0.0",
Production: []v1alpha1.EnvConfig{
Spec: v1alpha2.APISpec{
APIName: "test-api-different-backendrefs",
APIVersion: "1.0.0",
BasePath: "/test-api-different-backendrefs/1.0.0",
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
"test-api-different-backendrefs-prod-http-route",
Expand Down Expand Up @@ -702,16 +789,16 @@ func TestCreateRoutesWithClustersDifferentBackendRefs(t *testing.T) {

func TestCreateRoutesWithClustersSameBackendRefs(t *testing.T) {
apiState := synchronizer.APIState{}
apiDefinition := v1alpha1.API{
apiDefinition := v1alpha2.API{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "test-api-same-backendrefs",
},
Spec: v1alpha1.APISpec{
APIName: "test-api-same-backendrefs",
APIVersion: "1.0.0",
BasePath: "/test-api-same-backendrefs/1.0.0",
Production: []v1alpha1.EnvConfig{
Spec: v1alpha2.APISpec{
APIName: "test-api-same-backendrefs",
APIVersion: "1.0.0",
BasePath: "/test-api-same-backendrefs/1.0.0",
Production: []v1alpha2.EnvConfig{
{
HTTPRouteRefs: []string{
"test-api-same-backendrefs-prod-http-route",
Expand Down
Loading

0 comments on commit 1c472b0

Please sign in to comment.