From 7f37d64498639449fcebc5d0d63e5f2e94678fc8 Mon Sep 17 00:00:00 2001 From: Pierangelo Di Pilato Date: Wed, 12 Jun 2024 13:27:00 +0200 Subject: [PATCH] Add EventPolicy types (#7995) * Add EventPolicy types Signed-off-by: Pierangelo Di Pilato * Run hack/update-codegen.sh Signed-off-by: Pierangelo Di Pilato * Add EventPolicy CRD Signed-off-by: Pierangelo Di Pilato * Fix boilerplate / style Signed-off-by: Pierangelo Di Pilato --------- Signed-off-by: Pierangelo Di Pilato --- cmd/schema/main.go | 2 + config/core/resources/eventpolicy.yaml | 181 +++++++ docs/eventing-api.md | 454 ++++++++++++++++++ hack/update-codegen.sh | 4 +- pkg/apis/eventing/v1alpha1/doc.go | 20 + .../v1alpha1/eventpolicy_conversion.go | 34 ++ .../v1alpha1/eventpolicy_conversion_test.go | 34 ++ .../eventing/v1alpha1/eventpolicy_defaults.go | 31 ++ .../v1alpha1/eventpolicy_defaults_test.go | 44 ++ .../v1alpha1/eventpolicy_lifecycle.go | 52 ++ .../v1alpha1/eventpolicy_lifecycle_test.go | 107 +++++ .../eventing/v1alpha1/eventpolicy_types.go | 168 +++++++ .../v1alpha1/eventpolicy_types_test.go | 39 ++ .../v1alpha1/eventpolicy_validation.go | 86 ++++ .../v1alpha1/eventpolicy_validation_test.go | 209 ++++++++ pkg/apis/eventing/v1alpha1/register.go | 53 ++ pkg/apis/eventing/v1alpha1/register_test.go | 52 ++ .../v1alpha1/zz_generated.deepcopy.go | 250 ++++++++++ pkg/client/clientset/versioned/clientset.go | 31 +- .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../versioned/typed/eventing/v1alpha1/doc.go | 20 + .../eventing/v1alpha1/eventing_client.go | 107 +++++ .../typed/eventing/v1alpha1/eventpolicy.go | 195 ++++++++ .../typed/eventing/v1alpha1/fake/doc.go | 20 + .../v1alpha1/fake/fake_eventing_client.go | 40 ++ .../v1alpha1/fake/fake_eventpolicy.go | 141 ++++++ .../eventing/v1alpha1/generated_expansion.go | 21 + .../externalversions/eventing/interface.go | 8 + .../eventing/v1alpha1/eventpolicy.go | 90 ++++ .../eventing/v1alpha1/interface.go | 45 ++ .../informers/externalversions/generic.go | 9 +- .../v1alpha1/eventpolicy/eventpolicy.go | 52 ++ .../v1alpha1/eventpolicy/fake/fake.go | 40 ++ .../eventpolicy/filtered/eventpolicy.go | 65 +++ .../eventpolicy/filtered/fake/fake.go | 52 ++ .../v1alpha1/eventpolicy/controller.go | 170 +++++++ .../v1alpha1/eventpolicy/reconciler.go | 440 +++++++++++++++++ .../eventing/v1alpha1/eventpolicy/state.go | 97 ++++ .../listers/eventing/v1alpha1/eventpolicy.go | 99 ++++ .../eventing/v1alpha1/expansion_generated.go | 27 ++ 42 files changed, 3587 insertions(+), 13 deletions(-) create mode 100644 config/core/resources/eventpolicy.yaml create mode 100644 pkg/apis/eventing/v1alpha1/doc.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_conversion.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_conversion_test.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_defaults.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_defaults_test.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle_test.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_types.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_types_test.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_validation.go create mode 100644 pkg/apis/eventing/v1alpha1/eventpolicy_validation_test.go create mode 100644 pkg/apis/eventing/v1alpha1/register.go create mode 100644 pkg/apis/eventing/v1alpha1/register_test.go create mode 100644 pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventing_client.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventpolicy.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventing_client.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventpolicy.go create mode 100644 pkg/client/clientset/versioned/typed/eventing/v1alpha1/generated_expansion.go create mode 100644 pkg/client/informers/externalversions/eventing/v1alpha1/eventpolicy.go create mode 100644 pkg/client/informers/externalversions/eventing/v1alpha1/interface.go create mode 100644 pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/eventpolicy.go create mode 100644 pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/fake/fake.go create mode 100644 pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/eventpolicy.go create mode 100644 pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/fake/fake.go create mode 100644 pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/controller.go create mode 100644 pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/reconciler.go create mode 100644 pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/state.go create mode 100644 pkg/client/listers/eventing/v1alpha1/eventpolicy.go create mode 100644 pkg/client/listers/eventing/v1alpha1/expansion_generated.go diff --git a/cmd/schema/main.go b/cmd/schema/main.go index 62b58d42937..2c38476a3cb 100644 --- a/cmd/schema/main.go +++ b/cmd/schema/main.go @@ -23,6 +23,7 @@ import ( "knative.dev/hack/schema/registry" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1 "knative.dev/eventing/pkg/apis/flows/v1" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" @@ -47,6 +48,7 @@ func main() { // Flows registry.Register(&flowsv1.Sequence{}) registry.Register(&flowsv1.Parallel{}) + registry.Register(&eventingv1alpha1.EventPolicy{}) if err := commands.New("knative.dev/eventing").Execute(); err != nil { log.Fatal("Error during command execution: ", err) diff --git a/config/core/resources/eventpolicy.yaml b/config/core/resources/eventpolicy.yaml new file mode 100644 index 00000000000..159d379e5bb --- /dev/null +++ b/config/core/resources/eventpolicy.yaml @@ -0,0 +1,181 @@ +# 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: eventpolicies.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 EventPolicy. + type: object + properties: + from: + description: From is the list of sources or oidc identities, which are allowed to send events to the targets (.spec.to). + type: array + items: + type: object + properties: + ref: + description: Ref contains a direct reference to a resource which is allowed to send events to the target. + 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 + sub: + description: Sub sets the OIDC identity name to be allowed to send events to the target. It is also possible to set a glob-like pattern to match any suffix. + type: string + to: + description: To lists all resources for which this policy applies. Resources in this list must act like an ingress and have an audience. The resources are part of the same namespace as the EventPolicy. An empty list means it applies to all resources in the EventPolicies namespace + type: array + items: + type: object + properties: + ref: + description: Ref contains the direct reference to a target + 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 + selector: + description: Selector contains a selector to group targets + type: object + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + type: object + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + x-kubernetes-preserve-unknown-fields: true + status: + description: Status represents the current state of the EventPolicy. 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 + from: + description: From is the list of resolved oidc identities from .spec.from + type: array + items: + type: string + observedGeneration: + description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller. + type: integer + format: int64 + + additionalPrinterColumns: + - name: Ready + type: string + jsonPath: ".status.conditions[?(@.type==\"Ready\")].status" + - name: Reason + type: string + jsonPath: ".status.conditions[?(@.type==\"Ready\")].reason" + names: + kind: EventPolicy + plural: eventpolicies + singular: eventpolicy + categories: + - all + - knative + - eventing + scope: Namespaced + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + service: + name: eventing-webhook + namespace: knative-eventing diff --git a/docs/eventing-api.md b/docs/eventing-api.md index 6bec7a309d8..091344ae66c 100644 --- a/docs/eventing-api.md +++ b/docs/eventing-api.md @@ -13,6 +13,9 @@ eventing.knative.dev/v1
  • +eventing.knative.dev/v1alpha1 +
  • +
  • eventing.knative.dev/v1beta1
  • @@ -2488,6 +2491,457 @@ knative.dev/pkg/apis/duck/v1.AuthStatus
    +

    eventing.knative.dev/v1alpha1

    +

    +

    Package v1alpha1 is the v1alpha1 version of the API.

    +

    +Resource Types: + +

    EventPolicy +

    +

    +

    EventPolicy represents a policy for addressable resources (Broker, Channel, sinks).

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +eventing.knative.dev/v1alpha1 + +
    +kind
    +string +
    EventPolicy
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +(Optional) +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +EventPolicySpec + + +
    +

    Spec defines the desired state of the EventPolicy.

    +
    +
    + + + + + + + + + +
    +to
    + + +[]EventPolicySpecTo + + +
    +(Optional) +

    To lists all resources for which this policy applies. +Resources in this list must act like an ingress and have an audience. +The resources are part of the same namespace as the EventPolicy. +An empty list means it applies to all resources in the EventPolicies namespace

    +
    +from
    + + +[]EventPolicySpecFrom + + +
    +

    From is the list of sources or oidc identities, which are allowed to send events to the targets (.spec.to).

    +
    +
    +status
    + + +EventPolicyStatus + + +
    +(Optional) +

    Status represents the current state of the EventPolicy. +This data may be out of date.

    +
    +

    EventPolicyFromReference +

    +

    +(Appears on:EventPolicySpecFrom) +

    +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    + +string + +
    +

    API version of the referent.

    +
    +kind
    + +string + +
    +

    Kind of the referent. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

    +
    +name
    + +string + +
    +

    Name of the referent. +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

    +
    +namespace
    + +string + +
    +(Optional) +

    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.

    +
    +

    EventPolicySelector +

    +

    +(Appears on:EventPolicySpecTo) +

    +

    +

    + + + + + + + + + + + + + +
    FieldDescription
    +LabelSelector
    + + +Kubernetes meta/v1.LabelSelector + + +
    +

    +(Members of LabelSelector are embedded into this type.) +

    +
    +

    EventPolicySpec +

    +

    +(Appears on:EventPolicy) +

    +

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +to
    + + +[]EventPolicySpecTo + + +
    +(Optional) +

    To lists all resources for which this policy applies. +Resources in this list must act like an ingress and have an audience. +The resources are part of the same namespace as the EventPolicy. +An empty list means it applies to all resources in the EventPolicies namespace

    +
    +from
    + + +[]EventPolicySpecFrom + + +
    +

    From is the list of sources or oidc identities, which are allowed to send events to the targets (.spec.to).

    +
    +

    EventPolicySpecFrom +

    +

    +(Appears on:EventPolicySpec) +

    +

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +ref
    + + +EventPolicyFromReference + + +
    +(Optional) +

    Ref contains a direct reference to a resource which is allowed to send events to the target.

    +
    +sub
    + +string + +
    +(Optional) +

    Sub sets the OIDC identity name to be allowed to send events to the target. +It is also possible to set a glob-like pattern to match any suffix.

    +
    +

    EventPolicySpecTo +

    +

    +(Appears on:EventPolicySpec) +

    +

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +ref
    + + +EventPolicyToReference + + +
    +(Optional) +

    Ref contains the direct reference to a target

    +
    +selector
    + + +EventPolicySelector + + +
    +(Optional) +

    Selector contains a selector to group targets

    +
    +

    EventPolicyStatus +

    +

    +(Appears on:EventPolicy) +

    +

    +

    EventPolicyStatus represents the current state of a EventPolicy.

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +Status
    + + +knative.dev/pkg/apis/duck/v1.Status + + +
    +

    +(Members of Status are embedded into this type.) +

    +

    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.

    +
    +from
    + +[]string + +
    +

    From is the list of resolved oidc identities from .spec.from

    +
    +

    EventPolicyToReference +

    +

    +(Appears on:EventPolicySpecTo) +

    +

    +

    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    + +string + +
    +

    API version of the referent.

    +
    +kind
    + +string + +
    +

    Kind of the referent. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

    +
    +name
    + +string + +
    +

    Name of the referent. +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

    +
    +

    eventing.knative.dev/v1beta1

    Package v1beta1 is the v1beta1 version of the API.

    diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 3020dd85815..fdeb803f9ca 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -38,7 +38,7 @@ group "Kubernetes Codegen" # instead of the $GOPATH directly. For normal projects this can be dropped. ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \ - "sinks:v1alpha1 eventing:v1beta1 eventing:v1beta2 eventing:v1beta3 eventing:v1 messaging:v1 flows:v1 sources:v1beta2 sources:v1" \ + "sinks:v1alpha1 eventing:v1alpha1 eventing:v1beta1 eventing:v1beta2 eventing:v1beta3 eventing:v1 messaging:v1 flows:v1 sources:v1beta2 sources:v1" \ --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt # Deep copy config @@ -59,7 +59,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:v1beta1 eventing:v1beta2 eventing:v1beta3 eventing:v1 messaging:v1 flows:v1 sources:v1beta2 sources:v1 duck:v1beta1 duck:v1" \ + "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" diff --git a/pkg/apis/eventing/v1alpha1/doc.go b/pkg/apis/eventing/v1alpha1/doc.go new file mode 100644 index 00000000000..1f222246309 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package +// +groupName=eventing.knative.dev +package v1alpha1 diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_conversion.go b/pkg/apis/eventing/v1alpha1/eventpolicy_conversion.go new file mode 100644 index 00000000000..ed74482e2d4 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_conversion.go @@ -0,0 +1,34 @@ +/* +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 *EventPolicy) 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 *EventPolicy) ConvertFrom(ctx context.Context, obj apis.Convertible) error { + return fmt.Errorf("v1alpha1 is the highest known version, got: %T", obj) +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_conversion_test.go b/pkg/apis/eventing/v1alpha1/eventpolicy_conversion_test.go new file mode 100644 index 00000000000..31188a862ee --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_conversion_test.go @@ -0,0 +1,34 @@ +/* +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" +) + +func TestEventPolicyConversionHighestVersion(t *testing.T) { + good, bad := &EventPolicy{}, &EventPolicy{} + + 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) + } +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_defaults.go b/pkg/apis/eventing/v1alpha1/eventpolicy_defaults.go new file mode 100644 index 00000000000..3e52f5bd482 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_defaults.go @@ -0,0 +1,31 @@ +/* +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 (ep *EventPolicy) SetDefaults(ctx context.Context) { + ctx = apis.WithinParent(ctx, ep.ObjectMeta) + ep.Spec.SetDefaults(ctx) +} + +func (ets *EventPolicySpec) SetDefaults(ctx context.Context) { +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_defaults_test.go b/pkg/apis/eventing/v1alpha1/eventpolicy_defaults_test.go new file mode 100644 index 00000000000..09a377b082b --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_defaults_test.go @@ -0,0 +1,44 @@ +/* +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 TestEventPolicyDefaults(t *testing.T) { + testCases := map[string]struct { + initial EventPolicy + expected EventPolicy + }{ + "nil spec": { + initial: EventPolicy{}, + expected: EventPolicy{}, + }, + } + 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) + } + }) + } +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle.go b/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle.go new file mode 100644 index 00000000000..30c8575eac9 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle.go @@ -0,0 +1,52 @@ +/* +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 ( + "knative.dev/pkg/apis" +) + +var eventPolicyCondSet = apis.NewLivingConditionSet() + +const ( + EventPolicyConditionReady = apis.ConditionReady +) + +// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface. +func (*EventPolicy) GetConditionSet() apis.ConditionSet { + return eventPolicyCondSet +} + +// GetCondition returns the condition currently associated with the given type, or nil. +func (et *EventPolicyStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return eventPolicyCondSet.Manage(et).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (et *EventPolicyStatus) IsReady() bool { + return et.GetTopLevelCondition().IsTrue() +} + +// GetTopLevelCondition returns the top level Condition. +func (et *EventPolicyStatus) GetTopLevelCondition() *apis.Condition { + return eventPolicyCondSet.Manage(et).GetTopLevelCondition() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (et *EventPolicyStatus) InitializeConditions() { + eventPolicyCondSet.Manage(et).InitializeConditions() +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle_test.go b/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle_test.go new file mode 100644 index 00000000000..1f18f054a1f --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_lifecycle_test.go @@ -0,0 +1,107 @@ +/* +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" + "github.com/google/go-cmp/cmp/cmpopts" + + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +var ( + eventPolicyConditionReady = apis.Condition{ + Type: EventPolicyConditionReady, + Status: corev1.ConditionTrue, + } + + ignoreAllButTypeAndStatus = cmpopts.IgnoreFields( + apis.Condition{}, + "LastTransitionTime", "Message", "Reason", "Severity") +) + +func TestEventPolicyGetConditionSet(t *testing.T) { + r := &EventPolicy{} + + if got, want := r.GetConditionSet().GetTopLevelConditionType(), apis.ConditionReady; got != want { + t.Errorf("GetTopLevelCondition=%v, want=%v", got, want) + } +} + +func TestEventPolicyGetCondition(t *testing.T) { + tests := []struct { + name string + ets *EventPolicyStatus + condQuery apis.ConditionType + want *apis.Condition + }{{ + name: "single condition", + ets: &EventPolicyStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{ + eventPolicyConditionReady, + }, + }, + }, + condQuery: apis.ConditionReady, + want: &eventPolicyConditionReady, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.ets.GetCondition(test.condQuery) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Error("unexpected condition (-want, +got) =", diff) + } + }) + } +} + +func TestEventPolicyInitializeConditions(t *testing.T) { + tests := []struct { + name string + ets *EventPolicyStatus + want *EventPolicyStatus + }{ + { + name: "empty", + ets: &EventPolicyStatus{}, + want: &EventPolicyStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: EventPolicyConditionReady, + Status: corev1.ConditionUnknown, + }, + }, + }, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.ets.InitializeConditions() + if diff := cmp.Diff(test.want, test.ets, ignoreAllButTypeAndStatus); diff != "" { + t.Error("unexpected conditions (-want, +got) =", diff) + } + }) + } +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_types.go b/pkg/apis/eventing/v1alpha1/eventpolicy_types.go new file mode 100644 index 00000000000..53d62653444 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_types.go @@ -0,0 +1,168 @@ +/* +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" +) + +// +genclient +// +genreconciler +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// EventPolicy represents a policy for addressable resources (Broker, Channel, sinks). +type EventPolicy struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the EventPolicy. + Spec EventPolicySpec `json:"spec,omitempty"` + + // Status represents the current state of the EventPolicy. + // This data may be out of date. + // +optional + Status EventPolicyStatus `json:"status,omitempty"` +} + +var ( + // Check that EventPolicy can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*EventPolicy)(nil) + _ apis.Defaultable = (*EventPolicy)(nil) + + // Check that EventPolicy can return its spec untyped. + _ apis.HasSpec = (*EventPolicy)(nil) + + _ runtime.Object = (*EventPolicy)(nil) + + // Check that we can create OwnerReferences to an EventPolicy. + _ kmeta.OwnerRefable = (*EventPolicy)(nil) + + // Check that the type conforms to the duck Knative Resource shape. + _ duckv1.KRShaped = (*EventPolicy)(nil) +) + +type EventPolicySpec struct { + // To lists all resources for which this policy applies. + // Resources in this list must act like an ingress and have an audience. + // The resources are part of the same namespace as the EventPolicy. + // An empty list means it applies to all resources in the EventPolicies namespace + // +optional + To []EventPolicySpecTo `json:"to,omitempty"` + + // From is the list of sources or oidc identities, which are allowed to send events to the targets (.spec.to). + From []EventPolicySpecFrom `json:"from,omitempty"` +} + +type EventPolicySpecTo struct { + // Ref contains the direct reference to a target + // +optional + Ref *EventPolicyToReference `json:"ref,omitempty"` + + // Selector contains a selector to group targets + // +optional + Selector *EventPolicySelector `json:"selector,omitempty"` +} + +type EventPolicySpecFrom struct { + // Ref contains a direct reference to a resource which is allowed to send events to the target. + // +optional + Ref *EventPolicyFromReference `json:"ref,omitempty"` + + // Sub sets the OIDC identity name to be allowed to send events to the target. + // It is also possible to set a glob-like pattern to match any suffix. + // +optional + Sub *string `json:"sub,omitempty"` +} + +type EventPolicyToReference struct { + // API version of the referent. + APIVersion string `json:"apiVersion,omitempty"` + + // Kind of the referent. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Kind string `json:"kind"` + + // Name of the referent. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Name string `json:"name"` +} + +type EventPolicyFromReference struct { + // API version of the referent. + APIVersion string `json:"apiVersion,omitempty"` + + // Kind of the referent. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Kind string `json:"kind"` + + // Name of the referent. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Name string `json:"name"` + + // 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. + // +optional + Namespace string `json:"namespace,omitempty"` +} + +type EventPolicySelector struct { + *metav1.LabelSelector `json:",inline"` + *metav1.TypeMeta `json:",inline"` +} + +// EventPolicyStatus represents the current state of a EventPolicy. +type EventPolicyStatus 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"` + + // From is the list of resolved oidc identities from .spec.from + From []string `json:"from,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// EventPolicyList is a collection of EventPolicy. +type EventPolicyList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []EventPolicy `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for EventPolicy +func (ep *EventPolicy) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("EventPolicy") +} + +// GetUntypedSpec returns the spec of the EventPolicy. +func (ep *EventPolicy) GetUntypedSpec() interface{} { + return ep.Spec +} + +// GetStatus retrieves the status of the EventPolicy. Implements the KRShaped interface. +func (ep *EventPolicy) GetStatus() *duckv1.Status { + return &ep.Status.Status +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_types_test.go b/pkg/apis/eventing/v1alpha1/eventpolicy_types_test.go new file mode 100644 index 00000000000..b8dd6913ebe --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_types_test.go @@ -0,0 +1,39 @@ +/* +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 TestEventPolicyGetStatus(t *testing.T) { + r := &EventPolicy{ + Status: EventPolicyStatus{}, + } + if got, want := r.GetStatus(), &r.Status.Status; got != want { + t.Errorf("GetStatus=%v, want=%v", got, want) + } +} + +func TestEventPolicy_GetGroupVersionKind(t *testing.T) { + src := EventPolicy{} + gvk := src.GetGroupVersionKind() + + if gvk.Kind != "EventPolicy" { + t.Errorf("Should be EventPolicy.") + } +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_validation.go b/pkg/apis/eventing/v1alpha1/eventpolicy_validation.go new file mode 100644 index 00000000000..6c4eafb5caa --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_validation.go @@ -0,0 +1,86 @@ +/* +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 (ep *EventPolicy) Validate(ctx context.Context) *apis.FieldError { + return ep.Spec.Validate(ctx).ViaField("spec") +} + +func (ets *EventPolicySpec) Validate(ctx context.Context) *apis.FieldError { + var err *apis.FieldError + for i, f := range ets.From { + if f.Ref == nil && (f.Sub == nil || *f.Sub == "") { + err = err.Also(apis.ErrMissingOneOf("ref", "sub").ViaFieldIndex("from", i)) + } + if f.Ref != nil && f.Sub != nil { + err = err.Also(apis.ErrMultipleOneOf("ref", "sub").ViaFieldIndex("from", i)) + } + err = err.Also(f.Ref.Validate().ViaField("ref").ViaFieldIndex("from", i)) + } + + for i, t := range ets.To { + if t.Ref == nil && t.Selector == nil { + err = err.Also(apis.ErrMissingOneOf("ref", "selector").ViaFieldIndex("to", i)) + } + if t.Ref != nil && t.Selector != nil { + err = err.Also(apis.ErrMultipleOneOf("ref", "selector").ViaFieldIndex("to", i)) + } + if t.Ref != nil { + err = err.Also(t.Ref.Validate().ViaField("ref").ViaFieldIndex("to", i)) + } + } + + return err +} + +func (r *EventPolicyFromReference) Validate() *apis.FieldError { + if r == nil { + return nil + } + + var err *apis.FieldError + if r.Kind == "" { + err = err.Also(apis.ErrMissingField("kind")) + } + if r.APIVersion == "" { + err = err.Also(apis.ErrMissingField("apiVersion")) + } + if r.Name == "" { + err = err.Also(apis.ErrMissingField("name")) + } + return err +} + +func (r *EventPolicyToReference) Validate() *apis.FieldError { + var err *apis.FieldError + if r.Kind == "" { + err = err.Also(apis.ErrMissingField("kind")) + } + if r.APIVersion == "" { + err = err.Also(apis.ErrMissingField("apiVersion")) + } + if r.Name == "" { + err = err.Also(apis.ErrMissingField("name")) + } + return err +} diff --git a/pkg/apis/eventing/v1alpha1/eventpolicy_validation_test.go b/pkg/apis/eventing/v1alpha1/eventpolicy_validation_test.go new file mode 100644 index 00000000000..c4b388b0291 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/eventpolicy_validation_test.go @@ -0,0 +1,209 @@ +/* +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" + "knative.dev/pkg/ptr" +) + +func TestEventPolicySpecValidation(t *testing.T) { + tests := []struct { + name string + ep *EventPolicy + want *apis.FieldError + }{ + { + name: "valid, empty", + ep: &EventPolicy{ + Spec: EventPolicySpec{}, + }, + want: func() *apis.FieldError { + return nil + }(), + }, + { + name: "invalid, missing from.ref and from.sub", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + From: []EventPolicySpecFrom{{}}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingOneOf("ref", "sub").ViaFieldIndex("from", 0).ViaField("spec") + }(), + }, + { + name: "invalid, from.ref missing name", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + From: []EventPolicySpecFrom{{ + Ref: &EventPolicyFromReference{ + APIVersion: "a", + Kind: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("name").ViaField("ref").ViaFieldIndex("from", 0).ViaField("spec") + }(), + }, + { + name: "invalid, from.ref missing kind", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + From: []EventPolicySpecFrom{{ + Ref: &EventPolicyFromReference{ + APIVersion: "a", + Name: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("kind").ViaField("ref").ViaFieldIndex("from", 0).ViaField("spec") + }(), + }, + { + name: "invalid, from.ref missing apiVersion", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + From: []EventPolicySpecFrom{{ + Ref: &EventPolicyFromReference{ + Kind: "a", + Name: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("apiVersion").ViaField("ref").ViaFieldIndex("from", 0).ViaField("spec") + }(), + }, + { + name: "invalid, bot from.ref and from.sub set", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + From: []EventPolicySpecFrom{{ + Ref: &EventPolicyFromReference{ + APIVersion: "a", + Kind: "b", + Name: "c", + }, + Sub: ptr.String("abc"), + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMultipleOneOf("ref", "sub").ViaFieldIndex("from", 0).ViaField("spec") + }(), + }, + { + name: "invalid, missing to.ref and to.selector", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + To: []EventPolicySpecTo{{}}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingOneOf("ref", "selector").ViaFieldIndex("to", 0).ViaField("spec") + }(), + }, + { + name: "invalid, both to.ref and to.selector set", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + To: []EventPolicySpecTo{ + { + Ref: &EventPolicyToReference{ + APIVersion: "a", + Kind: "b", + Name: "c", + }, + Selector: &EventPolicySelector{}, + }, + }, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMultipleOneOf("ref", "selector").ViaFieldIndex("to", 0).ViaField("spec") + }(), + }, + { + name: "invalid, to.ref missing name", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + To: []EventPolicySpecTo{{ + Ref: &EventPolicyToReference{ + APIVersion: "a", + Kind: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("name").ViaField("ref").ViaFieldIndex("to", 0).ViaField("spec") + }(), + }, + { + name: "invalid, to.ref missing kind", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + To: []EventPolicySpecTo{{ + Ref: &EventPolicyToReference{ + APIVersion: "a", + Name: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("kind").ViaField("ref").ViaFieldIndex("to", 0).ViaField("spec") + }(), + }, + { + name: "invalid, to.ref missing apiVersion", + ep: &EventPolicy{ + Spec: EventPolicySpec{ + To: []EventPolicySpecTo{{ + Ref: &EventPolicyToReference{ + Kind: "a", + Name: "b", + }, + }}, + }, + }, + want: func() *apis.FieldError { + return apis.ErrMissingField("apiVersion").ViaField("ref").ViaFieldIndex("to", 0).ViaField("spec") + }(), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.ep.Validate(context.TODO()) + if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" { + t.Errorf("%s: Validate EventPolicySpec (-want, +got) = %v", test.name, diff) + } + }) + } +} diff --git a/pkg/apis/eventing/v1alpha1/register.go b/pkg/apis/eventing/v1alpha1/register.go new file mode 100644 index 00000000000..c6f3e98cd0b --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/register.go @@ -0,0 +1,53 @@ +/* +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 ( + "knative.dev/eventing/pkg/apis/eventing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: eventing.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &EventPolicy{}, + &EventPolicyList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/eventing/v1alpha1/register_test.go b/pkg/apis/eventing/v1alpha1/register_test.go new file mode 100644 index 00000000000..8fb9e403809 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/register_test.go @@ -0,0 +1,52 @@ +/* +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. +*/ + +package v1alpha1 + +import ( + "testing" + + "k8s.io/apimachinery/pkg/runtime" +) + +func TestKind(t *testing.T) { + schemaGroupKind := Kind("EventPolicy") + if schemaGroupKind.Kind != "EventPolicy" || schemaGroupKind.Group != "eventing.knative.dev" { + t.Errorf("Unexpected GroupKind: %+v", schemaGroupKind) + } +} + +func TestResource(t *testing.T) { + schemaGroupResource := Resource("EventPolicy") + if schemaGroupResource.Group != "eventing.knative.dev" || schemaGroupResource.Resource != "EventPolicy" { + t.Errorf("Unexpected GroupResource: %+v", schemaGroupResource) + } +} + +func TestKnownTypes(t *testing.T) { + scheme := runtime.NewScheme() + addKnownTypes(scheme) + types := scheme.KnownTypes(SchemeGroupVersion) + + for _, name := range []string{ + "EventPolicy", + "EventPolicyList", + } { + if _, ok := types[name]; !ok { + t.Errorf("Did not find %q as registered type", name) + } + } +} diff --git a/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..998b577cad3 --- /dev/null +++ b/pkg/apis/eventing/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,250 @@ +//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 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicy) DeepCopyInto(out *EventPolicy) { + *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 EventPolicy. +func (in *EventPolicy) DeepCopy() *EventPolicy { + if in == nil { + return nil + } + out := new(EventPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EventPolicy) 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 *EventPolicyFromReference) DeepCopyInto(out *EventPolicyFromReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicyFromReference. +func (in *EventPolicyFromReference) DeepCopy() *EventPolicyFromReference { + if in == nil { + return nil + } + out := new(EventPolicyFromReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicyList) DeepCopyInto(out *EventPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]EventPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicyList. +func (in *EventPolicyList) DeepCopy() *EventPolicyList { + if in == nil { + return nil + } + out := new(EventPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EventPolicyList) 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 *EventPolicySelector) DeepCopyInto(out *EventPolicySelector) { + *out = *in + if in.LabelSelector != nil { + in, out := &in.LabelSelector, &out.LabelSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.TypeMeta != nil { + in, out := &in.TypeMeta, &out.TypeMeta + *out = new(v1.TypeMeta) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicySelector. +func (in *EventPolicySelector) DeepCopy() *EventPolicySelector { + if in == nil { + return nil + } + out := new(EventPolicySelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicySpec) DeepCopyInto(out *EventPolicySpec) { + *out = *in + if in.To != nil { + in, out := &in.To, &out.To + *out = make([]EventPolicySpecTo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.From != nil { + in, out := &in.From, &out.From + *out = make([]EventPolicySpecFrom, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicySpec. +func (in *EventPolicySpec) DeepCopy() *EventPolicySpec { + if in == nil { + return nil + } + out := new(EventPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicySpecFrom) DeepCopyInto(out *EventPolicySpecFrom) { + *out = *in + if in.Ref != nil { + in, out := &in.Ref, &out.Ref + *out = new(EventPolicyFromReference) + **out = **in + } + if in.Sub != nil { + in, out := &in.Sub, &out.Sub + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicySpecFrom. +func (in *EventPolicySpecFrom) DeepCopy() *EventPolicySpecFrom { + if in == nil { + return nil + } + out := new(EventPolicySpecFrom) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicySpecTo) DeepCopyInto(out *EventPolicySpecTo) { + *out = *in + if in.Ref != nil { + in, out := &in.Ref, &out.Ref + *out = new(EventPolicyToReference) + **out = **in + } + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(EventPolicySelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicySpecTo. +func (in *EventPolicySpecTo) DeepCopy() *EventPolicySpecTo { + if in == nil { + return nil + } + out := new(EventPolicySpecTo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicyStatus) DeepCopyInto(out *EventPolicyStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + if in.From != nil { + in, out := &in.From, &out.From + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicyStatus. +func (in *EventPolicyStatus) DeepCopy() *EventPolicyStatus { + if in == nil { + return nil + } + out := new(EventPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventPolicyToReference) DeepCopyInto(out *EventPolicyToReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventPolicyToReference. +func (in *EventPolicyToReference) DeepCopy() *EventPolicyToReference { + if in == nil { + return nil + } + out := new(EventPolicyToReference) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 169fc4b748c..0ca8d7350b7 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -26,6 +26,7 @@ import ( rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" eventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" + eventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1" eventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" eventingv1beta2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta2" eventingv1beta3 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta3" @@ -38,6 +39,7 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface + EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface EventingV1beta1() eventingv1beta1.EventingV1beta1Interface EventingV1beta2() eventingv1beta2.EventingV1beta2Interface EventingV1beta3() eventingv1beta3.EventingV1beta3Interface @@ -52,15 +54,21 @@ type Interface interface { // Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient - eventingV1beta1 *eventingv1beta1.EventingV1beta1Client - eventingV1beta2 *eventingv1beta2.EventingV1beta2Client - eventingV1beta3 *eventingv1beta3.EventingV1beta3Client - eventingV1 *eventingv1.EventingV1Client - flowsV1 *flowsv1.FlowsV1Client - messagingV1 *messagingv1.MessagingV1Client - sinksV1alpha1 *sinksv1alpha1.SinksV1alpha1Client - sourcesV1beta2 *sourcesv1beta2.SourcesV1beta2Client - sourcesV1 *sourcesv1.SourcesV1Client + eventingV1alpha1 *eventingv1alpha1.EventingV1alpha1Client + eventingV1beta1 *eventingv1beta1.EventingV1beta1Client + eventingV1beta2 *eventingv1beta2.EventingV1beta2Client + eventingV1beta3 *eventingv1beta3.EventingV1beta3Client + eventingV1 *eventingv1.EventingV1Client + flowsV1 *flowsv1.FlowsV1Client + messagingV1 *messagingv1.MessagingV1Client + sinksV1alpha1 *sinksv1alpha1.SinksV1alpha1Client + sourcesV1beta2 *sourcesv1beta2.SourcesV1beta2Client + sourcesV1 *sourcesv1.SourcesV1Client +} + +// EventingV1alpha1 retrieves the EventingV1alpha1Client +func (c *Clientset) EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface { + return c.eventingV1alpha1 } // EventingV1beta1 retrieves the EventingV1beta1Client @@ -152,6 +160,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, var cs Clientset var err error + cs.eventingV1alpha1, err = eventingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.eventingV1beta1, err = eventingv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -209,6 +221,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { // New creates a new Clientset for the given RESTClient. func New(c rest.Interface) *Clientset { var cs Clientset + cs.eventingV1alpha1 = eventingv1alpha1.New(c) cs.eventingV1beta1 = eventingv1beta1.New(c) cs.eventingV1beta2 = eventingv1beta2.New(c) cs.eventingV1beta3 = eventingv1beta3.New(c) diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 8c17bc626b0..ce9c3649485 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -27,6 +27,8 @@ import ( clientset "knative.dev/eventing/pkg/client/clientset/versioned" eventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" fakeeventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1/fake" + eventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1" + fakeeventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake" eventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" fakeeventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake" eventingv1beta2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta2" @@ -95,6 +97,11 @@ var ( _ testing.FakeClient = &Clientset{} ) +// EventingV1alpha1 retrieves the EventingV1alpha1Client +func (c *Clientset) EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface { + return &fakeeventingv1alpha1.FakeEventingV1alpha1{Fake: &c.Fake} +} + // EventingV1beta1 retrieves the EventingV1beta1Client func (c *Clientset) EventingV1beta1() eventingv1beta1.EventingV1beta1Interface { return &fakeeventingv1beta1.FakeEventingV1beta1{Fake: &c.Fake} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index fdd99cc3855..69946bd6e54 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -25,6 +25,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" eventingv1beta3 "knative.dev/eventing/pkg/apis/eventing/v1beta3" @@ -39,6 +40,7 @@ var scheme = runtime.NewScheme() var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + eventingv1alpha1.AddToScheme, eventingv1beta1.AddToScheme, eventingv1beta2.AddToScheme, eventingv1beta3.AddToScheme, diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 447af7253c5..e037c6c1749 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -25,6 +25,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" eventingv1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" eventingv1beta3 "knative.dev/eventing/pkg/apis/eventing/v1beta3" @@ -39,6 +40,7 @@ var Scheme = runtime.NewScheme() var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + eventingv1alpha1.AddToScheme, eventingv1beta1.AddToScheme, eventingv1beta2.AddToScheme, eventingv1beta3.AddToScheme, diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/doc.go new file mode 100644 index 00000000000..0b13fd8e001 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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 client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventing_client.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventing_client.go new file mode 100644 index 00000000000..e901caf43a4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventing_client.go @@ -0,0 +1,107 @@ +/* +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 client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +type EventingV1alpha1Interface interface { + RESTClient() rest.Interface + EventPoliciesGetter +} + +// EventingV1alpha1Client is used to interact with features provided by the eventing.knative.dev group. +type EventingV1alpha1Client struct { + restClient rest.Interface +} + +func (c *EventingV1alpha1Client) EventPolicies(namespace string) EventPolicyInterface { + return newEventPolicies(c, namespace) +} + +// NewForConfig creates a new EventingV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*EventingV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new EventingV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*EventingV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &EventingV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new EventingV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *EventingV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new EventingV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *EventingV1alpha1Client { + return &EventingV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *EventingV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventpolicy.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventpolicy.go new file mode 100644 index 00000000000..bb510ab6eee --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/eventpolicy.go @@ -0,0 +1,195 @@ +/* +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 client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// EventPoliciesGetter has a method to return a EventPolicyInterface. +// A group's client should implement this interface. +type EventPoliciesGetter interface { + EventPolicies(namespace string) EventPolicyInterface +} + +// EventPolicyInterface has methods to work with EventPolicy resources. +type EventPolicyInterface interface { + Create(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.CreateOptions) (*v1alpha1.EventPolicy, error) + Update(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (*v1alpha1.EventPolicy, error) + UpdateStatus(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (*v1alpha1.EventPolicy, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.EventPolicy, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.EventPolicyList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.EventPolicy, err error) + EventPolicyExpansion +} + +// eventPolicies implements EventPolicyInterface +type eventPolicies struct { + client rest.Interface + ns string +} + +// newEventPolicies returns a EventPolicies +func newEventPolicies(c *EventingV1alpha1Client, namespace string) *eventPolicies { + return &eventPolicies{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the eventPolicy, and returns the corresponding eventPolicy object, and an error if there is any. +func (c *eventPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.EventPolicy, err error) { + result = &v1alpha1.EventPolicy{} + err = c.client.Get(). + Namespace(c.ns). + Resource("eventpolicies"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of EventPolicies that match those selectors. +func (c *eventPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.EventPolicyList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.EventPolicyList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("eventpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested eventPolicies. +func (c *eventPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("eventpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a eventPolicy and creates it. Returns the server's representation of the eventPolicy, and an error, if there is any. +func (c *eventPolicies) Create(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.CreateOptions) (result *v1alpha1.EventPolicy, err error) { + result = &v1alpha1.EventPolicy{} + err = c.client.Post(). + Namespace(c.ns). + Resource("eventpolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventPolicy). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a eventPolicy and updates it. Returns the server's representation of the eventPolicy, and an error, if there is any. +func (c *eventPolicies) Update(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (result *v1alpha1.EventPolicy, err error) { + result = &v1alpha1.EventPolicy{} + err = c.client.Put(). + Namespace(c.ns). + Resource("eventpolicies"). + Name(eventPolicy.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventPolicy). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *eventPolicies) UpdateStatus(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (result *v1alpha1.EventPolicy, err error) { + result = &v1alpha1.EventPolicy{} + err = c.client.Put(). + Namespace(c.ns). + Resource("eventpolicies"). + Name(eventPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eventPolicy). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the eventPolicy and deletes it. Returns an error if one occurs. +func (c *eventPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("eventpolicies"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *eventPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("eventpolicies"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched eventPolicy. +func (c *eventPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.EventPolicy, err error) { + result = &v1alpha1.EventPolicy{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("eventpolicies"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/doc.go new file mode 100644 index 00000000000..40528db3a52 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +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 client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventing_client.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventing_client.go new file mode 100644 index 00000000000..958cd866140 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventing_client.go @@ -0,0 +1,40 @@ +/* +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 client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1" +) + +type FakeEventingV1alpha1 struct { + *testing.Fake +} + +func (c *FakeEventingV1alpha1) EventPolicies(namespace string) v1alpha1.EventPolicyInterface { + return &FakeEventPolicies{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeEventingV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventpolicy.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventpolicy.go new file mode 100644 index 00000000000..a31bc820038 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake/fake_eventpolicy.go @@ -0,0 +1,141 @@ +/* +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 client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" +) + +// FakeEventPolicies implements EventPolicyInterface +type FakeEventPolicies struct { + Fake *FakeEventingV1alpha1 + ns string +} + +var eventpoliciesResource = v1alpha1.SchemeGroupVersion.WithResource("eventpolicies") + +var eventpoliciesKind = v1alpha1.SchemeGroupVersion.WithKind("EventPolicy") + +// Get takes name of the eventPolicy, and returns the corresponding eventPolicy object, and an error if there is any. +func (c *FakeEventPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.EventPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(eventpoliciesResource, c.ns, name), &v1alpha1.EventPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.EventPolicy), err +} + +// List takes label and field selectors, and returns the list of EventPolicies that match those selectors. +func (c *FakeEventPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.EventPolicyList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(eventpoliciesResource, eventpoliciesKind, c.ns, opts), &v1alpha1.EventPolicyList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.EventPolicyList{ListMeta: obj.(*v1alpha1.EventPolicyList).ListMeta} + for _, item := range obj.(*v1alpha1.EventPolicyList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested eventPolicies. +func (c *FakeEventPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(eventpoliciesResource, c.ns, opts)) + +} + +// Create takes the representation of a eventPolicy and creates it. Returns the server's representation of the eventPolicy, and an error, if there is any. +func (c *FakeEventPolicies) Create(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.CreateOptions) (result *v1alpha1.EventPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(eventpoliciesResource, c.ns, eventPolicy), &v1alpha1.EventPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.EventPolicy), err +} + +// Update takes the representation of a eventPolicy and updates it. Returns the server's representation of the eventPolicy, and an error, if there is any. +func (c *FakeEventPolicies) Update(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (result *v1alpha1.EventPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(eventpoliciesResource, c.ns, eventPolicy), &v1alpha1.EventPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.EventPolicy), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeEventPolicies) UpdateStatus(ctx context.Context, eventPolicy *v1alpha1.EventPolicy, opts v1.UpdateOptions) (*v1alpha1.EventPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(eventpoliciesResource, "status", c.ns, eventPolicy), &v1alpha1.EventPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.EventPolicy), err +} + +// Delete takes name of the eventPolicy and deletes it. Returns an error if one occurs. +func (c *FakeEventPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(eventpoliciesResource, c.ns, name, opts), &v1alpha1.EventPolicy{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeEventPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(eventpoliciesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.EventPolicyList{}) + return err +} + +// Patch applies the patch and returns the patched eventPolicy. +func (c *FakeEventPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.EventPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(eventpoliciesResource, c.ns, name, pt, data, subresources...), &v1alpha1.EventPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.EventPolicy), err +} diff --git a/pkg/client/clientset/versioned/typed/eventing/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..d5bd1a045d9 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/eventing/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +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 client-gen. DO NOT EDIT. + +package v1alpha1 + +type EventPolicyExpansion interface{} diff --git a/pkg/client/informers/externalversions/eventing/interface.go b/pkg/client/informers/externalversions/eventing/interface.go index e77e6ae25d8..ccfc67a42aa 100644 --- a/pkg/client/informers/externalversions/eventing/interface.go +++ b/pkg/client/informers/externalversions/eventing/interface.go @@ -20,6 +20,7 @@ package eventing import ( v1 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1" + v1alpha1 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1alpha1" v1beta1 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1beta1" v1beta2 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1beta2" v1beta3 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1beta3" @@ -28,6 +29,8 @@ import ( // Interface provides access to each of this group's versions. type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface // V1beta1 provides access to shared informers for resources in V1beta1. V1beta1() v1beta1.Interface // V1beta2 provides access to shared informers for resources in V1beta2. @@ -49,6 +52,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + // V1beta1 returns a new v1beta1.Interface. func (g *group) V1beta1() v1beta1.Interface { return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) diff --git a/pkg/client/informers/externalversions/eventing/v1alpha1/eventpolicy.go b/pkg/client/informers/externalversions/eventing/v1alpha1/eventpolicy.go new file mode 100644 index 00000000000..df3b47e2677 --- /dev/null +++ b/pkg/client/informers/externalversions/eventing/v1alpha1/eventpolicy.go @@ -0,0 +1,90 @@ +/* +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 informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + versioned "knative.dev/eventing/pkg/client/clientset/versioned" + internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "knative.dev/eventing/pkg/client/listers/eventing/v1alpha1" +) + +// EventPolicyInformer provides access to a shared informer and lister for +// EventPolicies. +type EventPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.EventPolicyLister +} + +type eventPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEventPolicyInformer constructs a new informer for EventPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEventPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEventPolicyInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEventPolicyInformer constructs a new informer for EventPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEventPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventingV1alpha1().EventPolicies(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.EventingV1alpha1().EventPolicies(namespace).Watch(context.TODO(), options) + }, + }, + &eventingv1alpha1.EventPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *eventPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEventPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *eventPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&eventingv1alpha1.EventPolicy{}, f.defaultInformer) +} + +func (f *eventPolicyInformer) Lister() v1alpha1.EventPolicyLister { + return v1alpha1.NewEventPolicyLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/eventing/v1alpha1/interface.go b/pkg/client/informers/externalversions/eventing/v1alpha1/interface.go new file mode 100644 index 00000000000..89263c25853 --- /dev/null +++ b/pkg/client/informers/externalversions/eventing/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +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 informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // EventPolicies returns a EventPolicyInformer. + EventPolicies() EventPolicyInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// EventPolicies returns a EventPolicyInformer. +func (v *version) EventPolicies() EventPolicyInformer { + return &eventPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 3e039fa365a..41c490e06ce 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -24,12 +24,13 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" v1 "knative.dev/eventing/pkg/apis/eventing/v1" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" v1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1" v1beta2 "knative.dev/eventing/pkg/apis/eventing/v1beta2" v1beta3 "knative.dev/eventing/pkg/apis/eventing/v1beta3" flowsv1 "knative.dev/eventing/pkg/apis/flows/v1" messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1" - v1alpha1 "knative.dev/eventing/pkg/apis/sinks/v1alpha1" + sinksv1alpha1 "knative.dev/eventing/pkg/apis/sinks/v1alpha1" sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1" sourcesv1beta2 "knative.dev/eventing/pkg/apis/sources/v1beta2" ) @@ -66,6 +67,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1.SchemeGroupVersion.WithResource("triggers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1().Triggers().Informer()}, nil + // Group=eventing.knative.dev, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("eventpolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1alpha1().EventPolicies().Informer()}, nil + // Group=eventing.knative.dev, Version=v1beta1 case v1beta1.SchemeGroupVersion.WithResource("eventtypes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1beta1().EventTypes().Informer()}, nil @@ -93,7 +98,7 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Messaging().V1().Subscriptions().Informer()}, nil // Group=sinks.knative.dev, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("jobsinks"): + case sinksv1alpha1.SchemeGroupVersion.WithResource("jobsinks"): return &genericInformer{resource: resource.GroupResource(), informer: f.Sinks().V1alpha1().JobSinks().Informer()}, nil // Group=sources.knative.dev, Version=v1 diff --git a/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/eventpolicy.go b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/eventpolicy.go new file mode 100644 index 00000000000..c6da95f0a05 --- /dev/null +++ b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/eventpolicy.go @@ -0,0 +1,52 @@ +/* +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 injection-gen. DO NOT EDIT. + +package eventpolicy + +import ( + context "context" + + v1alpha1 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1alpha1" + factory "knative.dev/eventing/pkg/client/injection/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Eventing().V1alpha1().EventPolicies() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1alpha1.EventPolicyInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1alpha1.EventPolicyInformer from context.") + } + return untyped.(v1alpha1.EventPolicyInformer) +} diff --git a/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/fake/fake.go b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/fake/fake.go new file mode 100644 index 00000000000..349893d97b7 --- /dev/null +++ b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/fake/fake.go @@ -0,0 +1,40 @@ +/* +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 injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + eventpolicy "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy" + fake "knative.dev/eventing/pkg/client/injection/informers/factory/fake" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" +) + +var Get = eventpolicy.Get + +func init() { + injection.Fake.RegisterInformer(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := fake.Get(ctx) + inf := f.Eventing().V1alpha1().EventPolicies() + return context.WithValue(ctx, eventpolicy.Key{}, inf), inf.Informer() +} diff --git a/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/eventpolicy.go b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/eventpolicy.go new file mode 100644 index 00000000000..11a83b51a8c --- /dev/null +++ b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/eventpolicy.go @@ -0,0 +1,65 @@ +/* +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 injection-gen. DO NOT EDIT. + +package filtered + +import ( + context "context" + + v1alpha1 "knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1alpha1" + filtered "knative.dev/eventing/pkg/client/injection/informers/factory/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterFilteredInformers(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct { + Selector string +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(filtered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := filtered.Get(ctx, selector) + inf := f.Eventing().V1alpha1().EventPolicies() + ctx = context.WithValue(ctx, Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context, selector string) v1alpha1.EventPolicyInformer { + untyped := ctx.Value(Key{Selector: selector}) + if untyped == nil { + logging.FromContext(ctx).Panicf( + "Unable to fetch knative.dev/eventing/pkg/client/informers/externalversions/eventing/v1alpha1.EventPolicyInformer with selector %s from context.", selector) + } + return untyped.(v1alpha1.EventPolicyInformer) +} diff --git a/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/fake/fake.go b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/fake/fake.go new file mode 100644 index 00000000000..68c9d13a5a9 --- /dev/null +++ b/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered/fake/fake.go @@ -0,0 +1,52 @@ +/* +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 injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + filtered "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy/filtered" + factoryfiltered "knative.dev/eventing/pkg/client/injection/informers/factory/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +var Get = filtered.Get + +func init() { + injection.Fake.RegisterFilteredInformers(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(factoryfiltered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := factoryfiltered.Get(ctx, selector) + inf := f.Eventing().V1alpha1().EventPolicies() + ctx = context.WithValue(ctx, filtered.Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} diff --git a/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/controller.go b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/controller.go new file mode 100644 index 00000000000..89163724a3e --- /dev/null +++ b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/controller.go @@ -0,0 +1,170 @@ +/* +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 injection-gen. DO NOT EDIT. + +package eventpolicy + +import ( + context "context" + fmt "fmt" + reflect "reflect" + strings "strings" + + zap "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + scheme "k8s.io/client-go/kubernetes/scheme" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + record "k8s.io/client-go/tools/record" + versionedscheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + client "knative.dev/eventing/pkg/client/injection/client" + eventpolicy "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/eventpolicy" + kubeclient "knative.dev/pkg/client/injection/kube/client" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + logkey "knative.dev/pkg/logging/logkey" + reconciler "knative.dev/pkg/reconciler" +) + +const ( + defaultControllerAgentName = "eventpolicy-controller" + defaultFinalizerName = "eventpolicies.eventing.knative.dev" +) + +// NewImpl returns a controller.Impl that handles queuing and feeding work from +// the queue through an implementation of controller.Reconciler, delegating to +// the provided Interface and optional Finalizer methods. OptionsFn is used to return +// controller.ControllerOptions to be used by the internal reconciler. +func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl { + logger := logging.FromContext(ctx) + + // Check the options function input. It should be 0 or 1. + if len(optionsFns) > 1 { + logger.Fatal("Up to one options function is supported, found: ", len(optionsFns)) + } + + eventpolicyInformer := eventpolicy.Get(ctx) + + lister := eventpolicyInformer.Lister() + + var promoteFilterFunc func(obj interface{}) bool + var promoteFunc = func(bkt reconciler.Bucket) {} + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + + // Signal promotion event + promoteFunc(bkt) + + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + if promoteFilterFunc != nil { + if ok := promoteFilterFunc(elt); !ok { + continue + } + } + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client.Get(ctx), + Lister: lister, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + ctrType := reflect.TypeOf(r).Elem() + ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name()) + ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".") + + logger = logger.With( + zap.String(logkey.ControllerType, ctrTypeName), + zap.String(logkey.Kind, "eventing.knative.dev.EventPolicy"), + ) + + impl := controller.NewContext(ctx, rec, controller.ControllerOptions{WorkQueueName: ctrTypeName, Logger: logger}) + agentName := defaultControllerAgentName + + // Pass impl to the options. Save any optional results. + for _, fn := range optionsFns { + opts := fn(impl) + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.AgentName != "" { + agentName = opts.AgentName + } + if opts.SkipStatusUpdates { + rec.skipStatusUpdates = true + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + if opts.PromoteFilterFunc != nil { + promoteFilterFunc = opts.PromoteFilterFunc + } + if opts.PromoteFunc != nil { + promoteFunc = opts.PromoteFunc + } + } + + rec.Recorder = createRecorder(ctx, agentName) + + return impl +} + +func createRecorder(ctx context.Context, agentName string) record.EventRecorder { + logger := logging.FromContext(ctx) + + recorder := controller.GetEventRecorder(ctx) + if recorder == nil { + // Create event broadcaster + logger.Debug("Creating event broadcaster") + eventBroadcaster := record.NewBroadcaster() + watches := []watch.Interface{ + eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof), + eventBroadcaster.StartRecordingToSink( + &v1.EventSinkImpl{Interface: kubeclient.Get(ctx).CoreV1().Events("")}), + } + recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName}) + go func() { + <-ctx.Done() + for _, w := range watches { + w.Stop() + } + }() + } + + return recorder +} + +func init() { + versionedscheme.AddToScheme(scheme.Scheme) +} diff --git a/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/reconciler.go b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/reconciler.go new file mode 100644 index 00000000000..264627eb9bd --- /dev/null +++ b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/reconciler.go @@ -0,0 +1,440 @@ +/* +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 injection-gen. DO NOT EDIT. + +package eventpolicy + +import ( + context "context" + json "encoding/json" + fmt "fmt" + + zap "go.uber.org/zap" + "go.uber.org/zap/zapcore" + v1 "k8s.io/api/core/v1" + equality "k8s.io/apimachinery/pkg/api/equality" + errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + sets "k8s.io/apimachinery/pkg/util/sets" + record "k8s.io/client-go/tools/record" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + versioned "knative.dev/eventing/pkg/client/clientset/versioned" + eventingv1alpha1 "knative.dev/eventing/pkg/client/listers/eventing/v1alpha1" + controller "knative.dev/pkg/controller" + kmp "knative.dev/pkg/kmp" + logging "knative.dev/pkg/logging" + reconciler "knative.dev/pkg/reconciler" +) + +// Interface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1alpha1.EventPolicy. +type Interface interface { + // ReconcileKind implements custom logic to reconcile v1alpha1.EventPolicy. Any changes + // to the objects .Status or .Finalizers will be propagated to the stored + // object. It is recommended that implementors do not call any update calls + // for the Kind inside of ReconcileKind, it is the responsibility of the calling + // controller to propagate those properties. The resource passed to ReconcileKind + // will always have an empty deletion timestamp. + ReconcileKind(ctx context.Context, o *v1alpha1.EventPolicy) reconciler.Event +} + +// Finalizer defines the strongly typed interfaces to be implemented by a +// controller finalizing v1alpha1.EventPolicy. +type Finalizer interface { + // FinalizeKind implements custom logic to finalize v1alpha1.EventPolicy. Any changes + // to the objects .Status or .Finalizers will be ignored. Returning a nil or + // Normal type reconciler.Event will allow the finalizer to be deleted on + // the resource. The resource passed to FinalizeKind will always have a set + // deletion timestamp. + FinalizeKind(ctx context.Context, o *v1alpha1.EventPolicy) reconciler.Event +} + +// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1alpha1.EventPolicy if they want to process resources for which +// they are not the leader. +type ReadOnlyInterface interface { + // ObserveKind implements logic to observe v1alpha1.EventPolicy. + // This method should not write to the API. + ObserveKind(ctx context.Context, o *v1alpha1.EventPolicy) reconciler.Event +} + +type doReconcile func(ctx context.Context, o *v1alpha1.EventPolicy) reconciler.Event + +// reconcilerImpl implements controller.Reconciler for v1alpha1.EventPolicy resources. +type reconcilerImpl struct { + // LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware. + reconciler.LeaderAwareFuncs + + // Client is used to write back status updates. + Client versioned.Interface + + // Listers index properties about resources. + Lister eventingv1alpha1.EventPolicyLister + + // Recorder is an event recorder for recording Event resources to the + // Kubernetes API. + Recorder record.EventRecorder + + // configStore allows for decorating a context with config maps. + // +optional + configStore reconciler.ConfigStore + + // reconciler is the implementation of the business logic of the resource. + reconciler Interface + + // finalizerName is the name of the finalizer to reconcile. + finalizerName string + + // skipStatusUpdates configures whether or not this reconciler automatically updates + // the status of the reconciled resource. + skipStatusUpdates bool +} + +// Check that our Reconciler implements controller.Reconciler. +var _ controller.Reconciler = (*reconcilerImpl)(nil) + +// Check that our generated Reconciler is always LeaderAware. +var _ reconciler.LeaderAware = (*reconcilerImpl)(nil) + +func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client versioned.Interface, lister eventingv1alpha1.EventPolicyLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler { + // Check the options function input. It should be 0 or 1. + if len(options) > 1 { + logger.Fatal("Up to one options struct is supported, found: ", len(options)) + } + + // Fail fast when users inadvertently implement the other LeaderAware interface. + // For the typed reconcilers, Promote shouldn't take any arguments. + if _, ok := r.(reconciler.LeaderAware); ok { + logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r) + } + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + // TODO: Consider letting users specify a filter in options. + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client, + Lister: lister, + Recorder: recorder, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + for _, opts := range options { + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.SkipStatusUpdates { + rec.skipStatusUpdates = true + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + } + + return rec +} + +// Reconcile implements controller.Reconciler +func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error { + logger := logging.FromContext(ctx) + + // Initialize the reconciler state. This will convert the namespace/name + // string into a distinct namespace and name, determine if this instance of + // the reconciler is the leader, and any additional interfaces implemented + // by the reconciler. Returns an error is the resource key is invalid. + s, err := newState(key, r) + if err != nil { + logger.Error("Invalid resource key: ", key) + return nil + } + + // If we are not the leader, and we don't implement either ReadOnly + // observer interfaces, then take a fast-path out. + if s.isNotLeaderNorObserver() { + return controller.NewSkipKey(key) + } + + // If configStore is set, attach the frozen configuration to the context. + if r.configStore != nil { + ctx = r.configStore.ToContext(ctx) + } + + // Add the recorder to context. + ctx = controller.WithEventRecorder(ctx, r.Recorder) + + // Get the resource with this namespace/name. + + getter := r.Lister.EventPolicies(s.namespace) + + original, err := getter.Get(s.name) + + if errors.IsNotFound(err) { + // The resource may no longer exist, in which case we stop processing and call + // the ObserveDeletion handler if appropriate. + logger.Debugf("Resource %q no longer exists", key) + if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok { + return del.ObserveDeletion(ctx, types.NamespacedName{ + Namespace: s.namespace, + Name: s.name, + }) + } + return nil + } else if err != nil { + return err + } + + // Don't modify the informers copy. + resource := original.DeepCopy() + + var reconcileEvent reconciler.Event + + name, do := s.reconcileMethodFor(resource) + // Append the target method to the logger. + logger = logger.With(zap.String("targetMethod", name)) + switch name { + case reconciler.DoReconcileKind: + // Set and update the finalizer on resource if r.reconciler + // implements Finalizer. + if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil { + return fmt.Errorf("failed to set finalizers: %w", err) + } + + if !r.skipStatusUpdates { + reconciler.PreProcessReconcile(ctx, resource) + } + + // Reconcile this copy of the resource and then write back any status + // updates regardless of whether the reconciliation errored out. + reconcileEvent = do(ctx, resource) + + if !r.skipStatusUpdates { + reconciler.PostProcessReconcile(ctx, resource, original) + } + + case reconciler.DoFinalizeKind: + // For finalizing reconcilers, if this resource being marked for deletion + // and reconciled cleanly (nil or normal event), remove the finalizer. + reconcileEvent = do(ctx, resource) + + if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil { + return fmt.Errorf("failed to clear finalizers: %w", err) + } + + case reconciler.DoObserveKind: + // Observe any changes to this resource, since we are not the leader. + reconcileEvent = do(ctx, resource) + + } + + // Synchronize the status. + switch { + case r.skipStatusUpdates: + // This reconciler implementation is configured to skip resource updates. + // This may mean this reconciler does not observe spec, but reconciles external changes. + case equality.Semantic.DeepEqual(original.Status, resource.Status): + // If we didn't change anything then don't call updateStatus. + // This is important because the copy we loaded from the injectionInformer's + // cache may be stale and we don't want to overwrite a prior update + // to status with this stale state. + case !s.isLeader: + // High-availability reconcilers may have many replicas watching the resource, but only + // the elected leader is expected to write modifications. + logger.Warn("Saw status changes when we aren't the leader!") + default: + if err = r.updateStatus(ctx, logger, original, resource); err != nil { + logger.Warnw("Failed to update resource status", zap.Error(err)) + r.Recorder.Eventf(resource, v1.EventTypeWarning, "UpdateFailed", + "Failed to update status for %q: %v", resource.Name, err) + return err + } + } + + // Report the reconciler event, if any. + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + logger.Infow("Returned an event", zap.Any("event", reconcileEvent)) + r.Recorder.Event(resource, event.EventType, event.Reason, event.Error()) + + // the event was wrapped inside an error, consider the reconciliation as failed + if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent { + return reconcileEvent + } + return nil + } + + if controller.IsSkipKey(reconcileEvent) { + // This is a wrapped error, don't emit an event. + } else if ok, _ := controller.IsRequeueKey(reconcileEvent); ok { + // This is a wrapped error, don't emit an event. + } else { + logger.Errorw("Returned an error", zap.Error(reconcileEvent)) + r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error()) + } + return reconcileEvent + } + + return nil +} + +func (r *reconcilerImpl) updateStatus(ctx context.Context, logger *zap.SugaredLogger, existing *v1alpha1.EventPolicy, desired *v1alpha1.EventPolicy) error { + existing = existing.DeepCopy() + return reconciler.RetryUpdateConflicts(func(attempts int) (err error) { + // The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API. + if attempts > 0 { + + getter := r.Client.EventingV1alpha1().EventPolicies(desired.Namespace) + + existing, err = getter.Get(ctx, desired.Name, metav1.GetOptions{}) + if err != nil { + return err + } + } + + // If there's nothing to update, just return. + if equality.Semantic.DeepEqual(existing.Status, desired.Status) { + return nil + } + + if logger.Desugar().Core().Enabled(zapcore.DebugLevel) { + if diff, err := kmp.SafeDiff(existing.Status, desired.Status); err == nil && diff != "" { + logger.Debug("Updating status with: ", diff) + } + } + + existing.Status = desired.Status + + updater := r.Client.EventingV1alpha1().EventPolicies(existing.Namespace) + + _, err = updater.UpdateStatus(ctx, existing, metav1.UpdateOptions{}) + return err + }) +} + +// updateFinalizersFiltered will update the Finalizers of the resource. +// TODO: this method could be generic and sync all finalizers. For now it only +// updates defaultFinalizerName or its override. +func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1alpha1.EventPolicy, desiredFinalizers sets.Set[string]) (*v1alpha1.EventPolicy, error) { + // Don't modify the informers copy. + existing := resource.DeepCopy() + + var finalizers []string + + // If there's nothing to update, just return. + existingFinalizers := sets.New[string](existing.Finalizers...) + + if desiredFinalizers.Has(r.finalizerName) { + if existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Add the finalizer. + finalizers = append(existing.Finalizers, r.finalizerName) + } else { + if !existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Remove the finalizer. + existingFinalizers.Delete(r.finalizerName) + finalizers = sets.List(existingFinalizers) + } + + mergePatch := map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": finalizers, + "resourceVersion": existing.ResourceVersion, + }, + } + + patch, err := json.Marshal(mergePatch) + if err != nil { + return resource, err + } + + patcher := r.Client.EventingV1alpha1().EventPolicies(resource.Namespace) + + resourceName := resource.Name + updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed", + "Failed to update finalizers for %q: %v", resourceName, err) + } else { + r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate", + "Updated %q finalizers", resource.GetName()) + } + return updated, err +} + +func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1alpha1.EventPolicy) (*v1alpha1.EventPolicy, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + // If this resource is not being deleted, mark the finalizer. + if resource.GetDeletionTimestamp().IsZero() { + finalizers.Insert(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} + +func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1alpha1.EventPolicy, reconcileEvent reconciler.Event) (*v1alpha1.EventPolicy, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + if resource.GetDeletionTimestamp().IsZero() { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + if event.EventType == v1.EventTypeNormal { + finalizers.Delete(r.finalizerName) + } + } + } else { + finalizers.Delete(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} diff --git a/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/state.go b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/state.go new file mode 100644 index 00000000000..e9f265c0206 --- /dev/null +++ b/pkg/client/injection/reconciler/eventing/v1alpha1/eventpolicy/state.go @@ -0,0 +1,97 @@ +/* +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 injection-gen. DO NOT EDIT. + +package eventpolicy + +import ( + fmt "fmt" + + types "k8s.io/apimachinery/pkg/types" + cache "k8s.io/client-go/tools/cache" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + reconciler "knative.dev/pkg/reconciler" +) + +// state is used to track the state of a reconciler in a single run. +type state struct { + // key is the original reconciliation key from the queue. + key string + // namespace is the namespace split from the reconciliation key. + namespace string + // name is the name split from the reconciliation key. + name string + // reconciler is the reconciler. + reconciler Interface + // roi is the read only interface cast of the reconciler. + roi ReadOnlyInterface + // isROI (Read Only Interface) the reconciler only observes reconciliation. + isROI bool + // isLeader the instance of the reconciler is the elected leader. + isLeader bool +} + +func newState(key string, r *reconcilerImpl) (*state, error) { + // Convert the namespace/name string into a distinct namespace and name. + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, fmt.Errorf("invalid resource key: %s", key) + } + + roi, isROI := r.reconciler.(ReadOnlyInterface) + + isLeader := r.IsLeaderFor(types.NamespacedName{ + Namespace: namespace, + Name: name, + }) + + return &state{ + key: key, + namespace: namespace, + name: name, + reconciler: r.reconciler, + roi: roi, + isROI: isROI, + isLeader: isLeader, + }, nil +} + +// isNotLeaderNorObserver checks to see if this reconciler with the current +// state is enabled to do any work or not. +// isNotLeaderNorObserver returns true when there is no work possible for the +// reconciler. +func (s *state) isNotLeaderNorObserver() bool { + if !s.isLeader && !s.isROI { + // If we are not the leader, and we don't implement the ReadOnly + // interface, then take a fast-path out. + return true + } + return false +} + +func (s *state) reconcileMethodFor(o *v1alpha1.EventPolicy) (string, doReconcile) { + if o.GetDeletionTimestamp().IsZero() { + if s.isLeader { + return reconciler.DoReconcileKind, s.reconciler.ReconcileKind + } else if s.isROI { + return reconciler.DoObserveKind, s.roi.ObserveKind + } + } else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok { + return reconciler.DoFinalizeKind, fin.FinalizeKind + } + return "unknown", nil +} diff --git a/pkg/client/listers/eventing/v1alpha1/eventpolicy.go b/pkg/client/listers/eventing/v1alpha1/eventpolicy.go new file mode 100644 index 00000000000..4601f8069e6 --- /dev/null +++ b/pkg/client/listers/eventing/v1alpha1/eventpolicy.go @@ -0,0 +1,99 @@ +/* +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 lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" +) + +// EventPolicyLister helps list EventPolicies. +// All objects returned here must be treated as read-only. +type EventPolicyLister interface { + // List lists all EventPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.EventPolicy, err error) + // EventPolicies returns an object that can list and get EventPolicies. + EventPolicies(namespace string) EventPolicyNamespaceLister + EventPolicyListerExpansion +} + +// eventPolicyLister implements the EventPolicyLister interface. +type eventPolicyLister struct { + indexer cache.Indexer +} + +// NewEventPolicyLister returns a new EventPolicyLister. +func NewEventPolicyLister(indexer cache.Indexer) EventPolicyLister { + return &eventPolicyLister{indexer: indexer} +} + +// List lists all EventPolicies in the indexer. +func (s *eventPolicyLister) List(selector labels.Selector) (ret []*v1alpha1.EventPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.EventPolicy)) + }) + return ret, err +} + +// EventPolicies returns an object that can list and get EventPolicies. +func (s *eventPolicyLister) EventPolicies(namespace string) EventPolicyNamespaceLister { + return eventPolicyNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// EventPolicyNamespaceLister helps list and get EventPolicies. +// All objects returned here must be treated as read-only. +type EventPolicyNamespaceLister interface { + // List lists all EventPolicies in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.EventPolicy, err error) + // Get retrieves the EventPolicy from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.EventPolicy, error) + EventPolicyNamespaceListerExpansion +} + +// eventPolicyNamespaceLister implements the EventPolicyNamespaceLister +// interface. +type eventPolicyNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all EventPolicies in the indexer for a given namespace. +func (s eventPolicyNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.EventPolicy, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.EventPolicy)) + }) + return ret, err +} + +// Get retrieves the EventPolicy from the indexer for a given namespace and name. +func (s eventPolicyNamespaceLister) Get(name string) (*v1alpha1.EventPolicy, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("eventpolicy"), name) + } + return obj.(*v1alpha1.EventPolicy), nil +} diff --git a/pkg/client/listers/eventing/v1alpha1/expansion_generated.go b/pkg/client/listers/eventing/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..e3f601930d7 --- /dev/null +++ b/pkg/client/listers/eventing/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +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 lister-gen. DO NOT EDIT. + +package v1alpha1 + +// EventPolicyListerExpansion allows custom methods to be added to +// EventPolicyLister. +type EventPolicyListerExpansion interface{} + +// EventPolicyNamespaceListerExpansion allows custom methods to be added to +// EventPolicyNamespaceLister. +type EventPolicyNamespaceListerExpansion interface{}