Skip to content

Commit

Permalink
Merge pull request #78 from Kuadrant/openapi-kuadrant-extensions-at-root
Browse files Browse the repository at this point in the history
[BREAKING CHANGE] root level kuadrant extensions
  • Loading branch information
eguzki authored Jun 4, 2024
2 parents 3788cb7 + 58539d6 commit 50dc3c4
Show file tree
Hide file tree
Showing 14 changed files with 552 additions and 121 deletions.
141 changes: 141 additions & 0 deletions cmd/generate_gatewayapi_httproute_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package cmd

import (
"bytes"
"io"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
"sigs.k8s.io/yaml"
)

var _ = Describe("Generate HTTPRoute", func() {
var (
cmd *cobra.Command
cmdStdoutBuffer *bytes.Buffer
cmdStderrBuffer *bytes.Buffer
)

BeforeEach(func() {
cmd = generateGatewayApiHttpRouteCommand()
cmdStdoutBuffer = bytes.NewBufferString("")
cmdStderrBuffer = bytes.NewBufferString("")
cmd.SetOut(cmdStdoutBuffer)
cmd.SetErr(cmdStderrBuffer)
})

Context("with invalid OAS", func() {
It("happy path", func() {
cmd.SetArgs([]string{"--oas", "testdata/invalid_oas.yaml"})
Expect(cmd.Execute()).Should(MatchError(ContainSubstring("OpenAPI validation error")))

})
})

Context("with root level kuadrant extensions", func() {
It("HTTPRoute is generated", func() {
cmd.SetArgs([]string{"--oas", "testdata/petstore_openapi.yaml"})
Expect(cmd.Execute()).ShouldNot(HaveOccurred())
out, err := io.ReadAll(cmdStdoutBuffer)
Expect(err).ShouldNot(HaveOccurred())

var httpRoute gatewayapiv1.HTTPRoute
Expect(yaml.Unmarshal(out, &httpRoute)).ShouldNot(HaveOccurred())
Expect(httpRoute.TypeMeta).To(Equal(metav1.TypeMeta{
APIVersion: gatewayapiv1.GroupVersion.String(),
Kind: "HTTPRoute",
}))
Expect(httpRoute.ObjectMeta).To(Equal(metav1.ObjectMeta{
Name: "petstore",
Namespace: "petstore-ns",
}))
Expect(httpRoute.Spec.CommonRouteSpec).To(Equal(gatewayapiv1.CommonRouteSpec{
ParentRefs: []gatewayapiv1.ParentReference{
{
Name: "gw", Namespace: ptr.To(gatewayapiv1.Namespace("gw-ns")),
},
},
}))
Expect(httpRoute.Spec.Hostnames).To(Equal([]gatewayapiv1.Hostname{
gatewayapiv1.Hostname("example.com"),
}))
Expect(httpRoute.Spec.Rules).To(HaveLen(3))
Expect(httpRoute.Spec.Rules).To(ContainElement(
gatewayapiv1.HTTPRouteRule{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/cat"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodGet),
},
},
BackendRefs: []gatewayapiv1.HTTPBackendRef{
{
BackendRef: gatewayapiv1.BackendRef{
BackendObjectReference: gatewayapiv1.BackendObjectReference{
Name: "petstore",
Namespace: ptr.To(gatewayapiv1.Namespace("petstore")),
Port: ptr.To(gatewayapiv1.PortNumber(80)),
},
},
},
},
},
))
Expect(httpRoute.Spec.Rules).To(ContainElement(
gatewayapiv1.HTTPRouteRule{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/dog"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodGet),
},
},
BackendRefs: []gatewayapiv1.HTTPBackendRef{
{
BackendRef: gatewayapiv1.BackendRef{
BackendObjectReference: gatewayapiv1.BackendObjectReference{
Name: "petstore",
Namespace: ptr.To(gatewayapiv1.Namespace("petstore")),
Port: ptr.To(gatewayapiv1.PortNumber(80)),
},
},
},
},
},
))
Expect(httpRoute.Spec.Rules).To(ContainElement(
gatewayapiv1.HTTPRouteRule{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/dog"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodPost),
},
},
BackendRefs: []gatewayapiv1.HTTPBackendRef{
{
BackendRef: gatewayapiv1.BackendRef{
BackendObjectReference: gatewayapiv1.BackendObjectReference{
Name: "petstore",
Namespace: ptr.To(gatewayapiv1.Namespace("petstore")),
Port: ptr.To(gatewayapiv1.PortNumber(80)),
},
},
},
},
},
))
})
})
})
111 changes: 111 additions & 0 deletions cmd/generate_kuadrant_authpolicy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package cmd

