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

v2alpha1 CORS and Hosts #1157

Merged
merged 16 commits into from
Jul 15, 2024
32 changes: 32 additions & 0 deletions internal/builders/virtual_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package builders
import (
"fmt"
apirulev1beta1 "github.com/kyma-project/api-gateway/apis/gateway/v1beta1"
apirulev2alpha1 "github.com/kyma-project/api-gateway/apis/gateway/v2alpha1"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
"istio.io/api/networking/v1beta1"
Expand Down Expand Up @@ -257,6 +258,37 @@ func (cp *corsPolicy) AllowOrigins(val ...*v1beta1.StringMatch) *corsPolicy {
return cp
}

func (cp *corsPolicy) FromV2Alpha1ApiRuleCorsPolicy(corsPolicy apirulev2alpha1.CorsPolicy) *corsPolicy {
if len(corsPolicy.AllowOrigins) == 0 {
cp.value.AllowOrigins = nil
} else {
matchers := corsPolicy.AllowOrigins.ToIstioStringMatchArray()
cp.value.AllowOrigins = append(cp.value.AllowOrigins, matchers...)
}

if len(corsPolicy.AllowHeaders) > 0 {
cp.value.AllowHeaders = corsPolicy.AllowHeaders
}

if len(corsPolicy.AllowMethods) > 0 {
cp.value.AllowMethods = corsPolicy.AllowMethods
}

if len(corsPolicy.ExposeHeaders) > 0 {
cp.value.ExposeHeaders = corsPolicy.ExposeHeaders
}

if corsPolicy.AllowCredentials != nil {
cp.value.AllowCredentials = &wrapperspb.BoolValue{Value: *corsPolicy.AllowCredentials}
}

if corsPolicy.MaxAge != nil {
cp.value.MaxAge = durationpb.New(time.Duration(*corsPolicy.MaxAge) * time.Second)
}

return cp
}

func (cp *corsPolicy) FromApiRuleCorsPolicy(corsPolicy apirulev1beta1.CorsPolicy) *corsPolicy {
if len(corsPolicy.AllowOrigins) == 0 {
cp.value.AllowOrigins = nil
Expand Down
19 changes: 19 additions & 0 deletions internal/processing/processors/v2alpha1/reconciliation.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,22 @@ func NewReconciliation(apiRuleV2alpha1 *gatewayv2alpha1.APIRule, apiRuleV1beta1
config: config,
}
}

func filterDuplicatePaths(rules []gatewayv2alpha1.Rule) []gatewayv2alpha1.Rule {
uniqueRules := make(map[string]gatewayv2alpha1.Rule)
for _, rule := range rules {
uniqueRules[rule.Path] = rule
}
var uniqueRulesSlice []gatewayv2alpha1.Rule
for _, rule := range uniqueRules {
uniqueRulesSlice = append(uniqueRulesSlice, rule)
}
return uniqueRulesSlice
}

func findServiceNamespace(api *gatewayv2alpha1.APIRule, rule *gatewayv2alpha1.Rule) string {
barchw marked this conversation as resolved.
Show resolved Hide resolved
if rule.Service != nil && rule.Service.Namespace != nil {
return *rule.Service.Namespace
}
return api.Namespace
}
202 changes: 202 additions & 0 deletions internal/processing/processors/v2alpha1/test_builders_test.go
barchw marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package v2alpha1_test

import (
gatewayv2alpha1 "github.com/kyma-project/api-gateway/apis/gateway/v2alpha1"
"k8s.io/utils/ptr"
"net/http"
)

type ruleBuilder struct {
rule *gatewayv2alpha1.Rule
}

func (r *ruleBuilder) WithPath(path string) *ruleBuilder {
r.rule.Path = path
return r
}

func (r *ruleBuilder) WithTimeout(timeout uint32) *ruleBuilder {
r.rule.Timeout = ptr.To(gatewayv2alpha1.Timeout(timeout))
return r
}

func (r *ruleBuilder) WithService(name, namespace string, port uint32) *ruleBuilder {
r.rule.Service = &gatewayv2alpha1.Service{
Name: &name,
Namespace: &namespace,
Port: &port,
}
return r
}

func (r *ruleBuilder) WithMethods(methods ...gatewayv2alpha1.HttpMethod) *ruleBuilder {
r.rule.Methods = methods
return r
}

func (r *ruleBuilder) NoAuth() *ruleBuilder {
r.rule.NoAuth = ptr.To(true)
return r
}

func (r *ruleBuilder) WithJWTAuthn(issuer, jwksUri string, fromHeaders []*gatewayv2alpha1.JwtHeader, fromParams []string) *ruleBuilder {
if r.rule.Jwt == nil {
r.rule.Jwt = &gatewayv2alpha1.JwtConfig{}
}
r.rule.Jwt.Authentications = append(r.rule.Jwt.Authentications, &gatewayv2alpha1.JwtAuthentication{
Issuer: issuer,
JwksUri: jwksUri,
FromHeaders: fromHeaders,
FromParams: fromParams,
})

return r
}

func (r *ruleBuilder) WithJWTAuthz(requiredScopes []string, audiences []string) *ruleBuilder {
if r.rule.Jwt == nil {
r.rule.Jwt = &gatewayv2alpha1.JwtConfig{}
}

r.rule.Jwt.Authorizations = append(r.rule.Jwt.Authorizations, &gatewayv2alpha1.JwtAuthorization{
RequiredScopes: requiredScopes,
Audiences: audiences,
})

return r
}

func newRuleBuilder() *ruleBuilder {
return &ruleBuilder{
rule: &gatewayv2alpha1.Rule{},
}
}

func (r *ruleBuilder) Build() *gatewayv2alpha1.Rule {
return r.rule
}

type apiRuleBuilder struct {
apiRule *gatewayv2alpha1.APIRule
}

func (a *apiRuleBuilder) WithHost(host string) *apiRuleBuilder {
a.apiRule.Spec.Hosts = append(a.apiRule.Spec.Hosts, ptr.To(gatewayv2alpha1.Host(host)))
return a
}

func (a *apiRuleBuilder) WithHosts(hosts ...string) *apiRuleBuilder {
for _, host := range hosts {
a.WithHost(host)
}
return a
}

func (a *apiRuleBuilder) WithService(name, namespace string, port uint32) *apiRuleBuilder {
a.apiRule.Spec.Service = &gatewayv2alpha1.Service{
Name: &name,
Namespace: &namespace,
Port: &port,
}
return a
}

func (a *apiRuleBuilder) WithGateway(gateway string) *apiRuleBuilder {
a.apiRule.Spec.Gateway = ptr.To(gateway)
return a
}

func (a *apiRuleBuilder) WithCORSPolicy(policy gatewayv2alpha1.CorsPolicy) *apiRuleBuilder {
a.apiRule.Spec.CorsPolicy = &policy
return a
}

func (a *apiRuleBuilder) WithTimeout(timeout uint32) *apiRuleBuilder {
a.apiRule.Spec.Timeout = ptr.To(gatewayv2alpha1.Timeout(timeout))
return a
}

func (a *apiRuleBuilder) WithRule(rule gatewayv2alpha1.Rule) *apiRuleBuilder {
a.apiRule.Spec.Rules = append(a.apiRule.Spec.Rules, rule)
return a
}

func (a *apiRuleBuilder) WithRules(rules ...*gatewayv2alpha1.Rule) *apiRuleBuilder {
for _, rule := range rules {
a.WithRule(*rule)
}
return a
}

func (a *apiRuleBuilder) Build() *gatewayv2alpha1.APIRule {
return a.apiRule
}

func newAPIRuleBuilder() *apiRuleBuilder {
return &apiRuleBuilder{
apiRule: &gatewayv2alpha1.APIRule{},
}
}

// newAPIRuleBuilderWithDummyData returns an APIRuleBuilder pre-filled with placeholder data:
//
// Host: example-host.example.com
//
// Gateway: example-namespace/example-gateway
//
// Service: example-namespace/example-service:8080
//
// Rule: GET /
//
// Strategy: NoAuth
func newAPIRuleBuilderWithDummyData() *apiRuleBuilder {
return newAPIRuleBuilder().
WithHost("example-host.example.com").
WithGateway("example-namespace/example-gateway").
WithService("example-service", "example-namespace", 8080).
WithRule(*newRuleBuilder().WithMethods(http.MethodGet).WithPath("/").NoAuth().Build())
}

type corsPolicyBuilder struct {
policy gatewayv2alpha1.CorsPolicy
}

func (c *corsPolicyBuilder) WithAllowOrigins(origins []map[string]string) *corsPolicyBuilder {
c.policy.AllowOrigins = origins
return c
}

func (c *corsPolicyBuilder) WithAllowMethods(methods []string) *corsPolicyBuilder {
c.policy.AllowMethods = methods
return c
}

func (c *corsPolicyBuilder) WithAllowHeaders(headers []string) *corsPolicyBuilder {
c.policy.AllowHeaders = headers
return c
}

func (c *corsPolicyBuilder) WithExposeHeaders(headers []string) *corsPolicyBuilder {
c.policy.ExposeHeaders = headers
return c
}

func (c *corsPolicyBuilder) WithMaxAge(maxAge uint64) *corsPolicyBuilder {
c.policy.MaxAge = &maxAge
return c
}

func (c *corsPolicyBuilder) WithAllowCredentials(allow bool) *corsPolicyBuilder {
c.policy.AllowCredentials = &allow
return c
}

func newCorsPolicyBuilder() *corsPolicyBuilder {
return &corsPolicyBuilder{
policy: gatewayv2alpha1.CorsPolicy{},
}
}

func (c *corsPolicyBuilder) Build() gatewayv2alpha1.CorsPolicy {
return c.policy
}
Loading
Loading