Skip to content

Commit

Permalink
Add e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
creydr committed Aug 27, 2024
1 parent d3081f0 commit 3a79845
Show file tree
Hide file tree
Showing 7 changed files with 528 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,5 @@ metadata:
knative.dev/config-propagation: original
knative.dev/config-category: eventing
data:
kreference-group: "disabled"
delivery-retryafter: "disabled"
delivery-timeout: "enabled"
kreference-mapping: "disabled"
new-trigger-filters: "enabled"
transport-encryption: "strict"
eventtype-auto-create: "disabled"
authentication-oidc: "enabled"
20 changes: 20 additions & 0 deletions test/e2e_new/broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"knative.dev/eventing-kafka-broker/control-plane/pkg/kafka"
"knative.dev/eventing-kafka-broker/test/e2e_new/single_partition_config"
"knative.dev/eventing-kafka-broker/test/rekt/features"
"knative.dev/eventing/test/rekt/features/authz"
"knative.dev/eventing/test/rekt/features/broker"
brokereventingfeatures "knative.dev/eventing/test/rekt/features/broker"
"knative.dev/eventing/test/rekt/features/oidc"
Expand Down Expand Up @@ -323,6 +324,25 @@ func TestBrokerSendsEventsWithOIDCSupport(t *testing.T) {
env.TestSet(ctx, t, brokereventingfeatures.BrokerSendEventWithOIDC())
}

func TestBrokerSupportsAuthZ(t *testing.T) {
t.Parallel()

ctx, env := global.Environment(
knative.WithKnativeNamespace(system.Namespace()),
knative.WithLoggingConfig,
knative.WithTracingConfig,
k8s.WithEventListener,
environment.WithPollTimings(4*time.Second, 12*time.Minute),
environment.Managed(t),
eventshub.WithTLS(t),
)

name := feature.MakeRandomK8sName("broker")
env.Prerequisite(ctx, t, broker.GoesReady(name, brokerresources.WithEnvConfig()...))

env.TestSet(ctx, t, authz.AddressableAuthZConformance(brokerresources.GVR(), "Broker", name))
}