import (
"bytes"
"io"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/yaml"

authorinoapi "github.com/kuadrant/authorino/api/v1beta2"
kuadrantapiv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2"
)

var _ = Describe("Generate AuthPolicy", func() {
var (
cmd *cobra.Command
cmdStdoutBuffer *bytes.Buffer
cmdStderrBuffer *bytes.Buffer
)

BeforeEach(func() {
cmd = generateKuadrantAuthPolicyCommand()
cmdStdoutBuffer = bytes.NewBufferString("")
cmdStderrBuffer = bytes.NewBufferString("")
cmd.SetOut(cmdStdoutBuffer)
cmd.SetErr(cmdStderrBuffer)
})

Context("with invalid OAS", func() {
It("happy path", func() {
cmd.SetArgs([]string{"--oas", "testdata/invalid_oas.yaml"})
Expect(cmd.Execute()).Should(MatchError(ContainSubstring("OpenAPI validation error")))

})
})

Context("with operation including security", func() {
It("authorization policy generated", func() {
cmd.SetArgs([]string{"--oas", "testdata/petstore_openapi.yaml"})
Expect(cmd.Execute()).ShouldNot(HaveOccurred())
out, err := io.ReadAll(cmdStdoutBuffer)
Expect(err).ShouldNot(HaveOccurred())

var kap kuadrantapiv1beta2.AuthPolicy
Expect(yaml.Unmarshal(out, &kap)).ShouldNot(HaveOccurred())
Expect(kap.TypeMeta).To(Equal(metav1.TypeMeta{
APIVersion: kuadrantapiv1beta2.GroupVersion.String(), Kind: "AuthPolicy",
}))
Expect(kap.ObjectMeta).To(Equal(metav1.ObjectMeta{
Name: "petstore",
Namespace: "petstore-ns",
}))
Expect(kap.Spec.TargetRef).To(Equal(gatewayapiv1alpha2.PolicyTargetReference{
Group: gatewayapiv1.GroupName,
Kind: gatewayapiv1.Kind("HTTPRoute"),
Name: gatewayapiv1.ObjectName("petstore"),
Namespace: ptr.To(gatewayapiv1.Namespace("petstore-ns")),
}))
Expect(kap.Spec.AuthPolicyCommonSpec.RouteSelectors).To(HaveExactElements(
kuadrantapiv1beta2.RouteSelector{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/dog"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodPost),
},
},
},
))
Expect(kap.Spec.AuthPolicyCommonSpec.AuthScheme).To(Equal(
&kuadrantapiv1beta2.AuthSchemeSpec{
Authentication: map[string]kuadrantapiv1beta2.AuthenticationSpec{
"postDog_securedDog": kuadrantapiv1beta2.AuthenticationSpec{
AuthenticationSpec: authorinoapi.AuthenticationSpec{
Credentials: authorinoapi.Credentials{},
AuthenticationMethodSpec: authorinoapi.AuthenticationMethodSpec{
Jwt: &authorinoapi.JwtAuthenticationSpec{
IssuerUrl: "https://example.com/.well-known/openid-configuration",
},
},
},
CommonAuthRuleSpec: kuadrantapiv1beta2.CommonAuthRuleSpec{
RouteSelectors: []kuadrantapiv1beta2.RouteSelector{
{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/dog"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodPost),
},
},
},
},
},
},
},
},
))
})
})
})
117 changes: 117 additions & 0 deletions cmd/generate_kuadrant_ratelimitpolicy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package cmd

