Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding multi environment support for APK #1770

Merged
merged 24 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
849498f
Resolving changes with the main branch
pubudu538 Sep 25, 2023
d085009
Adding the changed API crd
pubudu538 Aug 28, 2023
a7e3ba0
Passing environment field from Adapter to Enforcer
pubudu538 Aug 29, 2023
52d92ad
Adding environment ID for Choreo Analytics
pubudu538 Aug 31, 2023
723ef7a
Changing vhost to environment for rate limiting in the common controller
pubudu538 Sep 1, 2023
f41db36
Updating Router configs for rate limiting
pubudu538 Sep 1, 2023
0a5c537
Removing Environment data model
pubudu538 Sep 12, 2023
75de949
Adding environment field to APK Conf
pubudu538 Sep 15, 2023
1baf50a
Fixing compiler hints on Ballerina
pubudu538 Sep 15, 2023
44f68f6
Adding integration tests for multi environment feature
pubudu538 Sep 19, 2023
6693597
Changing to new schemas
pubudu538 Sep 26, 2023
8aab912
Fixing multi-env test cases
pubudu538 Sep 27, 2023
e45256a
Adding missing vhosts
pubudu538 Sep 27, 2023
cac99a0
Adding environment field for TokenIssuer
pubudu538 Oct 3, 2023
2763091
Adding test cases for token issuer with environments
pubudu538 Oct 5, 2023
4052297
Adding environment field to the helm chart
pubudu538 Oct 6, 2023
5e8a896
Moving environment as an object in the helm chart
pubudu538 Oct 13, 2023
fe82a1c
Adding resource level rate limit support for sandbox routes
pubudu538 Oct 17, 2023
a626420
Passing environment field to the interceptors
pubudu538 Oct 18, 2023
6f0c652
Adding v1alpha2 version for API Kind
pubudu538 Oct 21, 2023
f959e8a
Updating integration tests for multi-envs
pubudu538 Oct 21, 2023
8aa2784
Fixing build failures
pubudu538 Oct 21, 2023
bba085a
Fixing revive failure
pubudu538 Oct 21, 2023
c3b9896
Adding TokenIssuer v1alpha2 version
pubudu538 Oct 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading