Compare commits

..

15 Commits

Author SHA1 Message Date
Knative Automation 1898a2a10c
[release-1.16] Upgrade to latest dependencies (#8488)
upgrade to latest dependencies

bumping knative.dev/hack 30344ae...b5e4ff8:
  > b5e4ff8 [release-1.16] Update GKE version to 1.29 (# 415)
  > 6cb0feb [release-1.16] Refactor release script to gh CLI (# 410)
bumping knative.dev/hack/schema 30344ae...b5e4ff8:
  > b5e4ff8 [release-1.16] Update GKE version to 1.29 (# 415)
  > 6cb0feb [release-1.16] Refactor release script to gh CLI (# 410)
bumping knative.dev/reconciler-test 09111f0...f4bd4f5:
  > f4bd4f5 upgrade to latest dependencies (# 779)

Signed-off-by: Knative Automation <automation@knative.team>
2025-02-20 12:17:48 +00:00
Knative Prow Robot d59d3b68f8
[release-1.16] Scheduler: Resync reserved periodically to keep state consistent (#8452)
Scheduler: Resync reserved periodically to keep state consistent

Add resyncReserved removes deleted vPods from reserved to keep the
state consistent when leadership changes (Promote / Demote).

`initReserved` is not enough since the vPod lister can be stale.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2025-02-11 15:22:50 +00:00
Knative Prow Robot aae7a34a35
[release-1.16] Add `sinks.knative.dev` to namespaced ClusterRole (#8434)
Add `sinks.knative.dev` to namespaced ClusterRole

These are roles that users can use to give their developers access
to Knative Eventing resources and we're missing the sinks group.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2025-01-31 07:32:57 +00:00
Knative Prow Robot 7289df9b75
[release-1.16] fix: remove duplicated observedGeneration from jobsinks.sinks.knative.dev (#8423)
fix: remove duplicated observedGeneration from jobsinks.sinks.knative.dev

Co-authored-by: Fabian-K <fabiankajzar@googlemail.com>
2025-01-22 18:28:10 +00:00
Knative Prow Robot 2a46ff568f
[release-1.16] Reduce mt-broker-controller memory usage with namespaced endpoint informer (#8422)
* Reduce mt-broker-controller memory usage with namespaced endpoint informer

Currently, the mt-broker-controller is using a cluster-wide endpoints
informer but it actually only uses endpoints in the "SYSTEM_NAMESPACE".

Using the namespaced informer factory ensures that the watcher
is only watching endpoints in the `knative-eventing` (also known as
`SYSTEM_NAMESPACE`) namespace.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Start informer

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

---------

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2025-01-22 17:20:11 +00:00
Knative Automation bb92b8c414
[release-1.16] Upgrade to latest dependencies (#8409)
upgrade to latest dependencies

bumping knative.dev/hack/schema 05b2fb3...30344ae:
  > 30344ae Export KO_FLAGS for consuming scripts (# 402)
bumping knative.dev/hack 05b2fb3...30344ae:
  > 30344ae Export KO_FLAGS for consuming scripts (# 402)

Signed-off-by: Knative Automation <automation@knative.team>
2025-01-15 06:53:03 +00:00
Knative Prow Robot 7da3cee603
[release-1.16] Scheduler: LastOrdinal based on replicas instead of FreeCap (#8394)
Scheduler: LastOrdinal based on replicas instead of FreeCap

When scaling down and compacting, basing the last ordinal on the
free capacity structure leads to have a lastOrdinal off by one since
`FreeCap` might contain the free capacity for unschedulable pods.

We will have to continue including unschduelable pods in FreeCap
because it might happen that a pod becomes unscheduleble for external
reasons like node gets shutdown for pods with lower ordinals
and the pod need to be rescheduled and during that time period
we want to consider those when compacting; once all vpods that
were on that pod that is gone get rescheduled, FreeCap will only
include scheduleable pods.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2024-12-19 14:30:11 +00:00
Knative Prow Robot ee786eeee8
[release-1.16] Register eventshub image for JobSink (#8391)
Register eventshub image for JobSink

The package must be registered so that ImageProducer can map it to the
right image and replace it in the final yaml.

Co-authored-by: Martin Gencur <mgencur@redhat.com>
2024-12-19 06:10:10 +00:00
Knative Prow Robot 852ae3ba28
[release-1.16] Remove conversion webhook config in EventPolicy CRD (#8381)
Remove conversion webhook config in EventPolicy CRD

As we don't have multiple EP versions yet, we don't need the conversion webhook configuration in the EventPolicy CRD

Co-authored-by: Christoph Stäbler <cstabler@redhat.com>
2024-12-12 10:47:53 +00:00
Knative Prow Robot 9740b12837
[release-1.16] MT-Broker: return retriable status code based on the state to leverage retries (#8367)
* MT-Broker: return appropriate status code based on the state to leverage retries

The ingress or filter deployments were returning 400 even in the case
where a given resource (like trigger, broker, subscription) wasn't
found, however, this is a common case where the lister cache
hasn't caught up with the latest state.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Fix unit tests

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

---------

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2024-12-03 13:27:44 +00:00
Knative Prow Robot 96ab579ab5
[release-1.16] fix: rename `job-sink` to `job_sink` (#8339)
fix: rename `job-sink` to `job_sink`

Co-authored-by: Yates <yates.lyc@gmail.com>
2024-11-21 16:22:02 +00:00
Knative Prow Robot 526343206b
[release-1.16] JobSink: Delete secrets associated with jobs when jobs are deleted (#8332)
* JobSink: Delete secrets associated with jobs when jobs are deleted

As reported in https://github.com/knative/eventing/issues/8323 old
JobSink secrets lead to processing old events again while new events
are lost.

Using OwnerReference and k8s garbage collection, now a secret created
for a given event is bound to a given Job lifecycle, so that when a job
is deleted, the associated secret will be deleted.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Fix jobsink name generator + add unit and fuzz tests

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Fix e2e test

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Lint

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

---------

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2024-11-19 09:01:00 +00:00
Knative Prow Robot a16468471b
[release-1.16] Add jobsinks-addressable-resolver cluster role (#8302)
Add jobsinks-addressable-resolver cluster role

This will ensure that alld ServiceAccount that are bound to
"addressable-resolver" ClusterRole can read JobSinks.

Fixes issues like this for SinkBindings:
```
{"level":"error","ts":"2024-11-04T08:06:16.160Z","logger":"eventing-webhook","caller":"sinkbinding/sinkbinding.go:87",
"msg":"Failed to get Addressable from Destination:
%!w(*fmt.wrapError=&{failed to get lister for
sinks.knative.dev/v1alpha1,
Resource=jobsinks: jobsinks.sinks.knative.dev is forbidden:
User \"system:serviceaccount:knative-eventing:eventing-webhook\"
cannot list resource \"jobsinks\" in API group \"sinks.knative.dev\"
```

Co-authored-by: Martin Gencur <mgencur@redhat.com>
2024-11-19 07:19:59 +00:00
Knative Prow Robot d0c035b338
[release-1.16] Add observedGeneration in JobSink OpenAPI schema (#8300)
Add observedGeneration in JobSink OpenAPI schema

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2024-11-04 12:08:55 +00:00
Knative Prow Robot 6db9011037
[release-1.16] Schduler: MAXFILLUP strategy will spread vreplicas across multiple pods (#8291)
* Schduler: MAXFILLUP strategy will spread vreplicas across multiple pods

the MAXFILLUP algorithm was using an affinity strategy, meaning that
it would prioritize adding new vreplicas to pods with the same resources.

However, the downside is that if one pod goes down or gets
re-scheduled the entire resource would be down and not produce
events. By spreading replicas across multiple real replicas we would
guarantee better availability.

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Remove configurable HA scheduler, fix reserved replicas logic

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Log reserved

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Handle unschedulables pods and always start from reserved no matter what is placements

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Add reserved + overcommit

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Add benchmark + reduce OrdinalFromPodName calls

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

* Handle unschedulable pods

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>

---------

Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierdipi@redhat.com>
2024-10-30 06:43:49 +00:00
3914 changed files with 119150 additions and 352639 deletions

View File

@ -17,15 +17,25 @@ jobs:
fail-fast: false # Keep running if one leg fails.
matrix:
k8s-version:
- v1.32.x
- v1.33.x
- v1.28.7
- v1.29.0
test-suite:
- ./test/e2e
- ./test/conformance
- ./test/experimental
# Map between K8s and KinD versions.
# This is attempting to make it a bit clearer what's being tested.
# See: https://github.com/kubernetes-sigs/kind/releases/tag/v0.20.0
include:
- k8s-version: v1.28.7
kind-version: v0.21.0
kind-image-sha: sha256:9bc6c451a289cf96ad0bbaf33d416901de6fd632415b076ab05f5fa7e4f65c58
- k8s-version: v1.29.0
kind-version: v0.21.0
kind-image-sha: sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570
# Add the flags we use for each of these test suites.
- test-suite: ./test/e2e
extra-test-flags: >
@ -45,6 +55,7 @@ jobs:
ARTIFACTS: ${{ github.workspace }}/artifacts
NODE_VERSION: ${{ matrix.k8s-version }}
NODE_SHA: ${{ matrix.kind-image-sha }}
steps:
- name: Set up Go
@ -52,18 +63,26 @@ jobs:
# Install the latest release of ko
- name: Install ko
uses: ko-build/setup-ko@v0.9
uses: ko-build/setup-ko@v0.6
- name: Check out code onto GOPATH
uses: actions/checkout@v4
uses: actions/checkout@v2
- name: Install KinD
# TODO: replace with chainguard-dev/actions/setup-kind
uses: chainguard-dev/actions/setup-kind@16e2fd6603a1c6a1fbc880fdbb922b2e8e2be3e7 # main
with:
k8s-version: ${{ matrix.k8s-version }}
kind-worker-count: 1
cluster-suffix: c${{ github.run_id }}.local
run: |
set -x
# Disable swap otherwise memory enforcement doesn't work
# See: https://kubernetes.slack.com/archives/CEKK1KTN2/p1600009955324200
sudo swapoff -a
sudo rm -f /swapfile
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/${{ matrix.kind-version }}/kind-$(uname)-amd64
chmod +x ./kind
sudo mv kind /usr/local/bin
- name: Create KinD Cluster
run: ./hack/create-kind-cluster.sh
- name: Install Knative Eventing
run: |

View File

@ -1,11 +1,16 @@
version: "2"
run:
timeout: 10m
build-tags:
- e2e
- probe
- preupgrade
- postupgrade
- postdowngrade
skip-dirs:
- pkg/client
linters:
enable:
- asciicheck
@ -15,53 +20,10 @@ linters:
- unparam
disable:
- errcheck
settings:
staticcheck:
checks:
- all
- '-SA1019' # Temporary ignore SA1019: use of deprecated types or methods
- '-ST1003' # Temporary ignore ST1003: We have a lot of "Api" where it should be "API"
- '-ST1005' # Temporary ignore ST1005: error strings should not be capitalized
- '-ST1016' # Temporary ignore ST1016: methods on the same type should have the same receiver name
- '-ST1019' # Temporary ignore ST1019: multiple imports of a module with different names
- '-QF1002' # Temporary ignore QF1002: could use tagged switch
- '-QF1003' # Temporary ignore QF1003: Convert if/else-if chain to tagged switch
- '-QF1007' # Temporary ignore QF1007: merge conditional assignment into variable declaration
- '-QF1008' # Temporary ignore QF1008: Omit embedded fields from selector expression
- '-QF1009' # Temporary ignore QF1009: Merge conditional assignment into variable declaration
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- gosec
- unparam
path: test
- linters:
- staticcheck
text: "ST1003" # A lot of "Api" instead of "API" names
path: pkg/reconciler/testing/v1/apiserversource.go
- linters:
- staticcheck
text: "ST1001" # Prohibit dot imports
path: test/e2e/helpers/.*_helper.go
- linters:
- staticcheck
text: "ST1001" # Prohibit dot imports
path: test/rekt/features/.*.go
paths:
- pkg/client
- third_party/
- builtin$
- examples$
formatters:
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
issues:
exclude-rules:
- path: test # Excludes /test, *_test.go etc.
linters:
- gosec
- unparam

View File

@ -6,14 +6,18 @@ aliases:
- itsmurugappan
client-wg-leads:
- dsimansk
- rhuss
client-writers:
- dsimansk
- rhuss
- vyasgun
docs-reviewers:
- nainaz
- retocode
- skonto
docs-writers:
- csantanapr
- retocode
- skonto
eventing-reviewers:
- Leo6Leo
@ -21,7 +25,6 @@ aliases:
- cali0707
- creydr
eventing-wg-leads:
- creydr
- pierDipi
eventing-writers:
- Leo6Leo
@ -48,23 +51,24 @@ aliases:
knative-admin:
- aliok
- cardil
- davidhadas
- dprotaso
- dsimansk
- evankanderson
- gauron99
- knative-automation
- knative-prow-releaser-robot
- knative-prow-robot
- knative-prow-updater-robot
- knative-test-reporter-robot
- matzew
- nrrso
- nainaz
- psschwei
- retocode
- salaboy
- skonto
- upodroid
knative-release-leads:
- dprotaso
- dsimansk
- gauron99
- retocode
- skonto
knative-robots:
- knative-automation
@ -101,31 +105,39 @@ aliases:
- davidhadas
- evankanderson
serving-approvers:
- dsimansk
- ReToCode
- skonto
serving-reviewers:
- izabelacg
- retocode
- skonto
serving-triage:
- izabelacg
- retocode
- skonto
serving-wg-leads:
- dprotaso
serving-writers:
- ReToCode
- dprotaso
- dsimansk
- skonto
steering-committee:
- aliok
- davidhadas
- dprotaso
- dsimansk
- evankanderson
- matzew
- nrrso
- nainaz
- psschwei
- salaboy
technical-oversight-committee: []
ux-wg-leads:
- Leo6Leo
- cali0707
- leo6leo
- mmejia02
- zainabhusain227
ux-writers:
- Leo6Leo
- cali0707
- leo6leo
- mmejia02
- zainabhusain227

View File

@ -47,7 +47,7 @@ import (
eventingclient "knative.dev/eventing/pkg/client/injection/client"
brokerinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1/broker"
triggerinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1/trigger"
eventtypeinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1beta3/eventtype"
eventtypeinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1beta2/eventtype"
subscriptioninformer "knative.dev/eventing/pkg/client/injection/informers/messaging/v1/subscription"
"knative.dev/eventing/pkg/eventingtls"
"knative.dev/eventing/pkg/eventtype"
@ -130,7 +130,7 @@ func main() {
if featureFlags.IsEnabled(feature.EvenTypeAutoCreate) && featureStore != nil && handler != nil {
autoCreate := &eventtype.EventTypeAutoHandler{
EventTypeLister: eventtypeinformer.Get(ctx).Lister(),
EventingClient: eventingclient.Get(ctx).EventingV1beta3(),
EventingClient: eventingclient.Get(ctx).EventingV1beta2(),
FeatureStore: featureStore,
Logger: logger,
}

View File

@ -50,7 +50,7 @@ import (
eventingclient "knative.dev/eventing/pkg/client/injection/client"
brokerinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1/broker"
eventpolicyinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy"
eventtypeinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1beta3/eventtype"
eventtypeinformer "knative.dev/eventing/pkg/client/injection/informers/eventing/v1beta2/eventtype"
"knative.dev/eventing/pkg/eventingtls"
"knative.dev/eventing/pkg/eventtype"
"knative.dev/eventing/pkg/reconciler/names"
@ -75,7 +75,7 @@ type envConfig struct {
PodName string `envconfig:"POD_NAME" required:"true"`
ContainerName string `envconfig:"CONTAINER_NAME" required:"true"`
Port int `envconfig:"INGRESS_PORT" default:"8080"`
MaxTTL int32 `envconfig:"MAX_TTL" default:"255"`
MaxTTL int `envconfig:"MAX_TTL" default:"255"`
HTTPPort int `envconfig:"INGRESS_PORT" default:"8080"`
HTTPSPort int `envconfig:"INGRESS_PORT_HTTPS" default:"8443"`
}
@ -153,7 +153,7 @@ func main() {
if featureFlags.IsEnabled(feature.EvenTypeAutoCreate) && featureStore != nil && handler != nil {
autoCreate := &eventtype.EventTypeAutoHandler{
EventTypeLister: eventtypeinformer.Get(ctx).Lister(),
EventingClient: eventingclient.Get(ctx).EventingV1beta3(),
EventingClient: eventingclient.Get(ctx).EventingV1beta2(),
FeatureStore: featureStore,
Logger: logger,
}
@ -171,7 +171,7 @@ func main() {
oidcTokenProvider := auth.NewOIDCTokenProvider(ctx)
authVerifier := auth.NewVerifier(ctx, eventpolicyinformer.Get(ctx).Lister(), trustBundleConfigMapLister, configMapWatcher)
handler, err = ingress.NewHandler(logger, reporter, broker.TTLDefaulter(logger, env.MaxTTL), brokerInformer, authVerifier, oidcTokenProvider, trustBundleConfigMapLister, ctxFunc)
handler, err = ingress.NewHandler(logger, reporter, broker.TTLDefaulter(logger, int32(env.MaxTTL)), brokerInformer, authVerifier, oidcTokenProvider, trustBundleConfigMapLister, ctxFunc)
if err != nil {
logger.Fatal("Error creating Handler", zap.Error(err))
}
@ -190,7 +190,7 @@ func main() {
if featureStore.IsEnabled(feature.EvenTypeAutoCreate) {
autoCreate := &eventtype.EventTypeAutoHandler{
EventTypeLister: eventtypeinformer.Get(ctx).Lister(),
EventingClient: eventingclient.Get(ctx).EventingV1beta3(),
EventingClient: eventingclient.Get(ctx).EventingV1beta2(),
FeatureStore: featureStore,
Logger: logger,
}

View File

@ -20,27 +20,27 @@ import (
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"knative.dev/eventing/pkg/certificates"
"errors"
"log"
"net/http"
"os"
"time"
"knative.dev/pkg/injection/sharedmain"
kubefilteredfactory "knative.dev/pkg/client/injection/kube/informers/factory/filtered"
filteredFactory "knative.dev/pkg/client/injection/kube/informers/factory/filtered"
"knative.dev/pkg/signals"
eventingfilteredfactory "knative.dev/eventing/pkg/client/injection/informers/factory/filtered"
"knative.dev/eventing/pkg/apis/sinks"
"knative.dev/eventing/pkg/auth"
"knative.dev/eventing/pkg/eventingtls"
"knative.dev/eventing/pkg/reconciler/eventpolicy"
"knative.dev/eventing/pkg/reconciler/eventtransform"
"knative.dev/eventing/pkg/reconciler/jobsink"
"knative.dev/eventing/pkg/reconciler/apiserversource"
"knative.dev/eventing/pkg/reconciler/channel"
"knative.dev/eventing/pkg/reconciler/containersource"
"knative.dev/eventing/pkg/reconciler/eventtype"
integrationsink "knative.dev/eventing/pkg/reconciler/integration/sink"
integrationsource "knative.dev/eventing/pkg/reconciler/integration/source"
"knative.dev/eventing/pkg/reconciler/parallel"
"knative.dev/eventing/pkg/reconciler/pingsource"
"knative.dev/eventing/pkg/reconciler/sequence"
@ -51,18 +51,40 @@ import (
)
func main() {
ctx := signals.NewContext()
ctx = kubefilteredfactory.WithSelectors(ctx,
port := os.Getenv("PROBES_PORT")
if port == "" {
port = "8080"
}
// sets up liveness and readiness probes.
server := http.Server{
ReadTimeout: 5 * time.Second,
Handler: http.HandlerFunc(handler),
Addr: ":" + port,
}
go func() {
go func() {
<-ctx.Done()
_ = server.Shutdown(ctx)
}()
// start the web server on port and accept requests
log.Printf("Readiness and health check server listening on port %s", port)
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}()
ctx = filteredFactory.WithSelectors(ctx,
auth.OIDCLabelSelector,
eventingtls.TrustBundleLabelSelector,
sinks.JobSinkJobsLabelSelector,
eventtransform.JsonataResourcesSelector,
certificates.SecretLabelSelectorPair,
)
ctx = eventingfilteredfactory.WithSelectors(ctx,
eventtransform.JsonataResourcesSelector,
)
sharedmain.MainWithContext(ctx, "controller",
@ -82,20 +104,18 @@ func main() {
apiserversource.NewController,
pingsource.NewController,
containersource.NewController,
integrationsource.NewController,
// Sources CRD
sourcecrd.NewController,
// Sinks
jobsink.NewController,
integrationsink.NewController,
// Sugar
sugarnamespace.NewController,
sugartrigger.NewController,
// Transform
eventtransform.NewController,
)
}
func handler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}

View File

@ -257,9 +257,6 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
js = js.DeepCopy() // Do not modify informer copy.
js.SetDefaults(ctx)
job := js.Spec.Job.DeepCopy()
job.Name = jobName
if job.Labels == nil {

View File

@ -26,9 +26,7 @@ import (
eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1"
flowsv1 "knative.dev/eventing/pkg/apis/flows/v1"
messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1"
sinksv1alpha1 "knative.dev/eventing/pkg/apis/sinks/v1alpha1"
sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1"
sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1"
)
// schema is a tool to dump the schema for Eventing resources.
@ -42,21 +40,15 @@ func main() {
registry.Register(&messagingv1.Channel{})
registry.Register(&messagingv1.InMemoryChannel{})
// Sinks
registry.Register(&sinksv1alpha1.JobSink{})
registry.Register(&sinksv1alpha1.IntegrationSink{})
// Sources
registry.Register(&sourcesv1.ApiServerSource{})
registry.Register(&sourcesv1.SinkBinding{})
registry.Register(&sourcesv1.ContainerSource{}) // WARNING: THIS DOES NOT WORK OUT OF THE BOX: See https://github.com/knative/eventing/issues/5353.
registry.Register(&sourcesv1alpha1.IntegrationSource{})
// Flows
registry.Register(&flowsv1.Sequence{})
registry.Register(&flowsv1.Parallel{})
registry.Register(&eventingv1alpha1.EventPolicy{})
registry.Register(&eventingv1alpha1.EventTransform{})
if err := commands.New("knative.dev/eventing").Execute(); err != nil {
log.Fatal("Error during command execution: ", err)

View File

@ -20,8 +20,6 @@ import (
"context"
"os"
sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
@ -79,8 +77,7 @@ func init() {
var ourTypes = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
// For group eventing.knative.dev.
// v1alpha1
eventingv1alpha1.SchemeGroupVersion.WithKind("EventPolicy"): &eventingv1alpha1.EventPolicy{},
eventingv1alpha1.SchemeGroupVersion.WithKind("EventTransform"): &eventingv1alpha1.EventTransform{},
eventingv1alpha1.SchemeGroupVersion.WithKind("EventPolicy"): &eventingv1alpha1.EventPolicy{},
// v1beta1
eventingv1beta1.SchemeGroupVersion.WithKind("EventType"): &eventingv1beta1.EventType{},
// v1beta2
@ -95,8 +92,6 @@ var ourTypes = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
messagingv1.SchemeGroupVersion.WithKind("Subscription"): &messagingv1.Subscription{},
// For group sources.knative.dev.
// v1alpha1
sourcesv1alpha1.SchemeGroupVersion.WithKind("IntegrationSource"): &sourcesv1alpha1.IntegrationSource{},
// v1beta2
sourcesv1beta2.SchemeGroupVersion.WithKind("PingSource"): &sourcesv1beta2.PingSource{},
// v1
@ -107,8 +102,7 @@ var ourTypes = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
// For group sinks.knative.dev.
// v1alpha1
sinksv1alpha1.SchemeGroupVersion.WithKind("JobSink"): &sinksv1alpha1.JobSink{},
sinksv1alpha1.SchemeGroupVersion.WithKind("IntegrationSink"): &sinksv1alpha1.IntegrationSink{},
sinksv1alpha1.SchemeGroupVersion.WithKind("JobSink"): &sinksv1alpha1.JobSink{},
// For group flows.knative.dev
// v1

View File

@ -45,7 +45,6 @@ func init() {
func main() {
flag.Parse()
//nolint:staticcheck
k_sink := os.Getenv("K_SINK")
if k_sink != "" {
sink = k_sink

View File

@ -1 +0,0 @@
./core/resources/eventtransform.yaml

View File

@ -1 +0,0 @@
core/resources/integrationsink.yaml

View File

@ -1 +0,0 @@
core/resources/integrationsource.yaml

View File

@ -1 +0,0 @@
../third_party/eventing-integrations-latest/eventing-integrations-images.yaml

View File

@ -1 +0,0 @@
../third_party/eventing-integrations-latest/eventing-transformations-images.yaml

View File

@ -83,27 +83,8 @@ spec:
seccompProfile:
type: RuntimeDefault
livenessProbe:
httpGet:
path: /health
port: probes
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: probes
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
ports:
- name: metrics
containerPort: 9090
- name: profiling
containerPort: 8008
- name: probes
containerPort: 8080

View File

@ -1 +0,0 @@
../../../third_party/eventing-integrations-latest/eventing-integrations-images.yaml

View File

@ -1 +0,0 @@
../../../third_party/eventing-integrations-latest/eventing-transformations-images.yaml

View File

@ -23,7 +23,7 @@ metadata:
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
annotations:
knative.dev/example-checksum: "b7377954"
knative.dev/example-checksum: "f46cf09d"
data:
_example: |
################################
@ -41,45 +41,34 @@ data:
# this example block and unindented to be in the data block
# to actually change the configuration.
# metrics-protocol field specifies the protocol used when exporting metrics
# It supports either 'none' (the default), 'prometheus', 'http/protobuf' (OTLP HTTP), 'grpc' (OTLP gRPC)
metrics-protocol: http/protobuf
# metrics.backend-destination field specifies the system metrics destination.
# It supports either prometheus (the default) or stackdriver.
# Note: Using stackdriver will incur additional charges
metrics.backend-destination: prometheus
# metrics-endpoint field specifies the destination metrics should be exported to.
#
# The endpoint MUST be set when the protocol is http/protobuf or grpc.
# The endpoint MUST NOT be set when the protocol is none.
#
# When the protocol is prometheus the endpoint can accept a 'host:port' string to customize the
# listening host interface and port.
metrics-endpoint: http://collector.otel.svc.cluster.local/
# metrics.request-metrics-backend-destination specifies the request metrics
# destination. If non-empty, it enables queue proxy to send request metrics.
# Currently supported values: prometheus, stackdriver.
metrics.request-metrics-backend-destination: prometheus
# metrics-export-interval specifies the global metrics reporting period for control and data plane components.
# If a zero or negative value is passed the default reporting OTel period is used (60 secs).
metrics-export-interval: 60s
# metrics.stackdriver-project-id field specifies the stackdriver project ID. This
# field is optional. When running on GCE, application default credentials will be
# used if this field is not provided.
metrics.stackdriver-project-id: "<your stackdriver project id>"
# metrics.allow-stackdriver-custom-metrics indicates whether it is allowed to send metrics to
# Stackdriver using "global" resource type and custom metric type if the
# metrics are not supported by "knative_broker", "knative_trigger", and "knative_source" resource types.
# Setting this flag to "true" could cause extra Stackdriver charge.
# If metrics.backend-destination is not Stackdriver, this is ignored.
metrics.allow-stackdriver-custom-metrics: "false"
# profiling.enable indicates whether it is allowed to retrieve runtime profiling data from
# the pods via an HTTP server in the format expected by the pprof visualization tool. When
# enabled, the Knative Eventing pods expose the profiling data on an alternate HTTP port 8008.
# The HTTP context root for profiling is then /debug/pprof/.
profiling.enable: "false"
# sink-event-error-reporting.enable whether the adapter reports a kube event to the CRD indicating
# a failure to send a cloud event to the sink.
sink-event-error-reporting.enable: "false"
# runtime-profiling indicates whether it is allowed to retrieve runtime profiling data from
# the pods via an HTTP server in the format expected by the pprof visualization tool. When
# enabled, the Knative Eventing pods expose the profiling data on an alternate HTTP port 8008.
# The HTTP context root for profiling is then /debug/pprof/.
runtime-profiling: enabled
# tracing-protocol field specifies the protocol used when exporting traces
# It supports either 'none' (the default), 'prometheus', 'http/protobuf' (OTLP HTTP), 'grpc' (OTLP gRPC)
# or `stdout` for debugging purposes
tracing-protocol: http/protobuf
# tracing-endpoint field specifies the destination traces should be exporter to.
#
# The endpoint MUST be set when the protocol is http/protobuf or grpc.
# The endpoint MUST NOT be set when the protocol is none.
tracing-endpoint: http://jaeger-collector.observability:4318/v1/traces
# tracing-sampling-rate allows the user to specify what percentage of all traces should be exported
# The value should be between 0 (never sample) to 1 (always sample)
tracing-sampling-rate: "1"

View File

@ -23,11 +23,33 @@ metadata:
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
annotations:
knative.dev/example-checksum: "04c7e9a3"
knative.dev/example-checksum: "0492ceb0"
data:
_example: |
###########################################################
# #
# This config is deprecated - use config-observability #
# #
###########################################################
################################
# #
# EXAMPLE CONFIGURATION #
# #
################################
# This block is not actually functional configuration,
# but serves to illustrate the available configuration
# options and document them in a way that is accessible
# to users that `kubectl edit` this config map.
#
# These sample configuration options may be copied out of
# this example block and unindented to be in the data block
# to actually change the configuration.
#
# This may be "zipkin" or "none". the default is "none"
backend: "none"
# URL to zipkin collector where traces are sent.
# This must be specified when backend is "zipkin"
zipkin-endpoint: "http://zipkin.istio-system.svc.cluster.local:9411/api/v2/spans"
# Enable zipkin debug mode. This allows all spans to be sent to the server
# bypassing sampling.
debug: "false"
# Percentage (0-1) of requests to trace
sample-rate: "0.1"

View File

@ -77,59 +77,6 @@ spec:
fieldRef:
fieldPath: metadata.name
- name: EVENT_TRANSFORM_JSONATA_IMAGE
valueFrom:
configMapKeyRef:
key: transform-jsonata
name: eventing-transformations-images
- name: INTEGRATION_SOURCE_TIMER_IMAGE
valueFrom:
configMapKeyRef:
key: timer-source
name: eventing-integrations-images
- name: INTEGRATION_SOURCE_AWS_S3_IMAGE
valueFrom:
configMapKeyRef:
key: aws-s3-source
name: eventing-integrations-images
- name: INTEGRATION_SOURCE_AWS_SQS_IMAGE
valueFrom:
configMapKeyRef:
key: aws-sqs-source
name: eventing-integrations-images
- name: INTEGRATION_SOURCE_AWS_DDB_STREAMS_IMAGE
valueFrom:
configMapKeyRef:
key: aws-ddb-streams-source
name: eventing-integrations-images
- name: INTEGRATION_SINK_LOG_IMAGE
valueFrom:
configMapKeyRef:
key: log-sink
name: eventing-integrations-images
- name: INTEGRATION_SINK_AWS_S3_IMAGE
valueFrom:
configMapKeyRef:
key: aws-s3-sink
name: eventing-integrations-images
- name: INTEGRATION_SINK_AWS_SQS_IMAGE
valueFrom:
configMapKeyRef:
key: aws-sqs-sink
name: eventing-integrations-images
- name: INTEGRATION_SINK_AWS_SNS_IMAGE
valueFrom:
configMapKeyRef:
key: aws-sns-sink
name: eventing-integrations-images
## Adapter settings
# - name: K_LOGGING_CONFIG

View File

@ -87,8 +87,6 @@ spec:
- containerPort: 9090
name: metrics
protocol: TCP
- name: probes
containerPort: 8080
resources:
requests:
cpu: 125m
@ -106,21 +104,4 @@ spec:
seccompProfile:
type: RuntimeDefault
livenessProbe:
httpGet:
path: /health
port: probes
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: probes
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
serviceAccountName: pingsource-mt-adapter

View File

@ -1,281 +0,0 @@
# Copyright 2025 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.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: eventtransforms.eventing.knative.dev
labels:
knative.dev/crd-install: "true"
duck.knative.dev/addressable: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
spec:
group: eventing.knative.dev
versions:
- name: v1alpha1
served: true
storage: true
subresources:
status: { }
schema:
openAPIV3Schema:
type: object
properties:
spec:
description: Spec defines the desired state of the EventTransform.
type: object
properties:
jsonata:
type: object
properties:
expression:
description: Expression is the JSONata expression (https://jsonata.org/).
type: string
reply:
description: |
Reply is the configuration on how to handle responses from Sink. It can only be set if Sink is set.
Only one "type" can be used.
The used type must match the top-level transformation, if you need to mix transformation types, use compositions and chain transformations together to achieve your desired outcome.
type: object
properties:
jsonata:
type: object
properties:
expression:
description: Expression is the JSONata expression (https://jsonata.org/).
type: string
discard:
description: |
Discard discards responses from Sink and return empty response body.
When set to false, it returns the exact sink response body.
When set to true, Discard is mutually exclusive with EventTransformations in the reply
section, it can either be discarded or transformed.
Default: false.
type: boolean
sink:
description: 'Sink is a reference to an object that will resolve to a uri to use as the sink. If not present, the transformation will send back the transformed event as response, this is useful to leverage the built-in Broker reply feature to re-publish a transformed event back to the broker. '
type: object
properties:
CACerts:
description: CACerts are Certification Authority (CA) certificates in PEM format according to https://www.rfc-editor.org/rfc/rfc7468. If set, these CAs are appended to the set of CAs provided by the Addressable target, if any.
type: string
audience:
description: Audience is the OIDC audience. This need only be set, if the target is not an Addressable and thus the Audience can't be received from the Addressable itself. In case the Addressable specifies an Audience too, the Destinations Audience takes preference.
type: string
ref:
description: Ref points to an Addressable.
type: object
properties:
address:
description: Address points to a specific Address Name.
type: string
apiVersion:
description: API version of the referent.
type: string
group:
description: 'Group of the API, without the version of the group. This can be used as an alternative to the APIVersion, and then resolved using ResolveGroup. Note: This API is EXPERIMENTAL and might break anytime. For more details: https://github.com/knative/eventing/issues/5086'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ This is optional field, it gets defaulted to the object holding it if left out.'
type: string
uri:
description: URI can be an absolute URL(non-empty scheme and non-empty host) pointing to the target or a relative URI. Relative URIs will be resolved using the base URI retrieved from Ref.
type: string
status:
description: Status represents the current state of the EventTransform. This data may be out of date.
type: object
properties:
address:
description: Address is a single Addressable address. If Addresses is present, Address will be ignored by clients.
type: object
required:
- url
properties:
CACerts:
description: CACerts is the Certification Authority (CA) certificates in PEM format according to https://www.rfc-editor.org/rfc/rfc7468.
type: string
audience:
description: Audience is the OIDC audience for this address.
type: string
name:
description: Name is the name of the address.
type: string
url:
type: string
addresses:
description: Addresses is a list of addresses for different protocols (HTTP and HTTPS) If Addresses is present, Address must be ignored by clients.
type: array
items:
type: object
required:
- url
properties:
CACerts:
description: CACerts is the Certification Authority (CA) certificates in PEM format according to https://www.rfc-editor.org/rfc/rfc7468.
type: string
audience:
description: Audience is the OIDC audience for this address.
type: string
name:
description: Name is the name of the address.
type: string
url:
type: string
annotations:
description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.
type: object
x-kubernetes-preserve-unknown-fields: true
auth:
description: Auth defines the attributes that provide the generated service account name in the resource status.
type: object
required:
- serviceAccountName
properties:
serviceAccountName:
description: ServiceAccountName is the name of the generated service account used for this components OIDC authentication.
type: string
serviceAccountNames:
description: ServiceAccountNames is the list of names of the generated service accounts used for this components OIDC authentication. This list can have len() > 1, when the component uses multiple identities (e.g. in case of a Parallel).
type: array
items:
type: string
conditions:
description: Conditions the latest available observations of a resource's current state.
type: array
items:
type: object
required:
- type
- status
properties:
lastTransitionTime:
description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
severity:
description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition.
type: string
jsonata:
description: JsonataTransformationStatus is the status associated with JsonataEventTransformationSpec.
type: object
properties:
deployment:
type: object
properties:
availableReplicas:
description: Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.
type: integer
format: int32
collisionCount:
description: Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.
type: integer
format: int32
conditions:
description: Represents the latest available observations of a deployment's current state.
type: array
items:
type: object
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
type: string
lastUpdateTime:
description: The last time this condition was updated.
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of deployment condition.
type: string
observedGeneration:
description: The generation observed by the deployment controller.
type: integer
format: int64
readyReplicas:
description: readyReplicas is the number of pods targeted by this Deployment with a Ready Condition.
type: integer
format: int32
replicas:
description: Total number of non-terminated pods targeted by this deployment (their labels match the selector).
type: integer
format: int32
unavailableReplicas:
description: Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.
type: integer
format: int32
updatedReplicas:
description: Total number of non-terminated pods targeted by this deployment that have the desired template spec.
type: integer
format: int32
observedGeneration:
description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.
type: integer
format: int64
sinkAudience:
description: SinkAudience is the OIDC audience of the sink.
type: string
sinkCACerts:
description: SinkCACerts are Certification Authority (CA) certificates in PEM format according to https://www.rfc-editor.org/rfc/rfc7468.
type: string
sinkUri:
description: SinkURI is the current active sink URI that has been configured for the Source.
type: string
additionalPrinterColumns:
- name: URL
type: string
jsonPath: ".status.address.url"
- name: Sink
type: string
jsonPath: ".status.sinkUri"
- name: Ready
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].status"
- name: Reason
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].reason"
names:
kind: EventTransform
plural: eventtransforms
singular: eventtransform
categories:
- all
- knative
- eventing
scope: Namespaced

View File

@ -1,425 +0,0 @@
# Copyright 2020 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.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: integrationsinks.sinks.knative.dev
labels:
knative.dev/crd-install: "true"
duck.knative.dev/addressable: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
spec:
group: sinks.knative.dev
versions:
- name: v1alpha1
served: true
storage: true
subresources:
status: { }
schema:
openAPIV3Schema:
description: 'IntegrationSink sends events to generic event sink'
type: object
properties:
spec:
description: Spec defines the desired state of the IntegrationSink.
type: object
properties:
log:
type: object
properties:
loggerName:
type: string
title: Logger Name
description: Name of the logging category to use
default: log-sink
level:
type: string
title: Log Level
description: Logging level to use
default: INFO
logMask:
type: boolean
title: Log Mask
description: Mask sensitive information like password or passphrase in the
log
default: false
marker:
type: string
title: Marker
description: An optional Marker name to use
multiline:
type: boolean
title: Multiline
description: If enabled then each information is outputted on a newline
default: false
showAllProperties:
type: boolean
title: Show All Properties
description: Show all of the exchange properties (both internal and custom)
default: false
showBody:
type: boolean
title: Show Body
description: Show the message body
default: true
showBodyType:
type: boolean
title: Show Body Type
description: Show the body Java type
default: true
showExchangePattern:
type: boolean
title: Show Exchange Pattern
description: Shows the Message Exchange Pattern (or MEP for short)
default: true
showHeaders:
type: boolean
title: Show Headers
description: Show the headers received
default: false
showProperties:
type: boolean
title: Show Properties
description: Show the exchange properties (only custom). Use showAllProperties
to show both internal and custom properties.
default: false
showStreams:
type: boolean
title: Show Streams
description: Show the stream bodies (they may not be available in following
steps)
default: false
showCachedStreams:
type: boolean
title: Show Cached Streams
description: Whether Camel should show cached stream bodies or not.
default: true
aws:
type: object
properties:
s3:
type: object
properties:
arn:
type: string
title: Bucket Name
description: The S3 Bucket name or Amazon Resource Name (ARN).
deleteAfterRead:
type: boolean
title: Auto-delete Objects
description: Specifies to delete objects after consuming them.
default: true
moveAfterRead:
type: boolean
title: Move Objects After Delete
description: Move objects from S3 bucket to a different bucket after
they have been retrieved.
default: false
destinationBucket:
type: string
title: Destination Bucket
description: Define the destination bucket where an object must be moved
when moveAfterRead is set to true.
destinationBucketPrefix:
type: string
title: Destination Bucket Prefix
description: Define the destination bucket prefix to use when an object
must be moved, and moveAfterRead is set to true.
destinationBucketSuffix:
type: string
title: Destination Bucket Suffix
description: Define the destination bucket suffix to use when an object
must be moved, and moveAfterRead is set to true.
region:
type: string
title: AWS Region
description: The AWS region to access.
autoCreateBucket:
type: boolean
title: Autocreate Bucket
description: Specifies to automatically create the S3 bucket.
default: false
prefix:
type: string
title: Prefix
description: The AWS S3 bucket prefix to consider while searching.
example: folder/
ignoreBody:
type: boolean
title: Ignore Body
description: If true, the S3 Object body is ignored. Setting this to
true overrides any behavior defined by the `includeBody` option. If
false, the S3 object is put in the body.
default: false
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
forcePathStyle:
type: boolean
title: Force Path Style
description: Forces path style when accessing AWS S3 buckets.
default: false
delay:
type: integer
title: Delay
description: The number of milliseconds before the next poll of the
selected bucket.
default: 500
maxMessagesPerPoll:
type: integer
title: Max Messages Per Poll
description: Gets the maximum number of messages as a limit to poll
at each polling. Gets the maximum number of messages as a limit to
poll at each polling. The default value is 10. Use 0 or a negative
number to set it as unlimited.
default: 10
sqs:
type: object
properties:
arn:
type: string
title: Queue Name
description: The SQS Queue Name or ARN
deleteAfterRead:
type: boolean
title: Auto-delete Messages
description: Delete messages after consuming them
default: true
region:
type: string
title: AWS Region
description: The AWS region to access.
autoCreateQueue:
type: boolean
title: Autocreate Queue
description: Setting the autocreation of the SQS queue.
default: false
host:
type: string
title: AWS Host
description: The hostname of the Amazon AWS cloud.
default: amazonaws.com
protocol:
type: string
title: Protocol
description: The underlying protocol used to communicate with SQS
default: https
example: http or https
queueURL:
type: string
title: Queue URL
description: The full SQS Queue URL (required if using KEDA)
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
delay:
type: integer
title: Delay
description: The number of milliseconds before the next poll of the
selected stream
default: 500
greedy:
type: boolean
title: Greedy Scheduler
description: If greedy is enabled, then the polling will happen immediately
again, if the previous run polled 1 or more messages.
default: false
maxMessagesPerPoll:
type: integer
title: Max Messages Per Poll
description: The maximum number of messages to return. Amazon SQS never
returns more messages than this value (however, fewer messages might
be returned). Valid values 1 to 10. Default 1.
default: 1
waitTimeSeconds:
type: integer
title: Wait Time Seconds
description: The duration (in seconds) for which the call waits for
a message to arrive in the queue before returning. If a message is
available, the call returns sooner than WaitTimeSeconds. If no messages
are available and the wait time expires, the call does not return
a message list.
visibilityTimeout:
type: integer
title: Visibility Timeout
description: The duration (in seconds) that the received messages are
hidden from subsequent retrieve requests after being retrieved by
a ReceiveMessage request.
sns:
type: object
properties:
arn:
type: string
title: Topic Name
description: The SNS topic name name or Amazon Resource Name (ARN).
region:
type: string
title: AWS Region
description: The AWS region to access.
autoCreateTopic:
type: boolean
title: Autocreate Topic
description: Setting the autocreation of the SNS topic.
default: false
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
auth:
description: 'Auth configurations'
type: object
properties:
secret:
description: 'Auth secret'
type: object
properties:
ref:
description: |
Secret reference.
type: object
required:
- name
properties:
name:
description: 'Secret name'
type: string
status:
description: Status represents the current state of the IntegrationSink. This data may be out of date.
type: object
properties:
address:
description: IntegrationSink is Addressable. It exposes the endpoints as URIs to get events delivered into the used Kamelet.
type: object
properties:
name:
type: string
url:
type: string
CACerts:
type: string
audience:
type: string
addresses:
description: IntegrationSink is Addressable. It exposes the endpoints as URIs to get events delivered into the used Kamelet.
type: array
items:
type: object
properties:
name:
type: string
url:
type: string
CACerts:
type: string
audience:
type: string
annotations:
description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.
type: object
x-kubernetes-preserve-unknown-fields: true
policies:
description: List of applied EventPolicies
type: array
items:
type: object
properties:
apiVersion:
description: The API version of the applied EventPolicy. This indicates, which version of EventPolicy is supported by the resource.
type: string
name:
description: The name of the applied EventPolicy
type: string
conditions:
description: Conditions the latest available observations of a resource's current state.
type: array
items:
type: object
required:
- type
- status
properties:
lastTransitionTime:
description: 'LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).'
type: string
message:
description: 'A human readable message indicating details about the transition.'
type: string
reason:
description: 'The reason for the condition''s last transition.'
type: string
severity:
description: 'Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error.'
type: string
status:
description: 'Status of the condition, one of True, False, Unknown.'
type: string
type:
description: 'Type of condition.'
type: string
observedGeneration:
description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.
type: integer
format: int64
additionalPrinterColumns:
- name: URL
type: string
jsonPath: .status.address.url
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
- name: Ready
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].status"
- name: Reason
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].reason"
names:
kind: IntegrationSink
plural: integrationsinks
singular: integrationsink
categories:
- all
- knative
- eventing
- sink
scope: Namespaced

View File

@ -1,421 +0,0 @@
# Copyright 2020 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.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
labels:
eventing.knative.dev/source: "true"
duck.knative.dev/source: "true"
knative.dev/crd-install: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
name: integrationsources.sources.knative.dev
spec:
group: sources.knative.dev
versions:
- name: v1alpha1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
description: 'IntegrationSource is an event source that starts a container image which generates events under certain situations and sends messages to a sink URI'
type: object
properties:
spec:
type: object
properties:
ceOverrides:
description: CloudEventOverrides defines overrides to control the output format and modifications of the event sent to the sink.
type: object
properties:
extensions:
description: Extensions specify what attribute are added or overridden on the outbound event. Each `Extensions` key-value pair are set on the event as an attribute extension independently.
type: object
x-kubernetes-preserve-unknown-fields: true
sink:
description: Sink is a reference to an object that will resolve to a uri to use as the sink.
type: object
properties:
ref:
description: Ref points to an Addressable.
type: object
properties:
apiVersion:
description: API version of the referent.
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ This is optional field, it gets defaulted to the object holding it if left out.'
type: string
uri:
description: URI can be an absolute URL(non-empty scheme and non-empty host) pointing to the target or a relative URI. Relative URIs will be resolved using the base URI retrieved from Ref.
type: string
CACerts:
description: CACerts is the Certification Authority (CA) certificates in PEM format that the source trusts when sending events to the sink.
type: string
audience:
description: Audience is the OIDC audience. This only needs to be set if the target is not an Addressable and thus the Audience can't be received from the target itself. If specified, it takes precedence over the target's Audience.
type: string
timer:
type: object
properties:
period:
type: integer
title: Period
description: The interval (in milliseconds) to wait between producing the
next message.
default: 1000
message:
type: string
title: Message
description: The message to generate.
example: hello world
contentType:
type: string
title: Content Type
description: The content type of the generated message.
default: text/plain
repeatCount:
type: integer
title: Repeat Count
description: Specifies a maximum limit of number of fires
aws:
type: object
properties:
s3:
type: object
properties:
arn:
type: string
title: Bucket Name
description: The S3 Bucket name or Amazon Resource Name (ARN).
deleteAfterRead:
type: boolean
title: Auto-delete Objects
description: Specifies to delete objects after consuming them.
default: true
moveAfterRead:
type: boolean
title: Move Objects After Delete
description: Move objects from S3 bucket to a different bucket after
they have been retrieved.
default: false
destinationBucket:
type: string
title: Destination Bucket
description: Define the destination bucket where an object must be moved
when moveAfterRead is set to true.
destinationBucketPrefix:
type: string
title: Destination Bucket Prefix
description: Define the destination bucket prefix to use when an object
must be moved, and moveAfterRead is set to true.
destinationBucketSuffix:
type: string
title: Destination Bucket Suffix
description: Define the destination bucket suffix to use when an object
must be moved, and moveAfterRead is set to true.
region:
type: string
title: AWS Region
description: The AWS region to access.
autoCreateBucket:
type: boolean
title: Autocreate Bucket
description: Specifies to automatically create the S3 bucket.
default: false
prefix:
type: string
title: Prefix
description: The AWS S3 bucket prefix to consider while searching.
example: folder/
ignoreBody:
type: boolean
title: Ignore Body
description: If true, the S3 Object body is ignored. Setting this to
true overrides any behavior defined by the `includeBody` option. If
false, the S3 object is put in the body.
default: false
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
forcePathStyle:
type: boolean
title: Force Path Style
description: Forces path style when accessing AWS S3 buckets.
default: false
delay:
type: integer
title: Delay
description: The number of milliseconds before the next poll of the
selected bucket.
default: 500
maxMessagesPerPoll:
type: integer
title: Max Messages Per Poll
description: Gets the maximum number of messages as a limit to poll
at each polling. Gets the maximum number of messages as a limit to
poll at each polling. The default value is 10. Use 0 or a negative
number to set it as unlimited.
default: 10
sqs:
type: object
properties:
arn:
type: string
title: Queue Name
description: The SQS Queue Name or ARN
deleteAfterRead:
type: boolean
title: Auto-delete Messages
description: Delete messages after consuming them
default: true
region:
type: string
title: AWS Region
description: The AWS region to access.
autoCreateQueue:
type: boolean
title: Autocreate Queue
description: Setting the autocreation of the SQS queue.
default: false
host:
type: string
title: AWS Host
description: The hostname of the Amazon AWS cloud.
default: amazonaws.com
protocol:
type: string
title: Protocol
description: The underlying protocol used to communicate with SQS
default: https
example: http or https
queueURL:
type: string
title: Queue URL
description: The full SQS Queue URL (required if using KEDA)
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
delay:
type: integer
title: Delay
description: The number of milliseconds before the next poll of the
selected stream
default: 500
greedy:
type: boolean
title: Greedy Scheduler
description: If greedy is enabled, then the polling will happen immediately
again, if the previous run polled 1 or more messages.
default: false
maxMessagesPerPoll:
type: integer
title: Max Messages Per Poll
description: The maximum number of messages to return. Amazon SQS never
returns more messages than this value (however, fewer messages might
be returned). Valid values 1 to 10. Default 1.
default: 1
waitTimeSeconds:
type: integer
title: Wait Time Seconds
description: The duration (in seconds) for which the call waits for
a message to arrive in the queue before returning. If a message is
available, the call returns sooner than WaitTimeSeconds. If no messages
are available and the wait time expires, the call does not return
a message list.
visibilityTimeout:
type: integer
title: Visibility Timeout
description: The duration (in seconds) that the received messages are
hidden from subsequent retrieve requests after being retrieved by
a ReceiveMessage request.
ddbStreams:
type: object
properties:
table:
type: string
title: Table
description: The name of the DynamoDB table.
region:
type: string
title: AWS Region
description: The AWS region to access.
streamIteratorType:
type: string
title: Stream Iterator Type
description: Defines where in the DynamoDB stream to start getting records.
There are two enums and the value can be one of FROM_LATEST and FROM_START.
Note that using FROM_START can cause a significant delay before the stream
has caught up to real-time.
default: FROM_LATEST
uriEndpointOverride:
type: string
title: Overwrite Endpoint URI
description: The overriding endpoint URI. To use this option, you must
also select the `overrideEndpoint` option.
overrideEndpoint:
type: boolean
title: Endpoint Overwrite
description: Select this option to override the endpoint URI. To use
this option, you must also provide a URI for the `uriEndpointOverride`
option.
default: false
delay:
type: integer
title: Delay
description: The number of milliseconds before the next poll from the
database.
default: 500
auth:
description: 'Auth configurations'
type: object
properties:
secret:
description: 'Auth secret'
type: object
properties:
ref:
description: |
Secret reference.
type: object
required:
- name
properties:
name:
description: 'Secret name'
type: string
template:
type: object
x-kubernetes-preserve-unknown-fields: true
description: 'A template in the shape of `Deployment.spec.template` to be used for this ContainerSource. More info: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/'
status:
type: object
properties:
annotations:
description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.
type: object
x-kubernetes-preserve-unknown-fields: true
auth:
description: Auth provides the relevant information for OIDC authentication.
type: object
properties:
serviceAccountName:
description: ServiceAccountName is the name of the generated service account used for this components OIDC authentication.
type: string
serviceAccountNames:
description: ServiceAccountNames is the list of names of the generated service accounts used for this components OIDC authentication.
type: array
items:
type: string
ceAttributes:
description: CloudEventAttributes are the specific attributes that the Source uses as part of its CloudEvents.
type: array
items:
type: object
properties:
source:
description: Source is the CloudEvents source attribute.
type: string
type:
description: Type refers to the CloudEvent type attribute.
type: string
conditions:
description: Conditions the latest available observations of a resource's current state.
type: array
items:
type: object
required:
- type
- status
properties:
lastTransitionTime:
description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
severity:
description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition.
type: string
observedGeneration:
description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.
type: integer
format: int64
sinkUri:
description: SinkURI is the current active sink URI that has been configured for the Source.
type: string
sinkCACerts:
description: CACerts is the Certification Authority (CA) certificates in PEM format that the source trusts when sending events to the sink.
type: string
sinkAudience:
description: Audience is the OIDC audience of the sink.
type: string
additionalPrinterColumns:
- name: Sink
type: string
jsonPath: ".status.sinkUri"
- name: Age
type: date
jsonPath: ".metadata.creationTimestamp"
- name: Ready
type: string
jsonPath: ".status.conditions[?(@.type=='Ready')].status"
- name: Reason
type: string
jsonPath: ".status.conditions[?(@.type=='Ready')].reason"
names:
categories:
- all
- knative
- sources
kind: IntegrationSource
plural: integrationsources
singular: integrationsource
scope: Namespaced

View File

@ -1,213 +0,0 @@
# 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.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: requestreplies.eventing.knative.dev
labels:
knative.dev/crd-install: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
spec:
group: eventing.knative.dev
versions:
- name: v1alpha1
served: true
storage: true
subresources:
status: {}
schema:
openAPIV3Schema:
type: object
properties:
spec:
description: Spec defines the desired state of the RequestReply.
type: object
properties:
brokerRef:
description: A KReference referring to the broker this RequestReply forwards events to. CrossNamespace references are not allowed.
type: object
properties:
apiVersion:
description: API Version of the broker.
type: string
kind:
description: 'Kind of the broker. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the broker. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
correlationAttribute:
description: The name of the cloudevent attribute where the correlation id will be set on new events.
type: string
replyAttribute:
description: The name of the cloudevents attribute which will hold the correlation id for an event which will be treated as a reply.
type: string
secrets:
description: A list of the names of one or more secrets used to sign the correlation ids and reply ids. The secrets must be in the same namespace as the requestreply resource.
type: array
items:
type: string
timeout:
description: A ISO8601 string representing how long RequestReply holds onto an incoming request before it times out without a reply.
type: string
delivery:
description: Delivery contains the delivery spec for each trigger to this Broker. Each trigger delivery spec, if any, overrides this global delivery spec.
type: object
properties:
backoffDelay:
description: 'BackoffDelay is the delay before retrying. More information on Duration format: - https://www.iso.org/iso-8601-date-and-time-format.html - https://en.wikipedia.org/wiki/ISO_8601 For linear policy, backoff delay is backoffDelay*<numberOfRetries>. For exponential policy, backoff delay is backoffDelay*2^<numberOfRetries>.'
type: string
backoffPolicy:
description: BackoffPolicy is the retry backoff policy (linear, exponential).
type: string
deadLetterSink:
description: DeadLetterSink is the sink receiving event that could not be sent to a destination.
type: object
properties:
ref:
description: Ref points to an Addressable.
type: object
properties:
apiVersion:
description: API version of the referent.
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ This is optional field, it gets defaulted to the object holding it if left out.'
type: string
uri:
description: URI can be an absolute URL(non-empty scheme and non-empty host) pointing to the target or a relative URI. Relative URIs will be resolved using the base URI retrieved from Ref.
type: string
CACerts:
description: Certification Authority (CA) certificates in PEM format that the source trusts when sending events to the sink.
type: string
audience:
description: Audience is the OIDC audience. This only needs to be set if the target is not an Addressable and thus the Audience can't be received from the target itself. If specified, it takes precedence over the target's Audience.
type: string
retry:
description: Retry is the minimum number of retries the sender should attempt when sending an event before moving it to the dead letter sink.
type: integer
format: int32
x-kubernetes-preserve-unknown-fields: true # This is necessary to enable the experimental feature delivery-timeout
status:
description: Status represents the current state of the RequestReply. This data may be out of date.
type: object
properties:
annotations:
description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.
type: object
x-kubernetes-preserve-unknown-fields: true
conditions:
description: Conditions the latest available observations of a resource's current state.
type: array
items:
type: object
required:
- type
- status
properties:
lastTransitionTime:
description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
severity:
description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition.
type: string
address:
description: RequestReply is Addressable. It exposes the endpoint as an URI to get events delivered.
type: object
properties:
name:
type: string
url:
type: string
CACerts:
type: string
audience:
type: string
addresses:
description: RequestReply is Addressable. It exposes the endpoints as URIs to get events delivered.
type: array
items:
type: object
properties:
name:
type: string
url:
type: string
CACerts:
type: string
audience:
type: string
policies:
description: List of applied EventPolicies
type: array
items:
type: object
properties:
apiVersion:
description: The API version of the applied EventPolicy. This indicates whichversion of EventPolicy is supported by the resource.
type: string
name:
description: The name of the applied EventPolicy
type: string
observedGeneration:
description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.
type: integer
format: int64
additionalPrinterColumns:
- name: URL
type: string
jsonPath: ".status.address.url"
- name: Ready
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].status"
- name: Reason
type: string
jsonPath: ".status.conditions[?(@.type==\"Ready\")].reason"
names:
kind: RequestReply
plural: requestreplies
singular: requestreply
categories:
- all
- knative
- eventing
scope: Namespaced
conversion:
strategy: Webhook
webhook:
conversionReviewVersions: ["v1", "v1beta1"]
clientConfig:
service:
name: eventing-webhook
namespace: knative-eventing

View File

@ -166,47 +166,3 @@ rules:
- get
- list
- watch
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: integrationsinks-addressable-resolver
labels:
duck.knative.dev/addressable: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
# Do not use this role directly. These rules will be added to the "addressable-resolver" role.
rules:
- apiGroups:
- sinks.knative.dev
resources:
- integrationsinks
- integrationsinks/status
verbs:
- get
- list
- watch
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: eventtransforms-addressable-resolver
labels:
duck.knative.dev/addressable: "true"
app.kubernetes.io/version: devel
app.kubernetes.io/name: knative-eventing
# Do not use this role directly. These rules will be added to the "addressable-resolver" role.
rules:
- apiGroups:
- eventing.knative.dev
resources:
- eventtransforms
- eventtransforms/status
verbs:
- get
- list
- watch

View File

@ -64,13 +64,11 @@ rules:
- "list"
- "watch"
# PingSource and EventTransform controllers manipulate Deployment and ConfigMap owner reference
# PingSource controller manipulates Deployment owner reference
- apiGroups:
- "apps"
- ""
resources:
- "deployments/finalizers"
- "configmaps/finalizers"
verbs:
- "update"
@ -101,8 +99,6 @@ rules:
- "eventtypes/status"
- "eventpolicies"
- "eventpolicies/status"
- "eventtransforms"
- "eventtransforms/status"
verbs:
- "get"
- "list"
@ -117,8 +113,6 @@ rules:
resources:
- "jobsinks"
- "jobsinks/status"
- "integrationsinks"
- "integrationsinks/status"
verbs:
- "get"
- "list"
@ -134,23 +128,6 @@ rules:
resources:
- "brokers/finalizers"
- "triggers/finalizers"
- "eventtransforms/finalizers"
verbs:
- "update"
# EventTransform controller manipulates SinkBinding owner reference
- apiGroups:
- "sources.knative.dev"
resources:
- "sinkbindings/finalizers"
verbs:
- "update"
# EventTransform controller manipulates Service owner reference
- apiGroups:
- ""
resources:
- "services/finalizers"
verbs:
- "update"
@ -158,7 +135,6 @@ rules:
- "sinks.knative.dev"
resources:
- "jobsinks/finalizers"
- "integrationsinks/finalizers"
verbs:
- "update"
@ -242,37 +218,3 @@ rules:
- "delete"
- "patch"
- "watch"
- apiGroups:
- "cert-manager.io"
resources:
- "certificates"
verbs:
- "get"
- "list"
- "create"
- "update"
- "delete"
- "patch"
- "watch"
# EventTransform controller manipulates Certificate owner reference
- apiGroups:
- "cert-manager.io"
resources:
- "certificates/finalizers"
verbs:
- "update"
- apiGroups:
- "acme.cert-manager.io"
resources:
- "challenges"
verbs:
- "get"
- "list"
- "create"
- "update"
- "delete"
- "patch"
- "watch"

View File

@ -45,7 +45,6 @@ rules:
- pingsources
- sinkbindings
- containersources
- integrationsources
verbs:
- get
- list

View File

@ -66,9 +66,6 @@ rules:
- "containersources"
- "containersources/status"
- "containersources/finalizers"
- "integrationsources"
- "integrationsources/status"
- "integrationsources/finalizers"
verbs:
- "get"
- "list"

View File

@ -16,6 +16,4 @@ limitations under the License.
// Package post_install is a placeholder that allows us to pull in config files
// via go mod vendor.
//
//nolint:staticcheck
package post_install

View File

@ -41,9 +41,6 @@ spec:
containers:
- name: migrate
image: ko://knative.dev/pkg/apiextensions/storageversion/cmd/migrate
env:
- name: IGNORE_NOT_FOUND
value: "true"
args:
- "apiserversources.sources.knative.dev"
- "brokers.eventing.knative.dev"
@ -58,9 +55,6 @@ spec:
- "subscriptions.messaging.knative.dev"
- "triggers.eventing.knative.dev"
- "jobsinks.sinks.knative.dev"
- "eventpolicies.eventing.knative.dev"
- "integrationsources.sources.knative.dev"
- "integrationsinks.sinks.knative.dev"
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ In the following the control plane components and their responsibilities are des
The `mt-broker-controller` is kind of the heart of the MTChannelBasedBroker control plane and has the following responsibilities:
* Watches for new `Broker` resources with the `eventing.knative.dev/broker.class: MTChannelBasedBroker` annotation (step 2 in the diagram) and creates a new _concrete_ channel resource (step 3 in the diagram) depending on the `channel-template-spec` from the configmap referenced in the `config-br-defaults` configmap (by default this points to `config-br-default-channel`).
* Watches for new `Broker` resources with the `eventing.kantive.dev/broker.class: MTChannelBasedBroker` annotation (step 2 in the diagram) and creates a new _concrete_ channel resource (step 3 in the diagram) depending on the `channel-template-spec` from the configmap referenced in the `config-br-defaults` configmap (by default this points to `config-br-default-channel`).
Be aware that in case the default `brokerClass` in `config-br-defaults` is not set to `MTChannelBasedBroker`, the referenced configmap still must contain a `channel-template-spec`. Otherwise the user needs to define the corresponding config on the broker resource directly when using the `MTChannelBasedBroker` broker class, e.g.:

134
go.mod
View File

@ -1,21 +1,21 @@
module knative.dev/eventing
go 1.24.0
go 1.22.0
require (
github.com/ahmetb/gen-crd-api-reference-docs v0.3.1-0.20210420163308-c1402a70e2f1
github.com/cert-manager/cert-manager v1.16.3
github.com/cloudevents/conformance v0.4.1
github.com/cloudevents/conformance v0.2.0
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2
github.com/cloudevents/sdk-go/protocol/mqtt_paho/v2 v2.0.0-20240508060731-1ed9471c98bd
github.com/cloudevents/sdk-go/sql/v2 v2.0.0-20240712172937-3ce6b2f1f011
github.com/cloudevents/sdk-go/v2 v2.15.2
github.com/coreos/go-oidc/v3 v3.9.0
github.com/eclipse/paho.golang v0.12.0
github.com/go-jose/go-jose/v3 v3.0.4
github.com/google/go-cmp v0.7.0
github.com/go-jose/go-jose/v3 v3.0.3
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/gorilla/websocket v1.5.1
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/hashicorp/golang-lru v1.0.2
@ -27,32 +27,27 @@ require (
github.com/pkg/errors v0.9.1
github.com/rickb777/date v1.13.0
github.com/robfig/cron/v3 v3.0.1
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.9.0
github.com/wavesoftware/go-ensure v1.0.0
go.opencensus.io v0.24.0
go.opentelemetry.io/contrib/instrumentation/runtime v0.62.0
go.opentelemetry.io/otel v1.37.0
go.opentelemetry.io/otel/sdk v1.37.0
go.opentelemetry.io/otel/sdk/metric v1.37.0
go.opentelemetry.io/otel/trace v1.37.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/atomic v1.10.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.41.0
golang.org/x/sync v0.15.0
k8s.io/api v0.33.1
k8s.io/apiextensions-apiserver v0.33.1
k8s.io/apimachinery v0.33.1
k8s.io/apiserver v0.33.1
k8s.io/client-go v0.33.1
k8s.io/code-generator v0.33.1
k8s.io/utils v0.0.0-20241210054802-24370beab758
knative.dev/hack v0.0.0-20250708013849-70d4b00da6ba
knative.dev/hack/schema v0.0.0-20250708013849-70d4b00da6ba
knative.dev/pkg v0.0.0-20250708013613-d3550d4350f9
knative.dev/reconciler-test v0.0.0-20250708152404-d97d9007b8d3
sigs.k8s.io/randfill v1.0.0
sigs.k8s.io/yaml v1.5.0
golang.org/x/net v0.30.0
golang.org/x/sync v0.8.0
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver v0.30.3
k8s.io/apimachinery v0.30.3
k8s.io/apiserver v0.30.3
k8s.io/client-go v0.30.3
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
knative.dev/hack v0.0.0-20250220110655-b5e4ff820460
knative.dev/hack/schema v0.0.0-20250220110655-b5e4ff820460
knative.dev/pkg v0.0.0-20241021183759-9b9d535af5ad
knative.dev/reconciler-test v0.0.0-20250217113355-f4bd4f5199d4
sigs.k8s.io/yaml v1.4.0
)
require (
@ -63,19 +58,15 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
@ -83,64 +74,51 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/statsd_exporter v0.22.7 // indirect
github.com/rickb777/plural v1.2.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/tools v0.34.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/api v0.198.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.26.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.183.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/code-generator v0.30.3 // indirect
k8s.io/gengo v0.0.0-20240404160639-a0386bf69313 // indirect
k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 // indirect
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
k8s.io/klog v1.0.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
sigs.k8s.io/gateway-api v1.1.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)

604
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -20,8 +20,8 @@ set -o nounset
set -o pipefail
CLUSTER_SUFFIX=${CLUSTER_SUFFIX:-"cluster.local"}
NODE_VERSION=${NODE_VERSION:-"v1.31.4"}
NODE_SHA=${NODE_SHA:-"sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30"}
NODE_VERSION=${NODE_VERSION:-"v1.28.7"}
NODE_SHA=${NODE_SHA:-"sha256:9bc6c451a289cf96ad0bbaf33d416901de6fd632415b076ab05f5fa7e4f65c58"}
cat <<EOF | kind create cluster --config=-
apiVersion: kind.x-k8s.io/v1alpha4

View File

@ -17,50 +17,9 @@
# Documentation about this script and how to use it can be found
# at https://github.com/knative/test-infra/tree/main/ci
source "$(dirname "${BASH_SOURCE[0]}")/../vendor/knative.dev/hack/release.sh"
KNATIVE_EVENTING_INTEGRATIONS_IMAGES_RELEASE="$(get_latest_knative_yaml_source "eventing-integrations" "eventing-integrations-images")"
readonly KNATIVE_EVENTING_INTEGRATIONS_IMAGES_RELEASE
KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_RELEASE="$(get_latest_knative_yaml_source "eventing-integrations" "eventing-transformations-images")"
readonly KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_RELEASE
readonly KNATIVE_EVENTING_INTEGRATIONS_IMAGES_CM="${REPO_ROOT_DIR}/third_party/eventing-integrations-latest/eventing-integrations-images.yaml"
readonly KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_CM="${REPO_ROOT_DIR}/third_party/eventing-integrations-latest/eventing-transformations-images.yaml"
function update_eventing_integrations_release_cms() {
curl "${KNATIVE_EVENTING_INTEGRATIONS_IMAGES_RELEASE}" --create-dirs -o "${KNATIVE_EVENTING_INTEGRATIONS_IMAGES_CM}" || return $?
curl "${KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_RELEASE}" --create-dirs -o "${KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_CM}" || return $?
}
function check_knative_nightly() {
local files=(
"${KNATIVE_EVENTING_INTEGRATIONS_IMAGES_CM}"
"${KNATIVE_EVENTING_TRANSFORMATIONS_IMAGES_CM}"
"${REPO_ROOT_DIR}/config/core/configmaps/eventing-integrations-images.yaml"
"${REPO_ROOT_DIR}/config/core/configmaps/eventing-transformations-images.yaml"
"${REPO_ROOT_DIR}/config/400-config-eventing-integrations-images.yaml"
"${REPO_ROOT_DIR}/config/400-config-eventing-transformations-images.yaml"
)
for file in "${files[@]}"; do
if grep -q "knative-nightly" "$file"; then
echo "Error: Found 'knative-nightly' in $file, is eventing-integrations for this major and minor '${TAG}' version already released? https://github.com/knative-extensions/eventing-integrations/releases"
cat "${file}"
return 1
fi
done
echo "No 'knative-nightly' occurrences found."
}
source $(dirname $0)/../vendor/knative.dev/hack/release.sh
function build_release() {
if (( PUBLISH_TO_GITHUB )); then
# For official releases, update eventing-integrations ConfigMaps and stop the release if a nightly image is found
# in the ConfigMaps.
update_eventing_integrations_release_cms || return $?
check_knative_nightly || return $?
fi
# Run `generate-yamls.sh`, which should be versioned with the
# branch since the detail of building may change over time.
local YAML_LIST="$(mktemp)"

View File

@ -36,7 +36,4 @@ import (
// API reference docs generation.
_ "github.com/ahmetb/gen-crd-api-reference-docs"
_ "github.com/ahmetb/gen-crd-api-reference-docs/template"
// K8s code generation tools
_ "k8s.io/code-generator/cmd/validation-gen"
)

View File

@ -24,4 +24,4 @@ EOF
helm template -n cert-manager cert-manager jetstack/trust-manager --create-namespace --version "${trust_manager_version}" --set crds.enabled=true > third_party/cert-manager/02-trust-manager.yaml
}
update_cert_manager "v1.16.3" "v0.12.0"
update_cert_manager "v1.13.3" "v0.12.0"

View File

@ -49,14 +49,7 @@ group "Knative Codegen"
# Knative Injection
${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \
knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \
"sinks:v1alpha1 eventing:v1alpha1 eventing:v1beta1 eventing:v1beta2 eventing:v1beta3 eventing:v1 messaging:v1 flows:v1 sources:v1alpha1 sources:v1beta2 sources:v1 duck:v1beta1 duck:v1" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt
# Knative Injection (for cert-manager)
OUTPUT_PKG="knative.dev/eventing/pkg/client/certmanager/injection" \
${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \
github.com/cert-manager/cert-manager/pkg/client github.com/cert-manager/cert-manager/pkg/apis "certmanager:v1 acme:v1" \
--disable-informer-init \
"sinks:v1alpha1 eventing:v1alpha1 eventing:v1beta1 eventing:v1beta2 eventing:v1beta3 eventing:v1 messaging:v1 flows:v1 sources:v1beta2 sources:v1 duck:v1beta1 duck:v1" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt
group "Generating API reference docs"

View File

@ -19,6 +19,7 @@ package apiserver
import (
"context"
"fmt"
"net/http"
"time"
cloudevents "github.com/cloudevents/sdk-go/v2"
@ -125,8 +126,20 @@ func (a *apiServerAdapter) start(ctx context.Context, stopCh <-chan struct{}) er
}
}
srv := &http.Server{
Addr: ":8080",
// Configure read header timeout to overcome potential Slowloris Attack because ReadHeaderTimeout is not
// configured in the http.Server.
ReadHeaderTimeout: 10 * time.Second,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}),
}
go srv.ListenAndServe()
<-stopCh
close(stop)
stop <- struct{}{}
srv.Shutdown(ctx)
return nil
}

View File

@ -20,7 +20,6 @@ import (
"bytes"
"context"
"encoding/base64"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
@ -214,8 +213,8 @@ func TestSendEventsTLS(t *testing.T) {
eventsChan := make(chan cloudevents.Event, 10)
handler := eventingtlstesting.EventChannelHandler(eventsChan)
events := make([]cloudevents.Event, 0, 8)
ca, port := eventingtlstesting.StartServer(ctx, t, 0, handler)
hostString := fmt.Sprintf("localhost:%d", port)
ca := eventingtlstesting.StartServer(ctx, t, 8500, handler)
hostString := "localhost:8500"
var wg sync.WaitGroup
wg.Add(1)

View File

@ -18,7 +18,6 @@ package adapter
import (
"context"
"fmt"
nethttp "net/http"
"os"
"strconv"
@ -310,7 +309,7 @@ func TestTLS(t *testing.T) {
ctx, cancel := context.WithCancel(ctx)
t.Cleanup(cancel)
ca, port := eventingtlstesting.StartServer(ctx, t, 0, nethttp.HandlerFunc(func(writer nethttp.ResponseWriter, request *nethttp.Request) {
ca := eventingtlstesting.StartServer(ctx, t, 8333, nethttp.HandlerFunc(func(writer nethttp.ResponseWriter, request *nethttp.Request) {
if request.TLS == nil {
// It's not on TLS, fail request
writer.WriteHeader(nethttp.StatusInternalServerError)
@ -329,17 +328,17 @@ func TestTLS(t *testing.T) {
}{
{
name: "https sink URL, no CA certs fail",
sink: fmt.Sprintf("https://localhost:%d", port),
sink: "https://localhost:8333",
wantErr: true,
},
{
name: "https sink URL with ca certs",
sink: fmt.Sprintf("https://localhost:%d", port),
sink: "https://localhost:8333",
caCerts: pointer.String(ca),
},
{
name: "http sink URL with ca certs",
sink: fmt.Sprintf("http://localhost:%d", port),
sink: "http://localhost:8333",
caCerts: pointer.String(ca),
wantErr: true,
},

View File

@ -124,14 +124,3 @@ func ConfiguratorOptionsFromContext(ctx context.Context) []ConfiguratorOption {
}
return value.([]ConfiguratorOption)
}
type healthProbesDisabledKey struct{}
// WithHealthProbesDisabled signals to MainWithContext that it should disable default probes (readiness and liveness).
func WithHealthProbesDisabled(ctx context.Context) context.Context {
return context.WithValue(ctx, healthProbesDisabledKey{}, struct{}{})
}
func HealthProbesDisabled(ctx context.Context) bool {
return ctx.Value(healthProbesDisabledKey{}) != nil
}

View File

@ -306,14 +306,6 @@ func MainWithInformers(ctx context.Context, component string, env EnvConfigAcces
}()
}
if !HealthProbesDisabled(ctx) {
wg.Add(1)
go func() {
defer wg.Done()
injection.ServeHealthProbes(ctx, injection.HealthCheckDefaultPort)
}()
}
// Finally start the adapter (blocking)
if err := adapter.Start(ctx); err != nil {
logger.Fatalw("Start returned an error", zap.Error(err))

View File

@ -67,7 +67,6 @@ func TestMainWithContext(t *testing.T) {
}()
ctx := context.TODO()
ctx = WithHealthProbesDisabled(ctx)
ctx, _ = fakekubeclient.With(ctx)
MainWithContext(ctx, "mycomponent",

View File

@ -13,7 +13,6 @@ 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 test
import (

View File

@ -74,9 +74,7 @@ func UpdateFromConfigMap(client *CRStatusEventClient) func(configMap *corev1.Con
}
}
type contextkeytype struct{}
var contextkey contextkeytype
var contextkey struct{}
func ContextWithCRStatus(ctx context.Context, kubeEventSink *record.EventSink, component string, source runtime.Object, logf func(format string, args ...interface{})) context.Context {
@ -146,7 +144,7 @@ func (a *crStatusEvent) createEvent(ctx context.Context, result protocol.Result)
reason = strconv.Itoa(res.StatusCode)
if res.Format != "" && res.Format != "%w" { // returns '"%w" but this does not format
msg += " " + fmt.Sprintf(res.Format, res.Args...)
} else if len(res.Args) > 0 {
} else if res.Args != nil && len(res.Args) > 0 {
if m, ok := res.Args[0].(*protocol.Receipt); ok {
if m.Err != nil {
msg += " " + m.Err.Error() // add any error message if it's there.

View File

@ -1,43 +0,0 @@
/*
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 v1alpha1
type Auth struct {
// Auth Secret
Secret *Secret `json:"secret,omitempty"`
// AccessKey is the AWS access key ID.
AccessKey string `json:"accessKey,omitempty"`
// SecretKey is the AWS secret access key.
SecretKey string `json:"secretKey,omitempty"`
}
func (a *Auth) HasAuth() bool {
return a != nil && a.Secret != nil &&
a.Secret.Ref != nil && a.Secret.Ref.Name != ""
}
type Secret struct {
// Secret reference for SASL and SSL configurations.
Ref *SecretReference `json:"ref,omitempty"`
}
type SecretReference struct {
// Secret name.
Name string `json:"name"`
}

View File

@ -1,76 +0,0 @@
/*
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 v1alpha1
const (
// AwsAccessKey is the name of the expected key on the secret for accessing the actual AWS access key value.
AwsAccessKey = "aws.accessKey"
// AwsSecretKey is the name of the expected key on the secret for accessing the actual AWS secret key value.
AwsSecretKey = "aws.secretKey"
)
type AWSCommon struct {
// Auth is the S3 authentication (accessKey/secretKey) configuration.
Region string `json:"region,omitempty"` // AWS region
URIEndpointOverride string `json:"uriEndpointOverride,omitempty"` // Override endpoint URI
OverrideEndpoint bool `json:"overrideEndpoint" default:"false"` // Override endpoint flag
}
type AWSS3 struct {
AWSCommon `json:",inline"` // Embeds AWSCommon to inherit its fields in JSON
Arn string `json:"arn,omitempty" camel:"BUCKET_NAME_OR_ARN"` // S3 ARN
DeleteAfterRead bool `json:"deleteAfterRead" default:"true"` // Auto-delete objects after reading
MoveAfterRead bool `json:"moveAfterRead" default:"false"` // Move objects after reading
DestinationBucket string `json:"destinationBucket,omitempty"` // Destination bucket for moved objects
DestinationBucketPrefix string `json:"destinationBucketPrefix,omitempty"` // Prefix for moved objects
DestinationBucketSuffix string `json:"destinationBucketSuffix,omitempty"` // Suffix for moved objects
AutoCreateBucket bool `json:"autoCreateBucket" default:"false"` // Auto-create S3 bucket
Prefix string `json:"prefix,omitempty"` // S3 bucket prefix for search
IgnoreBody bool `json:"ignoreBody" default:"false"` // Ignore object body
ForcePathStyle bool `json:"forcePathStyle" default:"false"` // Force path style for bucket access
Delay int `json:"delay" default:"500"` // Delay between polls in milliseconds
MaxMessagesPerPoll int `json:"maxMessagesPerPoll" default:"10"` // Max messages to poll per request
}
type AWSSQS struct {
AWSCommon `json:",inline"` // Embeds AWSCommon to inherit its fields in JSON
Arn string `json:"arn,omitempty" camel:"QUEUE_NAME_OR_ARN"` // SQS ARN
DeleteAfterRead bool `json:"deleteAfterRead" default:"true"` // Auto-delete messages after reading
AutoCreateQueue bool `json:"autoCreateQueue" default:"false"` // Auto-create SQS queue
Host string `json:"host" camel:"AMAZONAWSHOST" default:"amazonaws.com"` // AWS host
Protocol string `json:"protocol" default:"https"` // Communication protocol (http/https)
QueueURL string `json:"queueURL,omitempty"` // Full SQS queue URL
Greedy bool `json:"greedy" default:"false"` // Greedy scheduler
Delay int `json:"delay" default:"500"` // Delay between polls in milliseconds
MaxMessagesPerPoll int `json:"maxMessagesPerPoll" default:"1"` // Max messages to return (1-10)
WaitTimeSeconds int `json:"waitTimeSeconds,omitempty"` // Wait time for messages
VisibilityTimeout int `json:"visibilityTimeout,omitempty"` // Visibility timeout in seconds
}
type AWSDDBStreams struct {
AWSCommon `json:",inline"` // Embeds AWSCommon to inherit its fields in JSON
Table string `json:"table,omitempty"` // The name of the DynamoDB table
StreamIteratorType string `json:"streamIteratorType,omitempty" default:"FROM_LATEST"` // Defines where in the DynamoDB stream to start getting records
Delay int `json:"delay,omitempty" default:"500"` // Delay in milliseconds before the next poll from the database
}
type AWSSNS struct {
AWSCommon `json:",inline"` // Embeds AWSCommon to inherit its fields in JSON
Arn string `json:"arn,omitempty" camel:"TOPIC_NAME_OR_ARN"` // SNS ARN
AutoCreateTopic bool `json:"autoCreateTopic" default:"false"` // Auto-create SNS topic
}

View File

@ -1,19 +0,0 @@
/*
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.
*/
// +k8s:deepcopy-gen=package
package v1alpha1

View File

@ -1,164 +0,0 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2021 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSCommon) DeepCopyInto(out *AWSCommon) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSCommon.
func (in *AWSCommon) DeepCopy() *AWSCommon {
if in == nil {
return nil
}
out := new(AWSCommon)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSDDBStreams) DeepCopyInto(out *AWSDDBStreams) {
*out = *in
out.AWSCommon = in.AWSCommon
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSDDBStreams.
func (in *AWSDDBStreams) DeepCopy() *AWSDDBStreams {
if in == nil {
return nil
}
out := new(AWSDDBStreams)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSS3) DeepCopyInto(out *AWSS3) {
*out = *in
out.AWSCommon = in.AWSCommon
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSS3.
func (in *AWSS3) DeepCopy() *AWSS3 {
if in == nil {
return nil
}
out := new(AWSS3)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSSNS) DeepCopyInto(out *AWSSNS) {
*out = *in
out.AWSCommon = in.AWSCommon
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSSNS.
func (in *AWSSNS) DeepCopy() *AWSSNS {
if in == nil {
return nil
}
out := new(AWSSNS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AWSSQS) DeepCopyInto(out *AWSSQS) {
*out = *in
out.AWSCommon = in.AWSCommon
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSSQS.
func (in *AWSSQS) DeepCopy() *AWSSQS {
if in == nil {
return nil
}
out := new(AWSSQS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Auth) DeepCopyInto(out *Auth) {
*out = *in
if in.Secret != nil {
in, out := &in.Secret, &out.Secret
*out = new(Secret)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth.
func (in *Auth) DeepCopy() *Auth {
if in == nil {
return nil
}
out := new(Auth)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Secret) DeepCopyInto(out *Secret) {
*out = *in
if in.Ref != nil {
in, out := &in.Ref, &out.Ref
*out = new(SecretReference)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret.
func (in *Secret) DeepCopy() *Secret {
if in == nil {
return nil
}
out := new(Secret)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretReference) DeepCopyInto(out *SecretReference) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference.
func (in *SecretReference) DeepCopy() *SecretReference {
if in == nil {
return nil
}
out := new(SecretReference)
in.DeepCopyInto(out)
return out
}

View File

@ -138,7 +138,7 @@ func (c *Channelable) Populate() {
}
// GetFullType implements duck.Implementable
func (c *Channelable) GetFullType() duck.Populatable {
func (s *Channelable) GetFullType() duck.Populatable {
return &Channelable{}
}

View File

@ -41,11 +41,8 @@ func TestDeliverySpecConversionBadType(t *testing.T) {
// Test v1beta1 -> v1 -> v1beta1
func TestDeliverySpecConversion(t *testing.T) {
var retryCount int32 = 10
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicy BackoffPolicyType = BackoffPolicyLinear
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicyExp BackoffPolicyType = BackoffPolicyExponential
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicyBad BackoffPolicyType = "garbage"
badPolicyString := `unknown BackoffPolicy, got: "garbage"`
@ -121,11 +118,8 @@ func TestDeliverySpecConversion(t *testing.T) {
// Test v1 -> v1beta1 -> v1
func TestDeliverySpecConversionV1(t *testing.T) {
var retryCount int32 = 10
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicy v1.BackoffPolicyType = v1.BackoffPolicyLinear
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicyExp v1.BackoffPolicyType = v1.BackoffPolicyExponential
//nolint:staticcheck // ST1023 types can be inferred
var backoffPolicyBad v1.BackoffPolicyType = "garbage"
badPolicyString := `unknown BackoffPolicy, got: "garbage"`

View File

@ -19,8 +19,8 @@ package v1
import (
"testing"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/runtime/serializer"
"sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/runtime"
@ -36,8 +36,8 @@ import (
var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
func(codecs serializer.CodecFactory) []interface{} {
return []interface{}{
func(s *TriggerStatus, c randfill.Continue) {
c.FillNoCustom(s) // fuzz the status object
func(s *TriggerStatus, c fuzz.Continue) {
c.FuzzNoCustom(s) // fuzz the status object
// Clear the random fuzzed condition
s.Status.SetConditions(nil)
@ -46,8 +46,8 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
s.InitializeConditions()
pkgfuzzer.FuzzConditions(&s.Status, c)
},
func(s *BrokerStatus, c randfill.Continue) {
c.FillNoCustom(s) // fuzz the status object
func(s *BrokerStatus, c fuzz.Continue) {
c.FuzzNoCustom(s) // fuzz the status object
// Clear the random fuzzed condition
s.Status.SetConditions(nil)

View File

@ -1,24 +0,0 @@
/*
Copyright 2025 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 v1alpha1
import (
"context"
)
func (t *EventTransform) SetDefaults(_ context.Context) {
}

View File

@ -1,213 +0,0 @@
/*
Copyright 2025 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 v1alpha1
import (
cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
appsv1 "k8s.io/api/apps/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1"
)
const (
TransformConditionAddressable apis.ConditionType = "Addressable"
TransformationConditionReady apis.ConditionType = "TransformationReady"
TransformationAddressableEmptyURL string = "NoURL"
TransformationAddressableWaitingForServiceEndpoints string = "WaitingForServiceEndpoints"
// Specific transformations conditions
// TransformationJsonataDeploymentReady is the condition to indicate that the Jsonata deployment
// is ready.
TransformationJsonataDeploymentReady apis.ConditionType = "JsonataDeploymentReady"
TransformationJsonataDeploymentUnavailable string = "JsonataDeploymentUnavailable"
TransformationJsonataCertificateNotReady string = "JsonataCertificateNotReady"
// TransformationJsonataSinkBindingReady is the condition to indicate that the Jsonata sink
// binding is ready.
TransformationJsonataSinkBindingReady apis.ConditionType = "JsonataSinkBindingReady"
)
var TransformCondSet = apis.NewLivingConditionSet(
TransformationConditionReady,
TransformConditionAddressable,
)
// transformJsonataConditionSet is the subset of conditions for the Jsonata transformation
// The overall readiness of those conditions will be propagated to the top-level
// TransformationConditionReady condition.
var transformJsonataConditionSet = apis.NewLivingConditionSet(
TransformationJsonataDeploymentReady,
TransformationJsonataSinkBindingReady,
)
// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface.
func (et *EventTransform) GetConditionSet() apis.ConditionSet {
if et == nil {
return TransformCondSet
}
return et.Status.GetConditionSet()
}
func (*EventTransformStatus) GetConditionSet() apis.ConditionSet {
return TransformCondSet
}
// GetCondition returns the condition cutsently associated with the given type, or nil.
func (ts *EventTransformStatus) GetCondition(t apis.ConditionType) *apis.Condition {
return ts.GetConditionSet().Manage(ts).GetCondition(t)
}
// IsReady returns true if the resource is ready overall.
func (ts *EventTransformStatus) IsReady() bool {
return ts.GetTopLevelCondition().IsTrue()
}
// GetTopLevelCondition returns the top level Condition.
func (ts *EventTransformStatus) GetTopLevelCondition() *apis.Condition {
return ts.GetConditionSet().Manage(ts).GetTopLevelCondition()
}
// InitializeConditions sets relevant unset conditions to Unknown state.
func (ts *EventTransformStatus) InitializeConditions() {
ts.GetConditionSet().Manage(ts).InitializeConditions()
}
func (ts *EventTransformStatus) PropagateJsonataDeploymentStatus(ds appsv1.DeploymentStatus) bool {
defer ts.propagateTransformJsonataReadiness()
if ts.JsonataTransformationStatus == nil {
ts.JsonataTransformationStatus = &JsonataEventTransformationStatus{}
}
ts.JsonataTransformationStatus.Deployment = ds
if ds.Replicas > 0 && ds.Replicas == ds.AvailableReplicas {
transformJsonataConditionSet.Manage(ts).MarkTrue(TransformationJsonataDeploymentReady)
return true
}
transformJsonataConditionSet.Manage(ts).MarkFalse(TransformationJsonataDeploymentReady, TransformationJsonataDeploymentUnavailable, "Expected replicas: %d, available: %d", ds.Replicas, ds.AvailableReplicas)
return false
}
func (ts *EventTransformStatus) PropagateJsonataCertificateStatus(cs cmv1.CertificateStatus) bool {
defer ts.propagateTransformJsonataReadiness()
var topLevel *cmv1.CertificateCondition
for _, cond := range cs.Conditions {
if cond.Type == cmv1.CertificateConditionReady {
topLevel = &cond
break
}
}
if topLevel == nil {
transformJsonataConditionSet.Manage(ts).MarkUnknown(TransformationJsonataDeploymentReady, TransformationJsonataCertificateNotReady, "Certificate is progressing")
return false
}
if topLevel.Status == cmmeta.ConditionUnknown {
transformJsonataConditionSet.Manage(ts).MarkUnknown(TransformationJsonataDeploymentReady, TransformationJsonataCertificateNotReady, "Certificate is progressing, "+topLevel.Reason+" Message: "+topLevel.Message)
return false
}
if topLevel.Status == cmmeta.ConditionFalse {
transformJsonataConditionSet.Manage(ts).MarkFalse(TransformationJsonataDeploymentReady, TransformationJsonataCertificateNotReady, "Certificate is not ready, "+topLevel.Reason+" Message: "+topLevel.Message)
return false
}
return true
}
func (ts *EventTransformStatus) PropagateJsonataSinkBindingUnset() {
defer ts.propagateTransformJsonataReadiness()
transformJsonataConditionSet.Manage(ts).MarkTrue(TransformationJsonataSinkBindingReady)
}
func (ts *EventTransformStatus) PropagateJsonataSinkBindingStatus(sbs sourcesv1.SinkBindingStatus) bool {
defer ts.propagateTransformJsonataReadiness()
if ts.JsonataTransformationStatus == nil {
ts.JsonataTransformationStatus = &JsonataEventTransformationStatus{}
}
ts.SourceStatus.SinkURI = sbs.SinkURI
ts.SourceStatus.SinkAudience = sbs.SinkAudience
ts.SourceStatus.SinkCACerts = sbs.SinkCACerts
ts.SourceStatus.Auth = sbs.Auth
topLevel := sbs.GetCondition(apis.ConditionReady)
if topLevel == nil {
transformJsonataConditionSet.Manage(ts).MarkUnknown(TransformationJsonataSinkBindingReady, "", "")
return false
}
if topLevel.IsTrue() {
transformJsonataConditionSet.Manage(ts).MarkTrue(TransformationJsonataSinkBindingReady)
return true
}
if topLevel.IsFalse() {
transformJsonataConditionSet.Manage(ts).MarkFalse(TransformationJsonataSinkBindingReady, topLevel.Reason, topLevel.Message)
return false
}
transformJsonataConditionSet.Manage(ts).MarkUnknown(TransformationJsonataSinkBindingReady, topLevel.Reason, topLevel.Message)
return false
}
func (ts *EventTransformStatus) propagateTransformJsonataReadiness() {
ts.markTransformReady(transformJsonataConditionSet)
}
func (ts *EventTransformStatus) markTransformReady(set apis.ConditionSet) {
dCond := set.Manage(ts).GetCondition(TransformationJsonataDeploymentReady)
sbCond := set.Manage(ts).GetCondition(TransformationJsonataSinkBindingReady)
if !dCond.IsTrue() {
ts.propagateTransformationConditionStatus(dCond)
return
}
if !sbCond.IsTrue() {
ts.propagateTransformationConditionStatus(sbCond)
return
}
ts.propagateTransformationConditionStatus(sbCond)
ts.propagateTransformationConditionStatus(dCond)
}
func (ts *EventTransformStatus) propagateTransformationConditionStatus(cond *apis.Condition) {
if cond == nil {
ts.GetConditionSet().Manage(ts).MarkUnknown(TransformationConditionReady, "", "")
} else if cond.IsTrue() {
ts.GetConditionSet().Manage(ts).MarkTrue(TransformationConditionReady)
} else if cond.IsFalse() {
ts.GetConditionSet().Manage(ts).MarkFalse(TransformationConditionReady, cond.Reason, cond.Message)
} else {
ts.GetConditionSet().Manage(ts).MarkUnknown(TransformationConditionReady, cond.Reason, cond.Message)
}
}
func (ts *EventTransformStatus) MarkWaitingForServiceEndpoints() {
ts.GetConditionSet().Manage(ts).MarkFalse(TransformConditionAddressable, TransformationAddressableWaitingForServiceEndpoints, "URL is empty")
}
func (ts *EventTransformStatus) IsTransformationReady() bool {
return ts.GetConditionSet().Manage(ts).GetCondition(TransformationConditionReady).IsTrue()
}
func (ts *EventTransformStatus) SetAddresses(addresses ...duckv1.Addressable) {
if len(addresses) == 0 || addresses[0].URL.IsEmpty() {
ts.GetConditionSet().Manage(ts).MarkFalse(TransformConditionAddressable, TransformationAddressableEmptyURL, "URL is empty")
return
}
ts.AddressStatus = duckv1.AddressStatus{
Address: &addresses[0],
Addresses: addresses,
}
ts.GetConditionSet().Manage(ts).MarkTrue(TransformConditionAddressable)
}

View File

@ -1,104 +0,0 @@
/*
Copyright 2025 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 v1alpha1
import (
"testing"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
func TestFullLifecycle(t *testing.T) {
et := &EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{},
Spec: EventTransformSpec{
Sink: nil,
EventTransformations: EventTransformations{
Jsonata: &JsonataEventTransformationSpec{
Expression: `
{
"specversion": "1.0",
"id": id,
"type": "transformed-event",
"source": source,
"reason": data.reason,
"message": data.message,
"data": $
}
`,
},
},
},
}
et.Status.InitializeConditions()
topLevel := et.Status.GetCondition(apis.ConditionReady)
transformation := et.Status.GetCondition(TransformationConditionReady)
addressable := et.Status.GetCondition(TransformConditionAddressable)
assert.Equal(t, corev1.ConditionUnknown, topLevel.Status)
assert.Equal(t, corev1.ConditionUnknown, transformation.Status)
assert.Equal(t, corev1.ConditionUnknown, addressable.Status)
assert.Len(t, et.Status.Conditions, 3)
assert.Equal(t, false, et.Status.IsReady())
ds := appsv1.DeploymentStatus{
ObservedGeneration: 202,
Replicas: 1,
UpdatedReplicas: 1,
ReadyReplicas: 1,
AvailableReplicas: 1,
UnavailableReplicas: 0,
}
et.Status.PropagateJsonataDeploymentStatus(ds)
deploymentCondition := et.Status.GetCondition(TransformationJsonataDeploymentReady)
assert.Equal(t, corev1.ConditionTrue, deploymentCondition.Status)
assert.Len(t, et.Status.Conditions, 4)
assert.Equal(t, false, et.Status.IsReady())
transformationCondition := et.Status.GetCondition(TransformationConditionReady)
assert.Equal(t, corev1.ConditionUnknown, transformationCondition.Status, et)
assert.Len(t, et.Status.Conditions, 4)
assert.Equal(t, false, et.Status.IsReady())
et.Status.PropagateJsonataSinkBindingUnset()
transformationCondition = et.Status.GetCondition(TransformationConditionReady)
assert.Equal(t, corev1.ConditionTrue, transformationCondition.Status, et)
assert.Len(t, et.Status.Conditions, 5)
assert.Equal(t, false, et.Status.IsReady())
et.Status.SetAddresses(duckv1.Addressable{URL: apis.HTTPS("example.com")})
addrCondition := et.Status.GetCondition(TransformConditionAddressable)
assert.Equal(t, corev1.ConditionTrue, addrCondition.Status, et)
assert.Len(t, et.Status.Conditions, 5)
assert.Equal(t, true, et.Status.IsReady())
// All conditions are ready
for _, c := range et.Status.Conditions {
assert.Equal(t, true, c.IsTrue(), "Unexpected condition status %#v, expected True", c)
}
}

View File

@ -1,165 +0,0 @@
/*
Copyright 2025 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 v1alpha1
import (
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/kmeta"
)
// +genclient
// +genreconciler
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// EventTransform represents an even transformation.
type EventTransform struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec defines the desired state of the EventTransform.
Spec EventTransformSpec `json:"spec,omitempty"`
// Status represents the current state of the EventTransform.
// This data may be out of date.
// +optional
Status EventTransformStatus `json:"status,omitempty"`
}
var (
// Check that EventTransform can be validated, can be defaulted, and has immutable fields.
_ apis.Validatable = (*EventTransform)(nil)
_ apis.Defaultable = (*EventTransform)(nil)
// Check that EventTransform can return its spec untyped.
_ apis.HasSpec = (*EventTransform)(nil)
_ runtime.Object = (*EventTransform)(nil)
// Check that we can create OwnerReferences to an EventTransform.
_ kmeta.OwnerRefable = (*EventTransform)(nil)
// Check that the type conforms to the duck Knative Resource shape.
_ duckv1.KRShaped = (*EventTransform)(nil)
)
type EventTransformSpec struct {
// Sink is a reference to an object that will resolve to a uri to use as the sink.
//
// If not present, the transformation will send back the transformed event as response, this
// is useful to leverage the built-in Broker reply feature to re-publish a transformed event
// back to the broker.
//
// +optional
Sink *duckv1.Destination `json:"sink,omitempty"`
// Reply is the configuration on how to handle responses from Sink.
// It can only be set if Sink is set.
//
// +optional
Reply *ReplySpec `json:"reply,omitempty"`
// EventTransformations contain all possible transformations, only one "type" can be used.
EventTransformations `json:",inline"`
}
// ReplySpec is the configurations on how to handle responses from Sink.
type ReplySpec struct {
// EventTransformations for replies from the Sink, contain all possible transformations,
// only one "type" can be used.
//
// The used type must match the top-level transformation, if you need to mix transformation types,
// use compositions and chain transformations together to achieve your desired outcome.
EventTransformations `json:",inline"`
// Discard discards responses from Sink and return empty response body.
//
// When set to false, it returns the exact sink response body.
// When set to true, Discard is mutually exclusive with EventTransformations in the reply
// section, it can either be discarded or transformed.
//
// Default: false.
//
// +optional
Discard *bool `json:"discard,omitempty"`
}
type EventTransformations struct {
Jsonata *JsonataEventTransformationSpec `json:"jsonata,omitempty"`
}
type JsonataEventTransformationSpec struct {
// Expression is the JSONata expression.
Expression string `json:"expression,omitempty"`
}
// EventTransformStatus represents the current state of a EventTransform.
type EventTransformStatus struct {
// SourceStatus inherits duck/v1 SourceStatus, which currently provides:
// * ObservedGeneration - the 'Generation' of the Service that was last
// processed by the controller.
// * Conditions - the latest available observations of a resource's current
// state.
// * SinkURI - the current active sink URI that has been configured for the
// Source.
duckv1.SourceStatus `json:",inline"`
// AddressStatus is the part where the EventTransform fulfills the Addressable contract.
// It exposes the endpoint as an URI to get events delivered.
// +optional
duckv1.AddressStatus `json:",inline"`
// JsonataTransformationStatus is the status associated with JsonataEventTransformationSpec.
// +optional
JsonataTransformationStatus *JsonataEventTransformationStatus `json:"jsonata,omitempty"`
}
type JsonataEventTransformationStatus struct {
Deployment appsv1.DeploymentStatus `json:"deployment,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// EventTransformList is a collection of EventTransform.
type EventTransformList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []EventTransform `json:"items"`
}
// GetGroupVersionKind returns GroupVersionKind for EventTransform
func (ep *EventTransform) GetGroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind("EventTransform")
}
// GetUntypedSpec returns the spec of the EventTransform.
func (ep *EventTransform) GetUntypedSpec() interface{} {
return ep.Spec
}
// GetStatus retrieves the status of the EventTransform. Implements the KRShaped interface.
func (ep *EventTransform) GetStatus() *duckv1.Status {
return &ep.Status.Status
}

View File

@ -1,164 +0,0 @@
/*
Copyright 2025 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 v1alpha1
import (
"context"
"fmt"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/apis"
)
func (t *EventTransform) Validate(ctx context.Context) *apis.FieldError {
ctx = apis.WithinParent(ctx, t.ObjectMeta)
return t.Spec.Validate(ctx).ViaField("spec")
}
var possibleTransformations = []string{"jsonata"}
func (ts *EventTransformSpec) Validate(ctx context.Context) *apis.FieldError {
errs := ts.EventTransformations.Validate(ctx /* allowEmpty */, false)
errs = errs.Also(ts.Sink.Validate(ctx).ViaField("sink"))
errs = errs.Also(disallowSinkCaCerts(ts).ViaField("sink"))
errs = errs.Also(ts.Reply.Validate(ctx, ts).ViaField("reply"))
if apis.IsInUpdate(ctx) {
original := apis.GetBaseline(ctx).(*EventTransform)
errs = errs.Also(ts.CheckImmutableFields(ctx, original))
}
return errs
}
func (ets EventTransformations) Validate(ctx context.Context, allowEmpty bool) *apis.FieldError {
var errs *apis.FieldError
// Only one type of transformation is allowed.
// These are transformations field paths.
transformations := ets.transformations()
if len(transformations) == 0 && !allowEmpty {
errs = apis.ErrMissingOneOf(possibleTransformations...)
} else if len(transformations) > 1 {
errs = apis.ErrMultipleOneOf(transformations...)
}
errs = errs.Also(ets.Jsonata.Validate(ctx).ViaField("jsonata"))
return errs
}
func (ets EventTransformations) transformations() []string {
// Only one type of transformation is allowed.
// These are transformations field paths.
transformations := make([]string, 0, 2)
if ets.Jsonata != nil {
transformations = append(transformations, "jsonata")
}
return transformations
}
func (rs *ReplySpec) Validate(ctx context.Context, ts *EventTransformSpec) *apis.FieldError {
if rs == nil {
return nil
}
if ts.Sink == nil {
return apis.ErrGeneric(
"reply is set without spec.sink",
"",
)
}
errs := rs.EventTransformations.Validate(ctx /* allowEmpty */, true)
baseTransformationsSet := sets.New(ts.EventTransformations.transformations()...)
replyTransformationsSet := sets.New(rs.EventTransformations.transformations()...)
transformationsIntersection := baseTransformationsSet.Intersection(replyTransformationsSet)
replyTransformations := rs.EventTransformations.transformations()
if rs.Discard != nil && *rs.Discard {
replyTransformations = append(replyTransformations, "discard")
}
if len(replyTransformations) > 1 {
errs = apis.ErrMultipleOneOf(replyTransformations...)
} else if replyTransformationsSet.Len() > 0 &&
baseTransformationsSet.Len() > 0 &&
transformationsIntersection.Len() != 1 {
errs = apis.ErrGeneric(
fmt.Sprintf(
"Reply transformation type must match the transformation type in the top-level spec. Top-level transformations: %#v, reply transformations: %#v",
strings.Join(baseTransformationsSet.UnsortedList(), ", "),
strings.Join(replyTransformationsSet.UnsortedList(), ", "),
),
replyTransformationsSet.UnsortedList()...,
)
}
return errs
}
func (js *JsonataEventTransformationSpec) Validate(context.Context) *apis.FieldError {
// Jsonata parsers for Go are not maintained, therefore, we will not parse the expression here.
// The downside is that the errors will only be present in the status of the EventTransform resource.
// We can reconsider this in the future and improve.
return nil
}
func disallowSinkCaCerts(ts *EventTransformSpec) *apis.FieldError {
sink := ts.Sink
if sink == nil || sink.CACerts == nil || ts.Jsonata == nil {
return nil
}
return &apis.FieldError{
Message: "CACerts for the sink is not supported for JSONata transformations, to propagate CA trust bundles use labeled ConfigMaps: " +
"https://knative.dev/docs/eventing/features/transport-encryption/#configure-additional-ca-trust-bundles",
Paths: []string{"CACerts"},
}
}
func (in *EventTransformSpec) CheckImmutableFields(ctx context.Context, original *EventTransform) *apis.FieldError {
if original == nil {
return nil
}
errs := in.EventTransformations.CheckImmutableFields(ctx, original.Spec.EventTransformations)
errs = errs.Also(in.Reply.CheckImmutableFields(ctx, original.Spec.Reply).ViaField("reply"))
return errs
}
func (ets EventTransformations) CheckImmutableFields(ctx context.Context, original EventTransformations) *apis.FieldError {
var errs *apis.FieldError
const suggestion = "Suggestion: create a new transformation, migrate services to the new one, and delete this transformation."
if ets.Jsonata != nil && original.Jsonata == nil {
errs = apis.ErrGeneric("Transformations types are immutable, jsonata transformation cannot be changed to a different transformation type. " + suggestion).ViaField("jsonata")
} else if original.Jsonata != nil && ets.Jsonata == nil {
errs = apis.ErrGeneric("Transformations types are immutable, transformation type cannot be changed to a jsonata transformation. " + suggestion).ViaField("jsonata")
}
return errs
}
func (rs *ReplySpec) CheckImmutableFields(_ context.Context, _ *ReplySpec) *apis.FieldError {
// ReplySpec is fully mutable.
return nil
}

View File

@ -1,394 +0,0 @@
/*
Copyright 2025 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 v1alpha1_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
eventing "knative.dev/eventing/pkg/apis/eventing/v1alpha1"
"knative.dev/eventing/pkg/eventingtls/eventingtlstesting"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/ptr"
"knative.dev/pkg/webhook/json"
)
func TestJSONDecode(t *testing.T) {
et := &eventing.EventTransform{}
err := json.Decode([]byte(`
{
"apiVersion": "eventing.knative.dev/v1alpha1",
"kind": "EventTransform",
"metadata": {
"name": "identity"
},
"spec": {
"jsonata": {
"expression": "{\n \"specversion\": \"1.0\",\n \"id\": id,\n \"type\": \"transformation.jsonata\",\n \"source\": \"transformation.json.identity\",\n \"data\": $\n}\n"
}
}
}
`), et, true)
assert.Nil(t, err)
}
var sink = &duckv1.Destination{
URI: apis.HTTP("example.com"),
}
func TestEventTransform_Validate(t *testing.T) {
tests := []struct {
name string
in eventing.EventTransform
ctx context.Context
want *apis.FieldError
}{
{
name: "empty",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{},
Status: eventing.EventTransformStatus{},
},
ctx: context.Background(),
want: apis.ErrMissingOneOf("jsonata").ViaField("spec"),
},
{
name: "jsonata valid",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
},
},
ctx: context.Background(),
want: nil,
},
{
name: "jsonata with reply valid",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
},
},
Status: eventing.EventTransformStatus{},
},
ctx: context.Background(),
want: nil,
},
{
name: "jsonata with reply discard valid",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
Reply: &eventing.ReplySpec{
Discard: ptr.Bool(true),
},
},
Status: eventing.EventTransformStatus{},
},
ctx: context.Background(),
want: nil,
},
{
name: "jsonata with reply, jsonata reply transformations and discard = true, invalid",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
Discard: ptr.Bool(true),
},
},
},
ctx: context.Background(),
want: (&apis.FieldError{}).Also(apis.ErrMultipleOneOf("jsonata", "discard").ViaField("reply").ViaField("spec")),
},
{
name: "jsonata update change expression",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
},
},
ctx: apis.WithinUpdate(context.Background(), &eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
},
},
}),
want: nil,
},
{
name: "transform jsonata change transformation type, have -> not have",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
},
ctx: apis.WithinUpdate(context.Background(), &eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{},
},
}),
want: (&apis.FieldError{}).
Also(
apis.ErrGeneric("Transformations types are immutable, jsonata transformation cannot be changed to a different transformation type. Suggestion: create a new transformation, migrate services to the new one, and delete this transformation.").
ViaField("jsonata"),
).
ViaField("spec"),
},
{
name: "transform jsonata change reply transformation type, have -> not have",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
},
},
ctx: apis.WithinUpdate(context.Background(), &eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
}),
want: nil,
},
{
name: "transform jsonata change reply transformation type, jsonata expression -> discard",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: sink,
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
},
},
ctx: apis.WithinUpdate(context.Background(), &eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
Reply: &eventing.ReplySpec{
Discard: ptr.Bool(true),
},
},
}),
want: nil,
},
{
name: "reply without sink",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
Reply: &eventing.ReplySpec{
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "2.0" }`,
},
},
},
},
Status: eventing.EventTransformStatus{},
},
ctx: context.Background(),
want: (&apis.FieldError{}).Also(
apis.ErrGeneric("reply is set without spec.sink", "").
ViaField("reply").
ViaField("spec"),
),
},
{
name: "jsonata with sink unsupported CACerts",
in: eventing.EventTransform{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: "name",
},
Spec: eventing.EventTransformSpec{
Sink: &duckv1.Destination{
URI: sink.URI,
CACerts: ptr.String(string(eventingtlstesting.CA)),
},
EventTransformations: eventing.EventTransformations{
Jsonata: &eventing.JsonataEventTransformationSpec{
Expression: `{ "specversion": "1.0" }`,
},
},
},
},
ctx: context.Background(),
want: (&apis.FieldError{}).Also(&apis.FieldError{
Message: "CACerts for the sink is not supported for JSONata transformations, to propagate CA trust bundles use labeled ConfigMaps: " +
"https://knative.dev/docs/eventing/features/transport-encryption/#configure-additional-ca-trust-bundles",
Paths: []string{"spec.sink.CACerts"},
}),
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := tt.in.Validate(tt.ctx)
assert.Equalf(t, tt.want, tt.in.Validate(tt.ctx), "Validate(%v) = %v", tt.ctx, got)
})
}
}

View File

@ -47,10 +47,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&EventPolicy{},
&EventPolicyList{},
&RequestReply{},
&RequestReplyList{},
&EventTransform{},
&EventTransformList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@ -1,34 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"fmt"
"knative.dev/pkg/apis"
)
// ConvertTo implements apis.Convertible
func (ep *RequestReply) ConvertTo(ctx context.Context, obj apis.Convertible) error {
return fmt.Errorf("v1alpha1 is the highest known version, got: %T", obj)
}
// ConvertFrom implements apis.Convertible
func (ep *RequestReply) ConvertFrom(ctx context.Context, obj apis.Convertible) error {
return fmt.Errorf("v1alpha1 is the highest known version, got: %T", obj)
}

View File

@ -1,44 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"k8s.io/utils/ptr"
"knative.dev/eventing/pkg/apis/feature"
"knative.dev/pkg/apis"
)
func (rr *RequestReply) SetDefaults(ctx context.Context) {
ctx = apis.WithinParent(ctx, rr.ObjectMeta)
rr.Spec.SetDefaults(ctx)
}
func (rrs *RequestReplySpec) SetDefaults(ctx context.Context) {
if rrs.Timeout == nil || *rrs.Timeout == "" {
rrs.Timeout = ptr.To(feature.FromContextOrDefaults(ctx).RequestReplyDefaultTimeout())
}
if rrs.CorrelationAttribute == "" {
rrs.CorrelationAttribute = "correlationid"
}
if rrs.ReplyAttribute == "" {
rrs.ReplyAttribute = "replyid"
}
}

View File

@ -1,68 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"testing"
"k8s.io/utils/ptr"
"github.com/google/go-cmp/cmp"
)
func TestRequestReplyDefaults(t *testing.T) {
testCases := map[string]struct {
initial RequestReply
expected RequestReply
}{
"nil spec": {
initial: RequestReply{},
expected: RequestReply{
Spec: RequestReplySpec{
Timeout: ptr.To("30s"),
CorrelationAttribute: "correlationid",
ReplyAttribute: "replyid",
},
},
},
"does not override existing values": {
initial: RequestReply{
Spec: RequestReplySpec{
Timeout: ptr.To("40s"),
CorrelationAttribute: "othercorrelationid",
ReplyAttribute: "otherreplyid",
},
},
expected: RequestReply{
Spec: RequestReplySpec{
Timeout: ptr.To("40s"),
CorrelationAttribute: "othercorrelationid",
ReplyAttribute: "otherreplyid",
},
},
},
}
for n, tc := range testCases {
t.Run(n, func(t *testing.T) {
tc.initial.SetDefaults(context.TODO())
if diff := cmp.Diff(tc.expected, tc.initial); diff != "" {
t.Fatal("Unexpected defaults (-want, +got):", diff)
}
})
}
}

View File

@ -1,106 +0,0 @@
/*
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 v1alpha1
import (
"knative.dev/pkg/apis"
v1 "knative.dev/pkg/apis/duck/v1"
)
var requestReplyCondSet = apis.NewLivingConditionSet(RequestReplyConditionIngress, RequestReplyConditionTriggers, RequestReplyConditionAddressable, RequestReplyConditionEventPoliciesReady)
const (
RequestReplyConditionReady = apis.ConditionReady
RequestReplyConditionIngress apis.ConditionType = "IngressReady"
RequestReplyConditionTriggers apis.ConditionType = "TriggersReady"
RequestReplyConditionAddressable apis.ConditionType = "Addressable"
RequestReplyConditionEventPoliciesReady apis.ConditionType = "EventPoliciesReady"
)
// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface.
func (*RequestReply) GetConditionSet() apis.ConditionSet {
return requestReplyCondSet
}
func (*RequestReplyStatus) GetConditionSet() apis.ConditionSet {
return requestReplyCondSet
}
// GetCondition returns the condition currently associated with the given type, or nil.
func (rr *RequestReplyStatus) GetCondition(t apis.ConditionType) *apis.Condition {
return requestReplyCondSet.Manage(rr).GetCondition(t)
}
// IsReady returns true if the resource is ready overall.
func (rr *RequestReplyStatus) IsReady() bool {
return rr.GetTopLevelCondition().IsTrue()
}
// GetTopLevelCondition returns the top level Condition.
func (rr *RequestReplyStatus) GetTopLevelCondition() *apis.Condition {
return requestReplyCondSet.Manage(rr).GetTopLevelCondition()
}
// InitializeConditions sets relevant unset conditions to Unknown state.
func (rr *RequestReplyStatus) InitializeConditions() {
requestReplyCondSet.Manage(rr).InitializeConditions()
}
func (rr *RequestReplyStatus) SetAddress(address *v1.Addressable) {
rr.AddressStatus = v1.AddressStatus{
Address: address,
}
if address != nil && address.URL != nil {
rr.GetConditionSet().Manage(rr).MarkTrue(RequestReplyConditionAddressable)
rr.AddressStatus.Address.Name = &address.URL.Scheme
} else {
rr.GetConditionSet().Manage(rr).MarkFalse(RequestReplyConditionAddressable, "nil URL", "URL is nil")
}
}
func (rr *RequestReplyStatus) MarkTriggersReady() {
rr.GetConditionSet().Manage(rr).MarkTrue(RequestReplyConditionTriggers)
}
func (rr *RequestReplyStatus) MarkTriggersNotReadyWithReason(reason, messageFormat string, messageA ...interface{}) {
rr.GetConditionSet().Manage(rr).MarkUnknown(RequestReplyConditionTriggers, reason, messageFormat, messageA...)
}
func (rr *RequestReplyStatus) MarkIngressReady() {
rr.GetConditionSet().Manage(rr).MarkTrue(RequestReplyConditionIngress)
}
func (rr *RequestReplyStatus) MarkIngressNotReadyWithReason(reason, messageFormat string, messageA ...interface{}) {
rr.GetConditionSet().Manage(rr).MarkUnknown(RequestReplyConditionIngress, reason, messageFormat, messageA...)
}
func (rr *RequestReplyStatus) MarkEventPoliciesTrue() {
rr.GetConditionSet().Manage(rr).MarkTrue(RequestReplyConditionEventPoliciesReady)
}
func (rr *RequestReplyStatus) MarkEventPoliciesTrueWithReason(reason, messageFormat string, messageA ...interface{}) {
rr.GetConditionSet().Manage(rr).MarkTrueWithReason(RequestReplyConditionEventPoliciesReady, reason, messageFormat, messageA...)
}
func (rr *RequestReplyStatus) MarkEventPoliciesFailed(reason, messageFormat string, messageA ...interface{}) {
rr.GetConditionSet().Manage(rr).MarkFalse(RequestReplyConditionEventPoliciesReady, reason, messageFormat, messageA...)
}
func (rr *RequestReplyStatus) MarkEventPoliciesUnknown(reason, messageFormat string, messageA ...interface{}) {
rr.GetConditionSet().Manage(rr).MarkUnknown(RequestReplyConditionEventPoliciesReady, reason, messageFormat, messageA...)
}

View File

@ -1,267 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"testing"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
var (
requestReplyConditionReady = apis.Condition{
Type: RequestReplyConditionReady,
Status: corev1.ConditionTrue,
}
)
func TestRequestReplyGetConditionSet(t *testing.T) {
r := &RequestReply{}
if got, want := r.GetConditionSet().GetTopLevelConditionType(), apis.ConditionReady; got != want {
t.Errorf("GetTopLevelCondition=%v, want=%v", got, want)
}
}
func TestRequestReplyGetCondition(t *testing.T) {
tests := []struct {
name string
rrs *RequestReplyStatus
condQuery apis.ConditionType
want *apis.Condition
}{{
name: "single condition",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
requestReplyConditionReady,
},
},
},
condQuery: apis.ConditionReady,
want: &eventPolicyConditionReady,
}}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := test.rrs.GetCondition(test.condQuery)
if diff := cmp.Diff(test.want, got); diff != "" {
t.Error("unexpected condition (-want, +got) =", diff)
}
})
}
}
func TestRequestReplyInitializeConditions(t *testing.T) {
tests := []struct {
name string
rrs *RequestReplyStatus
want *RequestReplyStatus
}{
{
name: "empty status",
rrs: &RequestReplyStatus{},
want: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{
Type: RequestReplyConditionAddressable,
Status: corev1.ConditionUnknown,
},
{
Type: RequestReplyConditionEventPoliciesReady,
Status: corev1.ConditionUnknown,
},
{
Type: RequestReplyConditionIngress,
Status: corev1.ConditionUnknown,
},
{
Type: RequestReplyConditionReady,
Status: corev1.ConditionUnknown,
},
{
Type: RequestReplyConditionTriggers,
Status: corev1.ConditionUnknown,
},
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.rrs.InitializeConditions()
if diff := cmp.Diff(test.want, test.rrs, ignoreAllButTypeAndStatus); diff != "" {
t.Error("unexpected conditions (-want, +got) =", diff)
}
})
}
}
func TestRequestReplyReadyCondition(t *testing.T) {
tests := []struct {
name string
rrs *RequestReplyStatus
markAddresableSucceeded *bool
markIngressReadySucceeded *bool
markTriggersReadySucceeded *bool
markEventPoliciesReadySucceeded *bool
wantReady bool
}{
{
name: "Initially everything is Unknown, Auth&SubjectsResolved marked as true, EP should become Ready",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{Type: RequestReplyConditionReady, Status: corev1.ConditionUnknown},
{Type: RequestReplyConditionAddressable, Status: corev1.ConditionUnknown},
{Type: RequestReplyConditionIngress, Status: corev1.ConditionUnknown},
{Type: RequestReplyConditionTriggers, Status: corev1.ConditionUnknown},
{Type: RequestReplyConditionEventPoliciesReady, Status: corev1.ConditionUnknown},
},
},
},
markAddresableSucceeded: ptr.To(true),
markIngressReadySucceeded: ptr.To(true),
markTriggersReadySucceeded: ptr.To(true),
markEventPoliciesReadySucceeded: ptr.To(true),
wantReady: true,
},
{
name: "Initially everything is Ready, Addressable set to false, RR should become False",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{Type: RequestReplyConditionReady, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionAddressable, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionIngress, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionTriggers, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionEventPoliciesReady, Status: corev1.ConditionTrue},
},
},
},
markAddresableSucceeded: ptr.To(false),
markIngressReadySucceeded: ptr.To(true),
markTriggersReadySucceeded: ptr.To(true),
markEventPoliciesReadySucceeded: ptr.To(true),
wantReady: false,
},
{
name: "Initially everything is Ready, Ingress set to false, RR should become False",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{Type: RequestReplyConditionReady, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionAddressable, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionIngress, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionTriggers, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionEventPoliciesReady, Status: corev1.ConditionTrue},
},
},
},
markAddresableSucceeded: ptr.To(true),
markIngressReadySucceeded: ptr.To(false),
markTriggersReadySucceeded: ptr.To(true),
markEventPoliciesReadySucceeded: ptr.To(true),
wantReady: false,
},
{
name: "Initially everything is Ready, Trigger set to false, RR should become False",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{Type: RequestReplyConditionReady, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionAddressable, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionIngress, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionTriggers, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionEventPoliciesReady, Status: corev1.ConditionTrue},
},
},
},
markAddresableSucceeded: ptr.To(true),
markIngressReadySucceeded: ptr.To(true),
markTriggersReadySucceeded: ptr.To(false),
markEventPoliciesReadySucceeded: ptr.To(true),
wantReady: false,
},
{
name: "Initially everything is Ready, EPs set to false, RR should become False",
rrs: &RequestReplyStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{
{Type: RequestReplyConditionReady, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionAddressable, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionIngress, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionTriggers, Status: corev1.ConditionTrue},
{Type: RequestReplyConditionEventPoliciesReady, Status: corev1.ConditionTrue},
},
},
},
markAddresableSucceeded: ptr.To(true),
markIngressReadySucceeded: ptr.To(true),
markTriggersReadySucceeded: ptr.To(true),
markEventPoliciesReadySucceeded: ptr.To(false),
wantReady: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.markAddresableSucceeded != nil {
if *test.markAddresableSucceeded {
url, _ := apis.ParseURL("http://localhost:8080")
test.rrs.SetAddress(&duckv1.Addressable{URL: url})
} else {
test.rrs.SetAddress(nil)
}
}
if test.markIngressReadySucceeded != nil {
if *test.markIngressReadySucceeded {
test.rrs.MarkIngressReady()
} else {
test.rrs.MarkIngressNotReadyWithReason("", "")
}
}
if test.markTriggersReadySucceeded != nil {
if *test.markTriggersReadySucceeded {
test.rrs.MarkTriggersReady()
} else {
test.rrs.MarkTriggersNotReadyWithReason("", "")
}
}
if test.markEventPoliciesReadySucceeded != nil {
if *test.markEventPoliciesReadySucceeded {
test.rrs.MarkEventPoliciesTrue()
} else {
test.rrs.MarkEventPoliciesFailed("", "")
}
}
rr := RequestReply{Status: *test.rrs}
got := rr.GetConditionSet().Manage(test.rrs).IsHappy()
if test.wantReady != got {
t.Errorf("unexpected readiness: want %v, got %v", test.wantReady, got)
}
})
}
}

View File

@ -1,122 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/kmeta"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
)
// +genclient
// +genreconciler
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// RequestRepluy represents synchronous interface to sending and receiving events from a Broker.
type RequestReply struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec defines the desired state of the EventPolicy.
Spec RequestReplySpec `json:"spec,omitempty"`
// Status represents the current state of the EventPolicy.
// This data may be out of date.
// +optional
Status RequestReplyStatus `json:"status,omitempty"`
}
var (
// Check that EventPolicy can be validated, can be defaulted, and has immutable fields.
_ apis.Validatable = (*RequestReply)(nil)
_ apis.Defaultable = (*RequestReply)(nil)
// Check that EventPolicy can return its spec untyped.
_ apis.HasSpec = (*RequestReply)(nil)
_ runtime.Object = (*RequestReply)(nil)
// Check that we can create OwnerReferences to an EventPolicy.
_ kmeta.OwnerRefable = (*RequestReply)(nil)
// Check that the type conforms to the duck Knative Resource shape.
_ duckv1.KRShaped = (*RequestReply)(nil)
)
type RequestReplySpec struct {
// BrokerRef contains the reference to the broker the RequestReply sends events to.
BrokerRef duckv1.KReference `json:"brokerRef"`
CorrelationAttribute string `json:"correlationAttribute"`
ReplyAttribute string `json:"replyAttribute"`
Timeout *string `json:"timeout,omitempty"`
Delivery *eventingduckv1.DeliverySpec `json:"delivery,omitempty"`
Secrets []string `json:"secrets"`
}
// RequestReplyStatus represents the current state of a RequestReply.
type RequestReplyStatus struct {
// inherits duck/v1 Status, which currently provides:
// * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller.
// * Conditions - the latest available observations of a resource's current state.
duckv1.Status `json:",inline"`
// AddressStatus is the part where the RequestReply fulfills the Addressable contract.
// It exposes the endpoint as an URI to get events delivered.
// +optional
duckv1.AddressStatus `json:",inline"`
// AppliedEventPoliciesStatus contains the list of EventPolicies which apply to this Broker.
// +optional
eventingduckv1.AppliedEventPoliciesStatus `json:",inline"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// RequestReplyList is a collection of RequestReplies.
type RequestReplyList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []RequestReply `json:"items"`
}
// GetGroupVersionKind returns GroupVersionKind for EventPolicy
func (rr *RequestReply) GetGroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind("RequestReply")
}
// GetUntypedSpec returns the spec of the EventPolicy.
func (rr *RequestReply) GetUntypedSpec() interface{} {
return rr.Spec
}
// GetStatus retrieves the status of the EventPolicy. Implements the KRShaped interface.
func (rr *RequestReply) GetStatus() *duckv1.Status {
return &rr.Status.Status
}

View File

@ -1,39 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"testing"
)
func TestRequestReplyGetStatus(t *testing.T) {
r := &RequestReply{
Status: RequestReplyStatus{},
}
if got, want := r.GetStatus(), &r.Status.Status; got != want {
t.Errorf("GetStatus=%v, want=%v", got, want)
}
}
func TestRequestReply_GetGroupVersionKind(t *testing.T) {
src := RequestReply{}
gvk := src.GetGroupVersionKind()
if gvk.Kind != "RequestReply" {
t.Errorf("Should be RequestReply, got %s.", gvk.Kind)
}
}

View File

@ -1,83 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"strings"
"github.com/rickb777/date/period"
"knative.dev/pkg/apis"
)
func (rr *RequestReply) Validate(ctx context.Context) *apis.FieldError {
ctx = apis.WithinParent(ctx, rr.ObjectMeta)
return rr.Spec.Validate(ctx).ViaField("spec")
}
func (rrs *RequestReplySpec) Validate(ctx context.Context) *apis.FieldError {
var errs *apis.FieldError
if ke := rrs.BrokerRef.Validate(ctx); ke != nil {
errs = errs.Also(ke.ViaField("brokerRef"))
}
if !strings.EqualFold(rrs.BrokerRef.Kind, "broker") {
errs = errs.Also(apis.ErrInvalidValue(rrs.BrokerRef.Kind, ".kind", "brokerRef kind must be Broker").ViaField("brokerRef"))
}
if rrs.BrokerRef.Namespace != "" {
errs = errs.Also(apis.ErrDisallowedFields("namespace").ViaField("brokerRef"))
}
if rrs.Delivery != nil {
if de := rrs.Delivery.Validate(ctx); de != nil {
errs = errs.Also(de.ViaField("delivery"))
}
}
if rrs.Timeout != nil {
timeout, err := period.Parse(*rrs.Timeout)
if err != nil || timeout.IsZero() || timeout.IsNegative() {
errs = errs.Also(apis.ErrInvalidValue(*rrs.Timeout, "timeout"))
}
}
if len(rrs.Secrets) == 0 {
errs = errs.Also(apis.ErrInvalidValue(rrs.Secrets, "secrets", "one or more secrets must be provided"))
}
if rrs.CorrelationAttribute == "" ||
rrs.CorrelationAttribute == "id" ||
rrs.CorrelationAttribute == "course" ||
rrs.CorrelationAttribute == "specversion" ||
rrs.CorrelationAttribute == "type" {
errs = errs.Also(apis.ErrInvalidValue(rrs.CorrelationAttribute, "correlationattribute", "correlationattribute must be non-empty and cannot be a core cloudevent attribute (id, type, specversion, source)"))
}
if rrs.ReplyAttribute == "" ||
rrs.ReplyAttribute == "id" ||
rrs.ReplyAttribute == "course" ||
rrs.ReplyAttribute == "specversion" ||
rrs.ReplyAttribute == "type" {
errs = errs.Also(apis.ErrInvalidValue(rrs.ReplyAttribute, "replyattribute", "replyattribute must be non-empty and cannot be a core cloudevent attribute (id, type, specversion, source)"))
}
return errs
}

View File

@ -1,63 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
func TestRequestReplyValidation(t *testing.T) {
tests := []struct {
name string
rr *RequestReply
want *apis.FieldError
}{
{
name: "valid, all required fields set",
rr: &RequestReply{
Spec: RequestReplySpec{
ReplyAttribute: "reply",
CorrelationAttribute: "correlate",
Secrets: []string{"secret1"},
BrokerRef: duckv1.KReference{
APIVersion: "eventing.knative.dev/v1",
Kind: "Broker",
Name: "broker",
},
},
},
want: func() *apis.FieldError {
return nil
}(),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := apis.WithinCreate(context.Background())
got := test.rr.Validate(ctx)
if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" {
t.Errorf("%s: Validate EventPolicySpec (-want, +got) = %v", test.name, diff)
}
})
}
}

View File

@ -24,9 +24,7 @@ package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
apisduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
@ -258,302 +256,3 @@ func (in *EventPolicyToReference) DeepCopy() *EventPolicyToReference {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventTransform) DeepCopyInto(out *EventTransform) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTransform.
func (in *EventTransform) DeepCopy() *EventTransform {
if in == nil {
return nil
}
out := new(EventTransform)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *EventTransform) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventTransformList) DeepCopyInto(out *EventTransformList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]EventTransform, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTransformList.
func (in *EventTransformList) DeepCopy() *EventTransformList {
if in == nil {
return nil
}
out := new(EventTransformList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *EventTransformList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventTransformSpec) DeepCopyInto(out *EventTransformSpec) {
*out = *in
if in.Sink != nil {
in, out := &in.Sink, &out.Sink
*out = new(duckv1.Destination)
(*in).DeepCopyInto(*out)
}
if in.Reply != nil {
in, out := &in.Reply, &out.Reply
*out = new(ReplySpec)
(*in).DeepCopyInto(*out)
}
in.EventTransformations.DeepCopyInto(&out.EventTransformations)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTransformSpec.
func (in *EventTransformSpec) DeepCopy() *EventTransformSpec {
if in == nil {
return nil
}
out := new(EventTransformSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventTransformStatus) DeepCopyInto(out *EventTransformStatus) {
*out = *in
in.SourceStatus.DeepCopyInto(&out.SourceStatus)
in.AddressStatus.DeepCopyInto(&out.AddressStatus)
if in.JsonataTransformationStatus != nil {
in, out := &in.JsonataTransformationStatus, &out.JsonataTransformationStatus
*out = new(JsonataEventTransformationStatus)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTransformStatus.
func (in *EventTransformStatus) DeepCopy() *EventTransformStatus {
if in == nil {
return nil
}
out := new(EventTransformStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventTransformations) DeepCopyInto(out *EventTransformations) {
*out = *in
if in.Jsonata != nil {
in, out := &in.Jsonata, &out.Jsonata
*out = new(JsonataEventTransformationSpec)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventTransformations.
func (in *EventTransformations) DeepCopy() *EventTransformations {
if in == nil {
return nil
}
out := new(EventTransformations)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JsonataEventTransformationSpec) DeepCopyInto(out *JsonataEventTransformationSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JsonataEventTransformationSpec.
func (in *JsonataEventTransformationSpec) DeepCopy() *JsonataEventTransformationSpec {
if in == nil {
return nil
}
out := new(JsonataEventTransformationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JsonataEventTransformationStatus) DeepCopyInto(out *JsonataEventTransformationStatus) {
*out = *in
in.Deployment.DeepCopyInto(&out.Deployment)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JsonataEventTransformationStatus.
func (in *JsonataEventTransformationStatus) DeepCopy() *JsonataEventTransformationStatus {
if in == nil {
return nil
}
out := new(JsonataEventTransformationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ReplySpec) DeepCopyInto(out *ReplySpec) {
*out = *in
in.EventTransformations.DeepCopyInto(&out.EventTransformations)
if in.Discard != nil {
in, out := &in.Discard, &out.Discard
*out = new(bool)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplySpec.
func (in *ReplySpec) DeepCopy() *ReplySpec {
if in == nil {
return nil
}
out := new(ReplySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RequestReply) DeepCopyInto(out *RequestReply) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestReply.
func (in *RequestReply) DeepCopy() *RequestReply {
if in == nil {
return nil
}
out := new(RequestReply)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *RequestReply) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RequestReplyList) DeepCopyInto(out *RequestReplyList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]RequestReply, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestReplyList.
func (in *RequestReplyList) DeepCopy() *RequestReplyList {
if in == nil {
return nil
}
out := new(RequestReplyList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *RequestReplyList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RequestReplySpec) DeepCopyInto(out *RequestReplySpec) {
*out = *in
in.BrokerRef.DeepCopyInto(&out.BrokerRef)
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(string)
**out = **in
}
if in.Delivery != nil {
in, out := &in.Delivery, &out.Delivery
*out = new(apisduckv1.DeliverySpec)
(*in).DeepCopyInto(*out)
}
if in.Secrets != nil {
in, out := &in.Secrets, &out.Secrets
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestReplySpec.
func (in *RequestReplySpec) DeepCopy() *RequestReplySpec {
if in == nil {
return nil
}
out := new(RequestReplySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RequestReplyStatus) DeepCopyInto(out *RequestReplyStatus) {
*out = *in
in.Status.DeepCopyInto(&out.Status)
in.AddressStatus.DeepCopyInto(&out.AddressStatus)
in.AppliedEventPoliciesStatus.DeepCopyInto(&out.AppliedEventPoliciesStatus)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestReplyStatus.
func (in *RequestReplyStatus) DeepCopy() *RequestReplyStatus {
if in == nil {
return nil
}
out := new(RequestReplyStatus)
in.DeepCopyInto(out)
return out
}

View File

@ -67,10 +67,6 @@ const (
// DefaultOIDCDiscoveryURL is the default OIDC Discovery URL used in most Kubernetes clusters.
DefaultOIDCDiscoveryBaseURL Flag = "https://kubernetes.default.svc"
// DefaultRequestReplyTimeout is a value for RequestReplyDefaultTimeout that indicates to timeout
// a RequestReply resource after 30 seconds by default.
DefaultRequestReplyTimeout Flag = "30s"
)
// Flags is a map containing all the enabled/disabled flags for the experimental features.
@ -79,17 +75,16 @@ type Flags map[string]Flag
func newDefaults() Flags {
return map[string]Flag{
KReferenceGroup: Disabled,
DeliveryRetryAfter: Disabled,
DeliveryTimeout: Enabled,
KReferenceMapping: Disabled,
TransportEncryption: Disabled,
OIDCAuthentication: Disabled,
EvenTypeAutoCreate: Disabled,
NewAPIServerFilters: Disabled,
AuthorizationDefaultMode: AuthorizationAllowSameNamespace,
OIDCDiscoveryBaseURL: DefaultOIDCDiscoveryBaseURL,
RequestReplyDefaultTimeout: DefaultRequestReplyTimeout,
KReferenceGroup: Disabled,
DeliveryRetryAfter: Disabled,
DeliveryTimeout: Enabled,
KReferenceMapping: Disabled,
TransportEncryption: Disabled,
OIDCAuthentication: Disabled,
EvenTypeAutoCreate: Disabled,
NewAPIServerFilters: Disabled,
AuthorizationDefaultMode: AuthorizationAllowSameNamespace,
OIDCDiscoveryBaseURL: DefaultOIDCDiscoveryBaseURL,
}
}
@ -148,7 +143,6 @@ func (e Flags) OIDCDiscoveryBaseURL() string {
return string(DefaultOIDCDiscoveryBaseURL)
}
//nolint:staticcheck
discoveryUrl, ok := e[OIDCDiscoveryBaseURL]
if !ok {
return string(DefaultOIDCDiscoveryBaseURL)
@ -157,19 +151,6 @@ func (e Flags) OIDCDiscoveryBaseURL() string {
return string(discoveryUrl)
}
func (e Flags) RequestReplyDefaultTimeout() string {
if e == nil {
return string(DefaultRequestReplyTimeout)
}
timeout, ok := e[RequestReplyDefaultTimeout]
if !ok {
return string(DefaultRequestReplyTimeout)
}
return string(timeout)
}
func (e Flags) String() string {
return fmt.Sprintf("%+v", map[string]Flag(e))
}

View File

@ -17,17 +17,16 @@ limitations under the License.
package feature
const (
KReferenceGroup = "kreference-group"
DeliveryRetryAfter = "delivery-retryafter"
DeliveryTimeout = "delivery-timeout"
KReferenceMapping = "kreference-mapping"
TransportEncryption = "transport-encryption"
EvenTypeAutoCreate = "eventtype-auto-create"
OIDCAuthentication = "authentication-oidc"
NodeSelectorLabel = "apiserversources-nodeselector-"
CrossNamespaceEventLinks = "cross-namespace-event-links"
NewAPIServerFilters = "new-apiserversource-filters"
AuthorizationDefaultMode = "default-authorization-mode"
OIDCDiscoveryBaseURL = "oidc-discovery-base-url"
RequestReplyDefaultTimeout = "requestreply-default-timeout"
KReferenceGroup = "kreference-group"
DeliveryRetryAfter = "delivery-retryafter"
DeliveryTimeout = "delivery-timeout"
KReferenceMapping = "kreference-mapping"
TransportEncryption = "transport-encryption"
EvenTypeAutoCreate = "eventtype-auto-create"
OIDCAuthentication = "authentication-oidc"
NodeSelectorLabel = "apiserversources-nodeselector-"
CrossNamespaceEventLinks = "cross-namespace-event-links"
NewAPIServerFilters = "new-apiserversource-filters"
AuthorizationDefaultMode = "default-authorization-mode"
OIDCDiscoveryBaseURL = "oidc-discovery-base-url"
)

View File

@ -19,8 +19,8 @@ package v1
import (
"testing"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/runtime/serializer"
"sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/runtime"
@ -36,8 +36,8 @@ import (
var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
func(codecs serializer.CodecFactory) []interface{} {
return []interface{}{
func(s *SequenceStatus, c randfill.Continue) {
c.FillNoCustom(s) // fuzz the status object
func(s *SequenceStatus, c fuzz.Continue) {
c.FuzzNoCustom(s) // fuzz the status object
// Clear the random fuzzed condition
s.Status.SetConditions(nil)
@ -46,8 +46,8 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
s.InitializeConditions()
pkgfuzzer.FuzzConditions(&s.Status, c)
},
func(s *ParallelStatus, c randfill.Continue) {
c.FillNoCustom(s) // fuzz the status object
func(s *ParallelStatus, c fuzz.Continue) {
c.FuzzNoCustom(s) // fuzz the status object
// Clear the random fuzzed condition
s.Status.SetConditions(nil)

View File

@ -21,6 +21,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"knative.dev/pkg/kmp"
@ -101,14 +102,14 @@ func TestChannelDefaultsConfiguration(t *testing.T) {
wantChannelDefaults: &ChannelDefaults{
NamespaceDefaults: map[string]*ChannelTemplateSpec{
"some-namespace": {
TypeMeta: metav1.TypeMeta{
TypeMeta: v1.TypeMeta{
APIVersion: "messaging.knative.dev/v1beta1",
Kind: "KafkaChannel",
},
},
},
ClusterDefault: &ChannelTemplateSpec{
TypeMeta: metav1.TypeMeta{
TypeMeta: v1.TypeMeta{
APIVersion: "messaging.knative.dev/v1",
Kind: "InMemoryChannel",
},
@ -136,7 +137,7 @@ func TestChannelDefaultsConfiguration(t *testing.T) {
wantErr: false,
wantChannelDefaults: &ChannelDefaults{
ClusterDefault: &ChannelTemplateSpec{
TypeMeta: metav1.TypeMeta{
TypeMeta: v1.TypeMeta{
APIVersion: "messaging.knative.dev/v1beta1",
Kind: "KafkaChannel",
},
@ -161,7 +162,7 @@ func TestChannelDefaultsConfiguration(t *testing.T) {
wantChannelDefaults: &ChannelDefaults{
NamespaceDefaults: map[string]*ChannelTemplateSpec{
"some-namespace": {
TypeMeta: metav1.TypeMeta{
TypeMeta: v1.TypeMeta{
APIVersion: "messaging.knative.dev/v1",
Kind: "InMemoryChannel",
},
@ -188,7 +189,7 @@ func TestChannelDefaultsConfiguration(t *testing.T) {
wantChannelDefaults: &ChannelDefaults{
NamespaceDefaults: map[string]*ChannelTemplateSpec{
"some-namespace": {
TypeMeta: metav1.TypeMeta{
TypeMeta: v1.TypeMeta{
APIVersion: "messaging.knative.dev/v1",
Kind: "InMemoryChannel",
},

View File

@ -19,11 +19,10 @@ package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/kmeta"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
)
// +genclient
@ -45,14 +44,6 @@ type InMemoryChannel struct {
Status InMemoryChannelStatus `json:"status,omitempty"`
}
var (
// AsyncHandlerAnnotation controls whether InMemoryChannel uses the async handler.
//
// Async handler is subject to event loss since it responds with 200 before forwarding the event
// to all subscriptions.
AsyncHandlerAnnotation = SchemeGroupVersion.Group + "/async-handler"
)
var (
// Check that InMemoryChannel can be validated and defaulted.
_ apis.Validatable = (*InMemoryChannel)(nil)

View File

@ -22,13 +22,11 @@ import (
"knative.dev/pkg/apis"
"knative.dev/pkg/kmp"
"knative.dev/pkg/system"
"knative.dev/eventing/pkg/apis/eventing"
_ "knative.dev/pkg/system/testing"
)
var eventingControllerSAName = fmt.Sprintf("%s:%s:%s", "system:serviceaccount", system.Namespace(), "eventing-controller")
const eventingControllerSAName = "system:serviceaccount:knative-eventing:eventing-controller"
func (imc *InMemoryChannel) Validate(ctx context.Context) *apis.FieldError {
errs := imc.Spec.Validate(ctx).ViaField("spec")

View File

@ -17,11 +17,8 @@ limitations under the License.
package v1
import (
"fmt"
"testing"
"knative.dev/pkg/system"
"golang.org/x/net/context"
authenticationv1 "k8s.io/api/authentication/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -142,7 +139,7 @@ func TestInMemoryChannelValidation(t *testing.T) {
want: func() *apis.FieldError {
diff, _ := kmp.ShortDiff(validIMCSingleSubscriber.Spec.Subscribers, validIMCTwoSubscribers.Spec.Subscribers)
return &apis.FieldError{
Message: fmt.Sprintf("%s:%s:%s", "Channel.Spec.Subscribers changed by user test-user which was not the system:serviceaccount", system.Namespace(), "eventing-controller service account"),
Message: "Channel.Spec.Subscribers changed by user test-user which was not the system:serviceaccount:knative-eventing:eventing-controller service account",
Paths: []string{"spec.subscribers"},
Details: diff,
}

View File

@ -19,9 +19,9 @@ package v1
import (
"testing"
fuzz "github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/runtime/serializer"
"knative.dev/eventing/pkg/apis/messaging"
"sigs.k8s.io/randfill"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/runtime"
@ -37,8 +37,8 @@ import (
var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
func(codecs serializer.CodecFactory) []interface{} {
return []interface{}{
func(ch *Channel, c randfill.Continue) {
c.FillNoCustom(ch) // fuzz the Channel
func(ch *Channel, c fuzz.Continue) {
c.FuzzNoCustom(ch) // fuzz the Channel
if ch != nil {
if ch.Annotations == nil {
ch.Annotations = make(map[string]string)
@ -52,8 +52,8 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
ch.Status.InitializeConditions()
pkgfuzzer.FuzzConditions(&ch.Status, c)
},
func(imc *InMemoryChannel, c randfill.Continue) {
c.FillNoCustom(imc) // fuzz the InMemoryChannel
func(imc *InMemoryChannel, c fuzz.Continue) {
c.FuzzNoCustom(imc) // fuzz the InMemoryChannel
if imc != nil {
if imc.Annotations == nil {
imc.Annotations = make(map[string]string)
@ -67,8 +67,8 @@ var FuzzerFuncs = fuzzer.MergeFuzzerFuncs(
imc.Status.InitializeConditions()
pkgfuzzer.FuzzConditions(&imc.Status, c)
},
func(s *SubscriptionStatus, c randfill.Continue) {
c.FillNoCustom(s) // fuzz the status object
func(s *SubscriptionStatus, c fuzz.Continue) {
c.FuzzNoCustom(s) // fuzz the status object
// Clear the random fuzzed condition
s.Status.SetConditions(nil)

View File

@ -33,12 +33,6 @@ var (
Group: GroupName,
Resource: "jobsinks",
}
// IntegrationSinkResource respresents a Knative Eventing sink IntegrationSink
IntegrationSinkResource = schema.GroupResource{
Group: GroupName,
Resource: "integrationsinks",
}
)
type Config struct {

View File

@ -1,36 +0,0 @@
/*
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 v1alpha1
import (
"context"
"fmt"
"knative.dev/pkg/apis"
)
// ConvertTo implements apis.Convertible
// Converts source from v1alpha1.IntegrationSink into a higher version.
func (sink *IntegrationSink) ConvertTo(ctx context.Context, obj apis.Convertible) error {
return fmt.Errorf("v1alpha1 is the highest known version, got: %T", sink)
}
// ConvertFrom implements apis.Convertible
// Converts source from a higher version into v1beta2.IntegrationSink
func (sink *IntegrationSink) ConvertFrom(ctx context.Context, obj apis.Convertible) error {
return fmt.Errorf("v1alpha1 is the highest known version, got: %T", sink)
}

View File

@ -1,34 +0,0 @@
/*
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 v1alpha1
import (
"context"
"testing"
)
func TestIntegrationSinkConversionBadType(t *testing.T) {
good, bad := &IntegrationSink{}, &testObject{}
if err := good.ConvertTo(context.Background(), bad); err == nil {
t.Errorf("ConvertTo() = %#v, wanted error", bad)
}
if err := good.ConvertFrom(context.Background(), bad); err == nil {
t.Errorf("ConvertFrom() = %#v, wanted error", good)
}
}

View File

@ -1,26 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import "context"
func (sink *IntegrationSink) SetDefaults(ctx context.Context) {
sink.Spec.SetDefaults(ctx)
}
func (sink *IntegrationSinkSpec) SetDefaults(ctx context.Context) {
}

View File

@ -1,39 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestIntegrationSinkSetDefaults(t *testing.T) {
testCases := map[string]struct {
initial IntegrationSink
expected IntegrationSink
}{}
for n, tc := range testCases {
t.Run(n, func(t *testing.T) {
tc.initial.SetDefaults(context.TODO())
if diff := cmp.Diff(tc.expected, tc.initial); diff != "" {
t.Fatal("Unexpected defaults (-want, +got):", diff)
}
})
}
}

View File

@ -1,162 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
const (
// IntegrationSinkConditionReady has status True when the IntegrationSink is ready to send events.
IntegrationSinkConditionReady = apis.ConditionReady
IntegrationSinkConditionAddressable apis.ConditionType = "Addressable"
// IntegrationSinkConditionDeploymentReady has status True when the IntegrationSink has been configured with a deployment.
IntegrationSinkConditionDeploymentReady apis.ConditionType = "DeploymentReady"
// IntegrationSinkConditionEventPoliciesReady has status True when all the applying EventPolicies for this
// IntegrationSink are ready.
IntegrationSinkConditionEventPoliciesReady apis.ConditionType = "EventPoliciesReady"
// IntegrationSinkConditionCertificateReady has status True when the IntegrationSink's certificate is ready.
IntegrationSinkConditionCertificateReady apis.ConditionType = "CertificateReady"
// Certificate related condition reasons
IntegrationSinkCertificateNotReady string = "CertificateNotReady"
)
var IntegrationSinkCondSet = apis.NewLivingConditionSet(
IntegrationSinkConditionAddressable,
IntegrationSinkConditionDeploymentReady,
IntegrationSinkConditionEventPoliciesReady,
)
// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface.
func (*IntegrationSink) GetConditionSet() apis.ConditionSet {
return IntegrationSinkCondSet
}
// GetCondition returns the condition currently associated with the given type, or nil.
func (s *IntegrationSinkStatus) GetCondition(t apis.ConditionType) *apis.Condition {
return IntegrationSinkCondSet.Manage(s).GetCondition(t)
}
// GetTopLevelCondition returns the top level Condition.
func (ps *IntegrationSinkStatus) GetTopLevelCondition() *apis.Condition {
return IntegrationSinkCondSet.Manage(ps).GetTopLevelCondition()
}
// IsReady returns true if the resource is ready overall.
func (s *IntegrationSinkStatus) IsReady() bool {
return IntegrationSinkCondSet.Manage(s).IsHappy()
}
// InitializeConditions sets relevant unset conditions to Unknown state.
func (s *IntegrationSinkStatus) InitializeConditions() {
IntegrationSinkCondSet.Manage(s).InitializeConditions()
}
// MarkAddressableReady marks the Addressable condition to True.
func (s *IntegrationSinkStatus) MarkAddressableReady() {
IntegrationSinkCondSet.Manage(s).MarkTrue(IntegrationSinkConditionAddressable)
}
// MarkEventPoliciesFailed marks the EventPoliciesReady condition to False with the given reason and message.
func (s *IntegrationSinkStatus) MarkEventPoliciesFailed(reason, messageFormat string, messageA ...interface{}) {
IntegrationSinkCondSet.Manage(s).MarkFalse(IntegrationSinkConditionEventPoliciesReady, reason, messageFormat, messageA...)
}
// MarkEventPoliciesUnknown marks the EventPoliciesReady condition to Unknown with the given reason and message.
func (s *IntegrationSinkStatus) MarkEventPoliciesUnknown(reason, messageFormat string, messageA ...interface{}) {
IntegrationSinkCondSet.Manage(s).MarkUnknown(IntegrationSinkConditionEventPoliciesReady, reason, messageFormat, messageA...)
}
// MarkEventPoliciesTrue marks the EventPoliciesReady condition to True.
func (s *IntegrationSinkStatus) MarkEventPoliciesTrue() {
IntegrationSinkCondSet.Manage(s).MarkTrue(IntegrationSinkConditionEventPoliciesReady)
}
// MarkEventPoliciesTrueWithReason marks the EventPoliciesReady condition to True with the given reason and message.
func (s *IntegrationSinkStatus) MarkEventPoliciesTrueWithReason(reason, messageFormat string, messageA ...interface{}) {
IntegrationSinkCondSet.Manage(s).MarkTrueWithReason(IntegrationSinkConditionEventPoliciesReady, reason, messageFormat, messageA...)
}
func (s *IntegrationSinkStatus) PropagateDeploymentStatus(d *appsv1.DeploymentStatus) {
deploymentAvailableFound := false
for _, cond := range d.Conditions {
if cond.Type == appsv1.DeploymentAvailable {
deploymentAvailableFound = true
if cond.Status == corev1.ConditionTrue {
IntegrationSinkCondSet.Manage(s).MarkTrue(IntegrationSinkConditionDeploymentReady)
} else if cond.Status == corev1.ConditionFalse {
IntegrationSinkCondSet.Manage(s).MarkFalse(IntegrationSinkConditionDeploymentReady, cond.Reason, cond.Message)
} else if cond.Status == corev1.ConditionUnknown {
IntegrationSinkCondSet.Manage(s).MarkUnknown(IntegrationSinkConditionDeploymentReady, cond.Reason, cond.Message)
}
}
}
if !deploymentAvailableFound {
IntegrationSinkCondSet.Manage(s).MarkUnknown(IntegrationSinkConditionDeploymentReady, "DeploymentUnavailable", "The Deployment '%s' is unavailable.", d)
}
}
func (s *IntegrationSinkStatus) PropagateCertificateStatus(cs cmv1.CertificateStatus) bool {
var topLevel *cmv1.CertificateCondition
for _, cond := range cs.Conditions {
if cond.Type == cmv1.CertificateConditionReady {
topLevel = &cond
break
}
}
if topLevel == nil {
IntegrationSinkCondSet.Manage(s).MarkUnknown(IntegrationSinkConditionCertificateReady,
IntegrationSinkCertificateNotReady, "Certificate is progressing")
return false
}
if topLevel.Status == cmmeta.ConditionUnknown {
IntegrationSinkCondSet.Manage(s).MarkUnknown(IntegrationSinkConditionCertificateReady,
IntegrationSinkCertificateNotReady, "Certificate is progressing, "+topLevel.Reason+" Message: "+topLevel.Message)
return false
}
if topLevel.Status == cmmeta.ConditionFalse {
IntegrationSinkCondSet.Manage(s).MarkFalse(IntegrationSinkConditionCertificateReady,
IntegrationSinkCertificateNotReady, "Certificate is not ready, "+topLevel.Reason+" Message: "+topLevel.Message)
return false
}
IntegrationSinkCondSet.Manage(s).MarkTrue(IntegrationSinkConditionCertificateReady)
return true
}
func (s *IntegrationSinkStatus) SetAddress(address *duckv1.Addressable) {
s.Address = address
if address == nil || address.URL.IsEmpty() {
IntegrationSinkCondSet.Manage(s).MarkFalse(IntegrationSinkConditionAddressable, "EmptyHostname", "hostname is the empty string")
} else {
IntegrationSinkCondSet.Manage(s).MarkTrue(IntegrationSinkConditionAddressable)
}
}

View File

@ -1,125 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"testing"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
)
func TestIntegrationSinkGetConditionSet(t *testing.T) {
r := &IntegrationSink{}
if got, want := r.GetConditionSet().GetTopLevelConditionType(), apis.ConditionReady; got != want {
t.Errorf("GetTopLevelCondition=%v, want=%v", got, want)
}
}
func TestIntegrationSinkInitializeConditions(t *testing.T) {
tests := []struct {
name string
js *IntegrationSinkStatus
want *IntegrationSinkStatus
}{{
name: "empty",
js: &IntegrationSinkStatus{},
want: &IntegrationSinkStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{{
Type: IntegrationSinkConditionAddressable,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionDeploymentReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionEventPoliciesReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionReady,
Status: corev1.ConditionUnknown,
}},
},
},
}, {
name: "one false",
js: &IntegrationSinkStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{{
Type: IntegrationSinkConditionAddressable,
Status: corev1.ConditionFalse,
}},
},
},
want: &IntegrationSinkStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{{
Type: IntegrationSinkConditionAddressable,
Status: corev1.ConditionFalse,
}, {
Type: IntegrationSinkConditionDeploymentReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionEventPoliciesReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionReady,
Status: corev1.ConditionUnknown,
}},
},
},
}, {
name: "one true",
js: &IntegrationSinkStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{{
Type: IntegrationSinkConditionAddressable,
Status: corev1.ConditionTrue,
}},
},
},
want: &IntegrationSinkStatus{
Status: duckv1.Status{
Conditions: []apis.Condition{{
Type: IntegrationSinkConditionAddressable,
Status: corev1.ConditionTrue,
}, {
Type: IntegrationSinkConditionDeploymentReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionEventPoliciesReady,
Status: corev1.ConditionUnknown,
}, {
Type: IntegrationSinkConditionReady,
Status: corev1.ConditionUnknown,
}},
},
},
}}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.js.InitializeConditions()
if diff := cmp.Diff(test.want, test.js, ignoreAllButTypeAndStatus); diff != "" {
t.Error("unexpected conditions (-want, +got) =", diff)
}
})
}
}

View File

@ -1,118 +0,0 @@
/*
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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"knative.dev/eventing/pkg/apis/common/integration/v1alpha1"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
"knative.dev/pkg/apis"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/kmeta"
)
// +genclient
// +genreconciler
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:defaulter-gen=true
// IntegrationSink is the Schema for the IntegrationSink API.
type IntegrationSink struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec IntegrationSinkSpec `json:"spec,omitempty"`
Status IntegrationSinkStatus `json:"status,omitempty"`
}
// Check the interfaces that IntegrationSink should be implementing.
var (
_ runtime.Object = (*IntegrationSink)(nil)
_ kmeta.OwnerRefable = (*IntegrationSink)(nil)
_ apis.Validatable = (*IntegrationSink)(nil)
_ apis.Defaultable = (*IntegrationSink)(nil)
_ apis.HasSpec = (*IntegrationSink)(nil)
_ duckv1.KRShaped = (*IntegrationSink)(nil)
_ apis.Convertible = (*IntegrationSink)(nil)
)
type IntegrationSinkSpec struct {
Aws *Aws `json:"aws,omitempty"` // AWS source configuration
Log *Log `json:"log,omitempty"` // Log sink configuration
}
type Log struct {
LoggerName string `json:"loggerName,omitempty" default:"log-sink"` // Name of the logging category to use
Level string `json:"level,omitempty" default:"INFO"` // Logging level to use
LogMask bool `json:"logMask,omitempty" default:"false"` // Mask sensitive information in the log
Marker string `json:"marker,omitempty"` // An optional Marker name to use
Multiline bool `json:"multiline,omitempty" default:"false"` // If enabled, outputs each information on a newline
ShowAllProperties bool `json:"showAllProperties,omitempty" default:"false"` // Show all of the exchange properties (both internal and custom)
ShowBody bool `json:"showBody,omitempty" default:"true"` // Show the message body
ShowBodyType bool `json:"showBodyType,omitempty" default:"true"` // Show the body Java type
ShowExchangePattern bool `json:"showExchangePattern,omitempty" default:"true"` // Show the Message Exchange Pattern (MEP)
ShowHeaders bool `json:"showHeaders,omitempty" default:"false"` // Show the headers received
ShowProperties bool `json:"showProperties,omitempty" default:"false"` // Show the exchange properties (only custom)
ShowStreams bool `json:"showStreams,omitempty" default:"false"` // Show the stream bodies
ShowCachedStreams bool `json:"showCachedStreams,omitempty" default:"true"` // Show cached stream bodies
}
type Aws struct {
S3 *v1alpha1.AWSS3 `json:"s3,omitempty"` // S3 source configuration
SQS *v1alpha1.AWSSQS `json:"sqs,omitempty"` // SQS source configuration
SNS *v1alpha1.AWSSNS `json:"sns,omitempty"` // SNS source configuration
Auth *v1alpha1.Auth `json:"auth,omitempty"`
}
type IntegrationSinkStatus struct {
duckv1.Status `json:",inline"`
// AddressStatus is the part where the JobSink fulfills the Addressable contract.
// It exposes the endpoint as an URI to get events delivered.
// +optional
duckv1.AddressStatus `json:",inline"`
// AppliedEventPoliciesStatus contains the list of EventPolicies which apply to this JobSink
// +optional
eventingduckv1.AppliedEventPoliciesStatus `json:",inline"`
}
// GetGroupVersionKind returns the GroupVersionKind.
func (*IntegrationSink) GetGroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind("IntegrationSink")
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// IntegrationSinkList contains a list of IntegrationSink
type IntegrationSinkList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []IntegrationSink `json:"items"`
}
// GetUntypedSpec returns the spec of the IntegrationSink.
func (c *IntegrationSink) GetUntypedSpec() interface{} {
return c.Spec
}
// GetStatus retrieves the status of the IntegrationSink. Implements the KRShaped interface.
func (c *IntegrationSink) GetStatus() *duckv1.Status {
return &c.Status.Status
}

View File

@ -1,122 +0,0 @@
/*
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 v1alpha1
import (
"testing"
"knative.dev/eventing/pkg/apis/common/integration/v1alpha1"
)
func TestIntegrationSink_GetStatus(t *testing.T) {
r := &IntegrationSink{
Status: IntegrationSinkStatus{},
}
if got, want := r.GetStatus(), &r.Status.Status; got != want {
t.Errorf("GetStatus=%v, want=%v", got, want)
}
}
func TestIntegrationSink_GetGroupVersionKind(t *testing.T) {
src := &IntegrationSink{}
gvk := src.GetGroupVersionKind()
if gvk.Kind != "IntegrationSink" {
t.Errorf("Should be IntegrationSink.")
}
}
func TestLog(t *testing.T) {
log := Log{
Level: "info",
ShowHeaders: true,
}
if log.Level != "info" {
t.Errorf("Log.Level = %v, want 'info'", log.Level)
}
if log.ShowHeaders != true {
t.Errorf("Log.ShowHeaders = %v, want 'false'", log.ShowHeaders)
}
}
func TestAWS(t *testing.T) {
s3 := v1alpha1.AWSS3{
AWSCommon: v1alpha1.AWSCommon{
Region: "eu-north-1",
},
Arn: "example-bucket",
}
if s3.Region != "eu-north-1" {
t.Errorf("AWSS3.Region = %v, want 'eu-north-1'", s3.Region)
}
sqs := v1alpha1.AWSSQS{
AWSCommon: v1alpha1.AWSCommon{
Region: "eu-north-1",
},
Arn: "example-queue",
}
if sqs.Region != "eu-north-1" {
t.Errorf("AWSSQS.Region = %v, want 'eu-north-1'", sqs.Region)
}
ddbStreams := v1alpha1.AWSDDBStreams{
AWSCommon: v1alpha1.AWSCommon{
Region: "eu-north-1",
},
Table: "example-table",
}
if ddbStreams.Region != "eu-north-1" {
t.Errorf("AWSDDBStreams.Region = %v, want 'eu-north-1'", ddbStreams.Region)
}
sns := v1alpha1.AWSSNS{
AWSCommon: v1alpha1.AWSCommon{
Region: "eu-north-1",
},
Arn: "example-topic",
}
if sns.Region != "eu-north-1" {
t.Errorf("AWSDDBStreams.Region = %v, want 'eu-north-1'", sns.Region)
}
}
// TestAuthFieldAccess tests the HasAuth method and field access in Auth struct
func TestAuthFieldAccess(t *testing.T) {
auth := v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
AccessKey: "access-key",
SecretKey: "secret-key",
}
if !auth.HasAuth() {
t.Error("Auth.HasAuth() = false, want true")
}
if auth.Secret.Ref.Name != "aws-secret" {
t.Errorf("Auth.Secret.Ref.Name = %v, want 'aws-secret'", auth.Secret.Ref.Name)
}
}

View File

@ -1,97 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"knative.dev/pkg/apis"
)
func (sink *IntegrationSink) Validate(ctx context.Context) *apis.FieldError {
ctx = apis.WithinParent(ctx, sink.ObjectMeta)
return sink.Spec.Validate(ctx).ViaField("spec")
}
func (spec *IntegrationSinkSpec) Validate(ctx context.Context) *apis.FieldError {
var errs *apis.FieldError
// Count how many fields are set to ensure mutual exclusivity
sinkSetCount := 0
if spec.Log != nil {
sinkSetCount++
}
if spec.Aws != nil {
if spec.Aws.S3 != nil {
sinkSetCount++
}
if spec.Aws.SQS != nil {
sinkSetCount++
}
if spec.Aws.SNS != nil {
sinkSetCount++
}
}
// Validate that only one sink field is set
if sinkSetCount > 1 {
errs = errs.Also(apis.ErrGeneric("only one sink type can be set", "spec"))
} else if sinkSetCount == 0 {
errs = errs.Also(apis.ErrGeneric("at least one sink type must be specified", "spec"))
}
// Only perform AWS-specific validation if exactly one AWS sink is configured
if sinkSetCount == 1 && spec.Aws != nil {
if spec.Aws.S3 != nil || spec.Aws.SQS != nil || spec.Aws.SNS != nil {
// Check that AWS Auth is properly configured
if !spec.Aws.Auth.HasAuth() {
errs = errs.Also(apis.ErrMissingField("aws.auth.secret.ref.name"))
}
}
// Additional validation for AWS S3 required fields
if spec.Aws.S3 != nil {
if spec.Aws.S3.Arn == "" {
errs = errs.Also(apis.ErrMissingField("aws.s3.arn"))
}
if spec.Aws.S3.Region == "" {
errs = errs.Also(apis.ErrMissingField("aws.s3.region"))
}
}
// Additional validation for AWS SQS required fields
if spec.Aws.SQS != nil {
if spec.Aws.SQS.Arn == "" {
errs = errs.Also(apis.ErrMissingField("aws.sqs.arn"))
}
if spec.Aws.SQS.Region == "" {
errs = errs.Also(apis.ErrMissingField("aws.sqs.region"))
}
}
// Additional validation for AWS SNS required fields
if spec.Aws.SNS != nil {
if spec.Aws.SNS.Arn == "" {
errs = errs.Also(apis.ErrMissingField("aws.sns.arn"))
}
if spec.Aws.SNS.Region == "" {
errs = errs.Also(apis.ErrMissingField("aws.sns.region"))
}
}
}
return errs
}

View File

@ -1,219 +0,0 @@
/*
Copyright 2020 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 v1alpha1
import (
"context"
"testing"
"knative.dev/eventing/pkg/apis/common/integration/v1alpha1"
"github.com/google/go-cmp/cmp"
"knative.dev/pkg/apis"
)
func TestIntegrationSinkSpecValidation(t *testing.T) {
tests := []struct {
name string
spec IntegrationSinkSpec
want *apis.FieldError
}{
{
name: "valid log sink",
spec: IntegrationSinkSpec{
Log: &Log{
Level: "info",
ShowHeaders: true,
},
},
want: nil,
},
{
name: "valid AWS S3 sink with auth and region",
spec: IntegrationSinkSpec{
Aws: &Aws{
S3: &v1alpha1.AWSS3{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-bucket",
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: nil,
},
{
name: "valid AWS SQS sink with auth and region",
spec: IntegrationSinkSpec{
Aws: &Aws{
SQS: &v1alpha1.AWSSQS{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-queue",
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: nil,
},
{
name: "multiple sinks set (invalid)",
spec: IntegrationSinkSpec{
Log: &Log{
Level: "info",
ShowHeaders: true,
},
Aws: &Aws{
S3: &v1alpha1.AWSS3{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-bucket",
},
},
},
want: apis.ErrGeneric("only one sink type can be set", "spec"),
},
{
name: "multiple AWS sinks set (invalid)",
spec: IntegrationSinkSpec{
Aws: &Aws{
S3: &v1alpha1.AWSS3{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-bucket",
},
SQS: &v1alpha1.AWSSQS{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-queue",
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: apis.ErrGeneric("only one sink type can be set", "spec"),
},
{
name: "AWS SQS sink without QueueNameOrArn (invalid)",
spec: IntegrationSinkSpec{
Aws: &Aws{
SQS: &v1alpha1.AWSSQS{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: apis.ErrMissingField("aws.sqs.arn"),
},
{
name: "AWS SNS sink without TopicNameOrArn (invalid)",
spec: IntegrationSinkSpec{
Aws: &Aws{
SNS: &v1alpha1.AWSSNS{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: apis.ErrMissingField("aws.sns.arn"),
},
{
name: "no sink type specified (invalid)",
spec: IntegrationSinkSpec{},
want: apis.ErrGeneric("at least one sink type must be specified", "spec"),
},
{
name: "AWS sink without auth (invalid)",
spec: IntegrationSinkSpec{
Aws: &Aws{
S3: &v1alpha1.AWSS3{
AWSCommon: v1alpha1.AWSCommon{
Region: "us-east-1",
},
Arn: "example-bucket",
},
},
},
want: apis.ErrMissingField("aws.auth.secret.ref.name"),
},
{
name: "AWS S3 sink without region (invalid)",
spec: IntegrationSinkSpec{
Aws: &Aws{
S3: &v1alpha1.AWSS3{
Arn: "example-bucket",
},
Auth: &v1alpha1.Auth{
Secret: &v1alpha1.Secret{
Ref: &v1alpha1.SecretReference{
Name: "aws-secret",
},
},
},
},
},
want: apis.ErrMissingField("aws.s3.region"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := test.spec.Validate(context.TODO())
if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" {
t.Errorf("IntegrationSinkSpec.Validate (-want, +got) = %v", diff)
}
})
}
}

View File

@ -18,48 +18,7 @@ package v1alpha1
import (
"context"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
)
func (sink *JobSink) SetDefaults(ctx context.Context) {
if sink.Spec.Job != nil {
setBatchJobDefaults(sink.Spec.Job)
}
}
func setBatchJobDefaults(job *batchv1.Job) {
for i := range job.Spec.Template.Spec.Containers {
executionModeFound := false
for j := range job.Spec.Template.Spec.Containers[i].Env {
if job.Spec.Template.Spec.Containers[i].Env[j].Name == ExecutionModeEnvVar {
executionModeFound = true
break
}
}
if executionModeFound {
continue
}
job.Spec.Template.Spec.Containers[i].Env = append(job.Spec.Template.Spec.Containers[i].Env, corev1.EnvVar{
Name: ExecutionModeEnvVar,
Value: string(ExecutionModeBatch),
})
}
for i := range job.Spec.Template.Spec.InitContainers {
executionModeFound := false
for j := range job.Spec.Template.Spec.InitContainers[i].Env {
if job.Spec.Template.Spec.InitContainers[i].Env[j].Name == ExecutionModeEnvVar {
executionModeFound = true
break
}
}
if executionModeFound {
continue
}
job.Spec.Template.Spec.InitContainers[i].Env = append(job.Spec.Template.Spec.InitContainers[i].Env, corev1.EnvVar{
Name: ExecutionModeEnvVar,
Value: string(ExecutionModeBatch),
})
}
}

View File

@ -21,111 +21,13 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
)
func TestSetDefaults(t *testing.T) {
testCases := map[string]struct {
initial JobSink
expected JobSink
}{
"execution mode": {
initial: JobSink{
Spec: JobSinkSpec{
Job: &batchv1.Job{
Spec: batchv1.JobSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "cnt",
Image: "img",
},
{
Name: "cnt2",
Image: "img2",
},
{
Name: "cnt3",
Image: "img3",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "something"},
},
},
},
InitContainers: []corev1.Container{
{
Name: "cnt",
Image: "img",
},
{
Name: "cnt-ini2",
Image: "img-ini2",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "something"},
},
},
},
},
},
},
},
},
},
expected: JobSink{
Spec: JobSinkSpec{
Job: &batchv1.Job{
Spec: batchv1.JobSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
InitContainers: []corev1.Container{
{
Name: "cnt",
Image: "img",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "batch"},
},
},
{
Name: "cnt-ini2",
Image: "img-ini2",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "something"},
},
},
},
Containers: []corev1.Container{
{
Name: "cnt",
Image: "img",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "batch"},
},
},
{
Name: "cnt2",
Image: "img2",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "batch"},
},
},
{
Name: "cnt3",
Image: "img3",
Env: []corev1.EnvVar{
{Name: "K_EXECUTION_MODE", Value: "something"},
},
},
},
},
},
},
},
},
},
},
}
}{}
for n, tc := range testCases {
t.Run(n, func(t *testing.T) {
tc.initial.SetDefaults(context.TODO())

View File

@ -22,20 +22,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
duckv1 "knative.dev/pkg/apis/duck/v1"
"knative.dev/pkg/kmeta"
eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
)
const (
ExecutionModeEnvVar = "K_EXECUTION_MODE"
)
type ExecutionMode string
const (
ExecutionModeBatch ExecutionMode = "batch"
)
// +genclient

View File

@ -47,8 +47,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&JobSink{},
&JobSinkList{},
&IntegrationSink{},
&IntegrationSinkList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@ -62,8 +62,6 @@ func TestKnownTypes(t *testing.T) {
for _, name := range []string{
"JobSink",
"JobSinkList",
"IntegrationSink",
"IntegrationSinkList",
} {
if _, ok := types[name]; !ok {
t.Errorf("Did not find %q as registered type", name)

View File

@ -24,151 +24,8 @@ package v1alpha1
import (
v1 "k8s.io/api/batch/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
integrationv1alpha1 "knative.dev/eventing/pkg/apis/common/integration/v1alpha1"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Aws) DeepCopyInto(out *Aws) {
*out = *in
if in.S3 != nil {
in, out := &in.S3, &out.S3
*out = new(integrationv1alpha1.AWSS3)
**out = **in
}
if in.SQS != nil {
in, out := &in.SQS, &out.SQS
*out = new(integrationv1alpha1.AWSSQS)
**out = **in
}
if in.SNS != nil {
in, out := &in.SNS, &out.SNS
*out = new(integrationv1alpha1.AWSSNS)
**out = **in
}
if in.Auth != nil {
in, out := &in.Auth, &out.Auth
*out = new(integrationv1alpha1.Auth)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Aws.
func (in *Aws) DeepCopy() *Aws {
if in == nil {
return nil
}
out := new(Aws)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IntegrationSink) DeepCopyInto(out *IntegrationSink) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationSink.
func (in *IntegrationSink) DeepCopy() *IntegrationSink {
if in == nil {
return nil
}
out := new(IntegrationSink)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IntegrationSink) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IntegrationSinkList) DeepCopyInto(out *IntegrationSinkList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]IntegrationSink, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationSinkList.
func (in *IntegrationSinkList) DeepCopy() *IntegrationSinkList {
if in == nil {
return nil
}
out := new(IntegrationSinkList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IntegrationSinkList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IntegrationSinkSpec) DeepCopyInto(out *IntegrationSinkSpec) {
*out = *in
if in.Aws != nil {
in, out := &in.Aws, &out.Aws
*out = new(Aws)
(*in).DeepCopyInto(*out)
}
if in.Log != nil {
in, out := &in.Log, &out.Log
*out = new(Log)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationSinkSpec.
func (in *IntegrationSinkSpec) DeepCopy() *IntegrationSinkSpec {
if in == nil {
return nil
}
out := new(IntegrationSinkSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IntegrationSinkStatus) DeepCopyInto(out *IntegrationSinkStatus) {
*out = *in
in.Status.DeepCopyInto(&out.Status)
in.AddressStatus.DeepCopyInto(&out.AddressStatus)
in.AppliedEventPoliciesStatus.DeepCopyInto(&out.AppliedEventPoliciesStatus)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationSinkStatus.
func (in *IntegrationSinkStatus) DeepCopy() *IntegrationSinkStatus {
if in == nil {
return nil
}
out := new(IntegrationSinkStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JobSink) DeepCopyInto(out *JobSink) {
*out = *in
@ -286,19 +143,3 @@ func (in *JobStatus) DeepCopy() *JobStatus {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Log) DeepCopyInto(out *Log) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Log.
func (in *Log) DeepCopy() *Log {
if in == nil {
return nil
}
out := new(Log)
in.DeepCopyInto(out)
return out
}

View File

@ -22,7 +22,6 @@ limitations under the License.
package v1alpha1
import (
v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@ -36,51 +35,6 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_JobSink(in *JobSink) {
if in.Spec.Job != nil {
for i := range in.Spec.Job.Spec.Template.Spec.Volumes {
a := &in.Spec.Job.Spec.Template.Spec.Volumes[i]
if a.VolumeSource.ISCSI != nil {
if a.VolumeSource.ISCSI.ISCSIInterface == "" {
a.VolumeSource.ISCSI.ISCSIInterface = "default"
}
}
if a.VolumeSource.RBD != nil {
if a.VolumeSource.RBD.RBDPool == "" {
a.VolumeSource.RBD.RBDPool = "rbd"
}
if a.VolumeSource.RBD.RadosUser == "" {
a.VolumeSource.RBD.RadosUser = "admin"
}
if a.VolumeSource.RBD.Keyring == "" {
a.VolumeSource.RBD.Keyring = "/etc/ceph/keyring"
}
}
if a.VolumeSource.AzureDisk != nil {
if a.VolumeSource.AzureDisk.CachingMode == nil {
ptrVar1 := v1.AzureDataDiskCachingMode(v1.AzureDataDiskCachingReadWrite)
a.VolumeSource.AzureDisk.CachingMode = &ptrVar1
}
if a.VolumeSource.AzureDisk.FSType == nil {
var ptrVar1 string = "ext4"
a.VolumeSource.AzureDisk.FSType = &ptrVar1
}
if a.VolumeSource.AzureDisk.ReadOnly == nil {
var ptrVar1 bool = false
a.VolumeSource.AzureDisk.ReadOnly = &ptrVar1
}
if a.VolumeSource.AzureDisk.Kind == nil {
ptrVar1 := v1.AzureDataDiskKind(v1.AzureSharedBlobDisk)
a.VolumeSource.AzureDisk.Kind = &ptrVar1
}
}
if a.VolumeSource.ScaleIO != nil {
if a.VolumeSource.ScaleIO.StorageMode == "" {
a.VolumeSource.ScaleIO.StorageMode = "ThinProvisioned"
}
if a.VolumeSource.ScaleIO.FSType == "" {
a.VolumeSource.ScaleIO.FSType = "xfs"
}
}
}
for i := range in.Spec.Job.Spec.Template.Spec.InitContainers {
a := &in.Spec.Job.Spec.Template.Spec.InitContainers[i]
for j := range a.Ports {

View File

@ -16,8 +16,6 @@ limitations under the License.
package sources
//nolint:staticcheck // Not capitalizing "API" everywhere in this file
const (
// ApiServerSourceAddEventType is the ApiServerSource CloudEvent type for adds.
ApiServerSourceAddEventType = "dev.knative.apiserver.resource.add"

Some files were not shown because too many files have changed in this diff Show More