func TestBrokerDispatcherKedaScaling(t *testing.T) {
t.Parallel()

Expand Down
6 changes: 3 additions & 3 deletions test/reconciler-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ kubectl apply -Rf "$(dirname "$0")/config-transport-encryption"

go_test_e2e -timeout=1h ./test/e2e_new -run TLS || fail_test

echo "Running E2E Reconciler Tests with OIDC authentication enabled"
echo "Running E2E Reconciler OIDC and AuthZ Tests"

kubectl apply -Rf "$(dirname "$0")/config-oidc-authentication"
kubectl apply -Rf "$(dirname "$0")/config-auth"

go_test_e2e -timeout=1h ./test/e2e_new -run OIDC || fail_test
go_test_e2e -timeout=1h ./test/e2e_new -run "OIDC|AuthZ" || fail_test

if ! ${LOCAL_DEVELOPMENT}; then
go_test_e2e -tags=sacura -timeout=40m ./test/e2e/... || fail_test "E2E (sacura) suite failed"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/*
Copyright 2024 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package authz

import (
"context"
"fmt"
"time"

eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1"
"knative.dev/eventing/test/rekt/resources/eventpolicy"
"knative.dev/eventing/test/rekt/resources/pingsource"
"knative.dev/reconciler-test/pkg/environment"

"knative.dev/eventing/test/rekt/features/featureflags"

"github.com/cloudevents/sdk-go/v2/test"
"k8s.io/apimachinery/pkg/runtime/schema"
"knative.dev/reconciler-test/pkg/eventshub"
eventassert "knative.dev/reconciler-test/pkg/eventshub/assert"
"knative.dev/reconciler-test/pkg/feature"
"knative.dev/reconciler-test/pkg/k8s"
)

// AddressableAuthZConformance returns a feature set to test all Authorization features for an addressable.
func AddressableAuthZConformance(gvr schema.GroupVersionResource, kind, name string) *feature.FeatureSet {
fs := feature.FeatureSet{
Name: fmt.Sprintf("%s handles authorization features correctly", kind),
Features: []*feature.Feature{
addressableRespectsEventPolicyFilters(gvr, kind, name),
},
}

fs.Features = append(fs.Features, AddressableAuthZConformanceRequestHandling(gvr, kind, name).Features...)

return &fs
}

// AddressableAuthZConformanceRequestHandling returns a FeatureSet to test the basic authorization features.
// This basic feature set contains to allow authorized and reject unauthorized requests. In addition it also
// tests, that the addressable becomes unready in case of a NotReady assigned EventPolicy.
func AddressableAuthZConformanceRequestHandling(gvr schema.GroupVersionResource, kind, name string) *feature.FeatureSet {
fs := feature.FeatureSet{
Name: fmt.Sprintf("%s handles authorization in requests correctly", kind),
Features: []*feature.Feature{
addressableAllowsAuthorizedRequest(gvr, kind, name),
addressableRejectsUnauthorizedRequest(gvr, kind, name),
addressableBecomesUnreadyOnUnreadyEventPolicy(gvr, kind, name),
},
}
return &fs
}

func addressableAllowsAuthorizedRequest(gvr schema.GroupVersionResource, kind, name string) *feature.Feature {
f := feature.NewFeatureNamed(fmt.Sprintf("%s accepts authorized request", kind))

f.Prerequisite("OIDC authentication is enabled", featureflags.AuthenticationOIDCEnabled())
f.Prerequisite("transport encryption is strict", featureflags.TransportEncryptionStrict())
f.Prerequisite("should not run when Istio is enabled", featureflags.IstioDisabled())

source := feature.MakeRandomK8sName("source")
eventPolicy := feature.MakeRandomK8sName("eventpolicy")
sourceSubject := feature.MakeRandomK8sName("source-oidc-identity")

event := test.FullEvent()

// Install event policy
f.Setup("Install the EventPolicy", func(ctx context.Context, t feature.T) {
namespace := environment.FromContext(ctx).Namespace()
eventpolicy.Install(
eventPolicy,
eventpolicy.WithToRef(
gvr.GroupVersion().WithKind(kind),
name),
eventpolicy.WithFromSubject(fmt.Sprintf("system:serviceaccount:%s:%s", namespace, sourceSubject)),
)(ctx, t)
})
f.Setup(fmt.Sprintf("EventPolicy for %s %s is ready", kind, name), k8s.IsReady(eventpolicy.GVR(), eventPolicy))

// Install source
f.Requirement("install source", eventshub.Install(
source,
eventshub.StartSenderToResourceTLS(gvr, name, nil),
eventshub.InputEvent(event),
eventshub.OIDCSubject(sourceSubject),
))

f.Alpha(kind).
Must("event sent", eventassert.OnStore(source).MatchSentEvent(test.HasId(event.ID())).Exact(1)).
Must("get 202 on response", eventassert.OnStore(source).Match(eventassert.MatchStatusCode(202)).AtLeast(1))

return f
}

func addressableRejectsUnauthorizedRequest(gvr schema.GroupVersionResource, kind, name string) *feature.Feature {
f := feature.NewFeatureNamed(fmt.Sprintf("%s rejects unauthorized request", kind))

f.Prerequisite("OIDC authentication is enabled", featureflags.AuthenticationOIDCEnabled())
f.Prerequisite("transport encryption is strict", featureflags.TransportEncryptionStrict())
f.Prerequisite("should not run when Istio is enabled", featureflags.IstioDisabled())

source := feature.MakeRandomK8sName("source")
eventPolicy := feature.MakeRandomK8sName("eventpolicy")

event := test.FullEvent()

// Install event policy
f.Setup("Install the EventPolicy with from subject that does not match", eventpolicy.Install(
eventPolicy,
eventpolicy.WithToRef(
gvr.GroupVersion().WithKind(kind),
name),
eventpolicy.WithFromSubject("system:serviceaccount:default:unknown-identity"),
))
f.Setup(fmt.Sprintf("EventPolicy for %s %s is ready", kind, name), k8s.IsReady(eventpolicy.GVR(), eventPolicy))

// Install source
f.Requirement("install source", eventshub.Install(
source,
eventshub.StartSenderToResourceTLS(gvr, name, nil),
eventshub.InputEvent(event),
eventshub.InitialSenderDelay(10*time.Second),
))

f.Alpha(kind).
Must("event sent", eventassert.OnStore(source).MatchSentEvent(test.HasId(event.ID())).Exact(1)).
Must("get 403 on response", eventassert.OnStore(source).Match(eventassert.MatchStatusCode(403)).AtLeast(1))

return f
}

func addressableRespectsEventPolicyFilters(gvr schema.GroupVersionResource, kind, name string) *feature.Feature {
f := feature.NewFeatureNamed(fmt.Sprintf("%s only admits events that pass the event policy filter", kind))

f.Prerequisite("OIDC authentication is enabled", featureflags.AuthenticationOIDCEnabled())
f.Prerequisite("transport encryption is strict", featureflags.TransportEncryptionStrict())
f.Prerequisite("should not run when Istio is enabled", featureflags.IstioDisabled())

eventPolicy := feature.MakeRandomK8sName("eventpolicy")
source1 := feature.MakeRandomK8sName("source")
sourceSubject1 := feature.MakeRandomK8sName("source-oidc-identity")
source2 := feature.MakeRandomK8sName("source")
sourceSubject2 := feature.MakeRandomK8sName("source-oidc-identity")

event1 := test.FullEvent()
event1.SetType("valid.event.type")
event1.SetID("1")
event2 := test.FullEvent()
event2.SetType("invalid.event.type")
event2.SetID("2")

// Install event policy
f.Setup("Install the EventPolicy", func(ctx context.Context, t feature.T) {
namespace := environment.FromContext(ctx).Namespace()
eventpolicy.Install(
eventPolicy,
eventpolicy.WithToRef(
gvr.GroupVersion().WithKind(kind),
name),
eventpolicy.WithFromSubject(fmt.Sprintf("system:serviceaccount:%s:%s", namespace, sourceSubject1)),
eventpolicy.WithFromSubject(fmt.Sprintf("system:serviceaccount:%s:%s", namespace, sourceSubject2)),
eventpolicy.WithFilters([]eventingv1.SubscriptionsAPIFilter{
{
Prefix: map[string]string{
"type": "valid",
},
},
}),
)(ctx, t)
})
f.Setup(fmt.Sprintf("EventPolicy for %s %s is ready", kind, name), k8s.IsReady(eventpolicy.GVR(), eventPolicy))

// Install source
f.Requirement("install source 1", eventshub.Install(
source1,
eventshub.StartSenderToResourceTLS(gvr, name, nil),
eventshub.InputEvent(event1),
eventshub.OIDCSubject(sourceSubject1),
))

f.Requirement("install source 2", eventshub.Install(
source2,
eventshub.StartSenderToResourceTLS(gvr, name, nil),
eventshub.InputEvent(event2),
eventshub.OIDCSubject(sourceSubject2),
))

f.Alpha(kind).
Must("valid event sent", eventassert.OnStore(source1).MatchSentEvent(test.HasId(event1.ID())).Exact(1)).
Must("get 202 on response", eventassert.OnStore(source1).Match(eventassert.MatchStatusCode(202)).AtLeast(1))

f.Alpha(kind).
Must("invalid event sent", eventassert.OnStore(source2).MatchSentEvent(test.HasId(event2.ID())).Exact(1)).
Must("get 403 on response", eventassert.OnStore(source2).Match(eventassert.MatchStatusCode(403)).AtLeast(1))

return f
}

func addressableBecomesUnreadyOnUnreadyEventPolicy(gvr schema.GroupVersionResource, kind, name string) *feature.Feature {
f := feature.NewFeatureNamed(fmt.Sprintf("%s becomes NotReady when EventPolicy is NotReady", kind))

f.Prerequisite("OIDC authentication is enabled", featureflags.AuthenticationOIDCEnabled())
f.Prerequisite("transport encryption is strict", featureflags.TransportEncryptionStrict())
f.Prerequisite("should not run when Istio is enabled", featureflags.IstioDisabled())

eventPolicy := feature.MakeRandomK8sName("eventpolicy")

f.Setup(fmt.Sprintf("%s is ready initially", kind), k8s.IsReady(gvr, name))

// Install event policy
f.Requirement("Install the EventPolicy", eventpolicy.Install(
eventPolicy,
eventpolicy.WithToRef(
gvr.GroupVersion().WithKind(kind),
name),
eventpolicy.WithFromRef(pingsource.Gvr().GroupVersion().WithKind("PingSource"), "doesnt-exist", "doesnt-exist"),
))
f.Requirement(fmt.Sprintf("EventPolicy for %s %s is NotReady", kind, name), k8s.IsNotReady(eventpolicy.GVR(), eventPolicy))

f.Alpha(kind).Must("become NotReady with NotReady EventPolicy ", k8s.IsNotReady(gvr, name))

return f
}
Loading

0 comments on commit 3a79845

Please sign in to comment.