import (
"bytes"
"io"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/yaml"

kuadrantapiv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2"
)

var _ = Describe("Generate Ratelimitpolicy", func() {
var (
cmd *cobra.Command
cmdStdoutBuffer *bytes.Buffer
cmdStderrBuffer *bytes.Buffer
)

BeforeEach(func() {
cmd = generateKuadrantRateLimitPolicyCommand()
cmdStdoutBuffer = bytes.NewBufferString("")
cmdStderrBuffer = bytes.NewBufferString("")
cmd.SetOut(cmdStdoutBuffer)
cmd.SetErr(cmdStderrBuffer)
})

Context("with invalid OAS", func() {
It("happy path", func() {
cmd.SetArgs([]string{"--oas", "testdata/invalid_oas.yaml"})
Expect(cmd.Execute()).Should(MatchError(ContainSubstring("OpenAPI validation error")))

})
})

Context("with rate limiting kuadrant extensions", func() {
It("rate limit policy generated", func() {
cmd.SetArgs([]string{"--oas", "testdata/petstore_openapi.yaml"})
Expect(cmd.Execute()).ShouldNot(HaveOccurred())
out, err := io.ReadAll(cmdStdoutBuffer)
Expect(err).ShouldNot(HaveOccurred())

var rlp kuadrantapiv1beta2.RateLimitPolicy
Expect(yaml.Unmarshal(out, &rlp)).ShouldNot(HaveOccurred())
Expect(rlp.TypeMeta).To(Equal(metav1.TypeMeta{
APIVersion: kuadrantapiv1beta2.GroupVersion.String(), Kind: "RateLimitPolicy",
}))
Expect(rlp.ObjectMeta).To(Equal(metav1.ObjectMeta{
Name: "petstore",
Namespace: "petstore-ns",
}))
Expect(rlp.Spec.TargetRef).To(Equal(gatewayapiv1alpha2.PolicyTargetReference{
Group: gatewayapiv1.GroupName,
Kind: gatewayapiv1.Kind("HTTPRoute"),
Name: gatewayapiv1.ObjectName("petstore"),
Namespace: ptr.To(gatewayapiv1.Namespace("petstore-ns")),
}))
Expect(rlp.Spec.RateLimitPolicyCommonSpec.Limits).To(HaveLen(2))
Expect(rlp.Spec.RateLimitPolicyCommonSpec.Limits).To(HaveKeyWithValue("getCat", kuadrantapiv1beta2.Limit{
Counters: []kuadrantapiv1beta2.ContextSelector{
"request.headers.x-forwarded-for",
},
RouteSelectors: []kuadrantapiv1beta2.RouteSelector{
{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/cat"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodGet),
},
},
},
},
Rates: []kuadrantapiv1beta2.Rate{
{
Limit: 1,
Duration: 10,
Unit: kuadrantapiv1beta2.TimeUnit("second"),
},
},
}))
Expect(rlp.Spec.RateLimitPolicyCommonSpec.Limits).To(HaveKeyWithValue("getDog", kuadrantapiv1beta2.Limit{
Counters: []kuadrantapiv1beta2.ContextSelector{
"request.headers.x-forwarded-for",
},
RouteSelectors: []kuadrantapiv1beta2.RouteSelector{
{
Matches: []gatewayapiv1.HTTPRouteMatch{
{
Path: &gatewayapiv1.HTTPPathMatch{
Type: ptr.To(gatewayapiv1.PathMatchExact),
Value: ptr.To("/v1/dog"),
},
Method: ptr.To(gatewayapiv1.HTTPMethodGet),
},
},
},
},
Rates: []kuadrantapiv1beta2.Rate{
{
Limit: 3,
Duration: 10,
Unit: kuadrantapiv1beta2.TimeUnit("second"),
},
},
}))
})
})
})
Loading

0 comments on commit 50dc3c4

Please sign in to comment.