diff --git a/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yaml b/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yaml new file mode 100644 index 0000000000..409e36a72c --- /dev/null +++ b/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yaml @@ -0,0 +1,87 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: dnsendpoints.externaldns.nginx.org +spec: + group: externaldns.nginx.org + names: + kind: DNSEndpoint + listKind: DNSEndpointList + plural: dnsendpoints + singular: dnsendpoint + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: DNSEndpoint is the CRD wrapper for Endpoint + 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 + metadata: + type: object + spec: + type: object + properties: + endpoints: + type: array + items: + type: object + properties: + dnsName: + description: The hostname for the DNS record + type: string + labels: + description: Labels stores labels defined for the Endpoint + type: object + additionalProperties: + type: string + providerSpecific: + description: ProviderSpecific stores provider specific config + type: array + items: + type: object + properties: + name: + description: Name of the property + type: string + value: + description: Value of the property + type: string + recordTTL: + description: TTL for the record + type: integer + format: int64 + recordType: + description: RecordType type of record, e.g. CNAME, A, SRV, TXT, MX + type: string + targets: + description: The targets the DNS service points to + type: array + items: + type: string + status: + type: object + properties: + observedGeneration: + description: The generation observed by by the external-dns controller. + type: integer + format: int64 + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deployments/helm-chart/crds/externaldns.nginx.org_dnsendpoints.yaml b/deployments/helm-chart/crds/externaldns.nginx.org_dnsendpoints.yaml new file mode 100644 index 0000000000..409e36a72c --- /dev/null +++ b/deployments/helm-chart/crds/externaldns.nginx.org_dnsendpoints.yaml @@ -0,0 +1,87 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: dnsendpoints.externaldns.nginx.org +spec: + group: externaldns.nginx.org + names: + kind: DNSEndpoint + listKind: DNSEndpointList + plural: dnsendpoints + singular: dnsendpoint + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: DNSEndpoint is the CRD wrapper for Endpoint + 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 + metadata: + type: object + spec: + type: object + properties: + endpoints: + type: array + items: + type: object + properties: + dnsName: + description: The hostname for the DNS record + type: string + labels: + description: Labels stores labels defined for the Endpoint + type: object + additionalProperties: + type: string + providerSpecific: + description: ProviderSpecific stores provider specific config + type: array + items: + type: object + properties: + name: + description: Name of the property + type: string + value: + description: Value of the property + type: string + recordTTL: + description: TTL for the record + type: integer + format: int64 + recordType: + description: RecordType type of record, e.g. CNAME, A, SRV, TXT, MX + type: string + targets: + description: The targets the DNS service points to + type: array + items: + type: string + status: + type: object + properties: + observedGeneration: + description: The generation observed by by the external-dns controller. + type: integer + format: int64 + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/custom-resources/external-dns/README.md b/examples/custom-resources/external-dns/README.md new file mode 100644 index 0000000000..d962b0ae23 --- /dev/null +++ b/examples/custom-resources/external-dns/README.md @@ -0,0 +1,32 @@ +Step 1: Register the external-crd with the k8s api (run from the root of this repo): + + ```k apply -f deployments/common/crds/externaldns.nginx.org_dnsendpoints.yaml``` + +Step 2: Deploy external-dns + + Update `external-dns-route53.yaml` with your Domain Name and Hosted Zone ID, and apply the file. + + ```k apply -f external-dns-route53.yaml``` + +Step 3: Deploy the DNSEndpoint object + + Update `dnsendpoint.yaml` with the DNS hostname and the target IPs (the external IPs of the Ingress Controller service), and apply the file. + + ```k apply -f dnsendpoint.yaml``` + +Step 4: Check the logs of the external-dns pod, and you'll see something like this: + +``` +time="2022-05-26T15:04:45Z" level=info msg="Desired change: CREATE cafe.example.com A [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:04:45Z" level=info msg="Desired change: CREATE cafe.example.com TXT [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:04:46Z" level=info msg="2 record(s) in zone example.com. [Id: /hostedzone/Z04ABCDEFGHIJKLMNO] were successfully updated" +time="2022-05-26T15:05:45Z" level=info msg="Applying provider record filter for domains: [example.com. .example.com.]" +time="2022-05-26T15:05:45Z" level=info msg="Desired change: UPSERT cafe.example.com A [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:05:45Z" level=info msg="Desired change: UPSERT cafe.example.com TXT [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:05:46Z" level=info msg="2 record(s) in zone example.com. [Id: /hostedzone/Z04ABCDEFGHIJKLMNO] were successfully updated" +time="2022-05-26T15:06:45Z" level=info msg="Applying provider record filter for domains: [example.com. .example.com.]" +time="2022-05-26T15:06:45Z" level=info msg="Desired change: UPSERT cafe.example.com TXT [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:06:45Z" level=info msg="Desired change: DELETE cafe.example.com A [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:06:45Z" level=info msg="Desired change: CREATE cafe.example.com A [Id: /hostedzone/Z04ABCDEFGHIJKLMNO]" +time="2022-05-26T15:06:46Z" level=info msg="3 record(s) in zone example.com. [Id: /hostedzone/Z04ABCDEFGHIJKLMNO] were successfully updated" +``` diff --git a/examples/custom-resources/external-dns/dnsendpoint.yaml b/examples/custom-resources/external-dns/dnsendpoint.yaml new file mode 100644 index 0000000000..0153ace074 --- /dev/null +++ b/examples/custom-resources/external-dns/dnsendpoint.yaml @@ -0,0 +1,12 @@ +apiVersion: externaldns.nginx.org/v1 +kind: DNSEndpoint +metadata: + name: examplednsrecord +spec: + endpoints: + - dnsName: + recordTTL: 180 + recordType: A + targets: + - + - diff --git a/examples/custom-resources/external-dns/external-dns-route53.yaml b/examples/custom-resources/external-dns/external-dns-route53.yaml new file mode 100644 index 0000000000..20de16ad54 --- /dev/null +++ b/examples/custom-resources/external-dns/external-dns-route53.yaml @@ -0,0 +1,67 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: external-dns +rules: +- apiGroups: [""] + resources: ["services","endpoints","pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions","networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +- apiGroups: ["externaldns.nginx.org"] + resources: ["dnsendpoints"] + verbs: ["get","watch","list"] +- apiGroups: ["externaldns.nginx.org"] + resources: ["dnsendpoints/status"] + verbs: ["update"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["list","watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: +- kind: ServiceAccount + name: external-dns + namespace: default +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns +spec: + strategy: + type: Recreate + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + serviceAccountName: external-dns + containers: + - name: external-dns + image: k8s.gcr.io/external-dns/external-dns:v0.11.0 + args: + - --source=service + - --source=ingress + - --source=crd + - --crd-source-apiversion=externaldns.nginx.org/v1 + - --crd-source-kind=DNSEndpoint + - --domain-filter= # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones + - --provider=aws + - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization + - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both) + - --registry=txt + - --txt-owner-id= + securityContext: + fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files \ No newline at end of file diff --git a/go.mod b/go.mod index eae9439217..b221078f68 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/prometheus/client_golang v1.12.2 github.com/spiffe/go-spiffe/v2 v2.1.0 github.com/stretchr/testify v1.7.2 + golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d google.golang.org/grpc v1.47.0 k8s.io/api v0.23.6 k8s.io/apimachinery v0.23.6 @@ -99,14 +100,14 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect - golang.org/x/mod v0.5.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect + golang.org/x/tools v0.1.10 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 // indirect diff --git a/go.sum b/go.sum index 81498d7843..020760a25d 100644 --- a/go.sum +++ b/go.sum @@ -758,6 +758,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0= +golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -784,8 +786,9 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1045,8 +1048,9 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff h1:VX/uD7MK0AHXGiScH3fsieUQUcpmRERPDYtqZdJnA+Q= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index f353b44db1..1bdeddad80 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -33,6 +33,6 @@ fi # instead of the $GOPATH directly. For normal projects this can be dropped. bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" \ github.com/nginxinc/kubernetes-ingress/pkg/client github.com/nginxinc/kubernetes-ingress/pkg/apis \ - "configuration:v1alpha1,v1 dos:v1beta1" \ + "configuration:v1alpha1,v1 dos:v1beta1 externaldns:v1" \ --output-base "$(dirname "${BASH_SOURCE[0]}")/../../../.." \ --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt diff --git a/pkg/apis/externaldns/register.go b/pkg/apis/externaldns/register.go new file mode 100644 index 0000000000..53641dce4d --- /dev/null +++ b/pkg/apis/externaldns/register.go @@ -0,0 +1,6 @@ +package externaldns + +const ( + // GroupName the name of the group used by kubernetes. + GroupName = "externaldns.nginx.org" +) diff --git a/pkg/apis/externaldns/v1/doc.go b/pkg/apis/externaldns/v1/doc.go new file mode 100644 index 0000000000..2de8f750f2 --- /dev/null +++ b/pkg/apis/externaldns/v1/doc.go @@ -0,0 +1,5 @@ +// +k8s:deepcopy-gen=package +// +groupName=externaldns.nginx.org + +// Package v1 is the v1 version of the API. +package v1 diff --git a/pkg/apis/externaldns/v1/register.go b/pkg/apis/externaldns/v1/register.go new file mode 100644 index 0000000000..ed304ca203 --- /dev/null +++ b/pkg/apis/externaldns/v1/register.go @@ -0,0 +1,37 @@ +package v1 + +import ( + "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns" + 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 object. +var SchemeGroupVersion = schema.GroupVersion{Group: externaldns.GroupName, Version: "v1"} + +// 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 builds a scheme + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme a function to add to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &DNSEndpoint{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/externaldns/v1/types.go b/pkg/apis/externaldns/v1/types.go new file mode 100644 index 0000000000..400159b8ea --- /dev/null +++ b/pkg/apis/externaldns/v1/types.go @@ -0,0 +1,83 @@ +package v1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DNSEndpoint is the CRD wrapper for Endpoint +// +k8s:openapi-gen=true +// +kubebuilder:resource:path=dnsendpoints +// +kubebuilder:subresource:status +type DNSEndpoint struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DNSEndpointSpec `json:"spec,omitempty"` + Status DNSEndpointStatus `json:"status,omitempty"` +} + +// DNSEndpointStatus represents generation observed by the external dns controller. +type DNSEndpointStatus struct { + // The generation observed by by the external-dns controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// DNSEndpointSpec holds information about endpoints. +type DNSEndpointSpec struct { + Endpoints []*Endpoint `json:"endpoints,omitempty"` +} + +// Endpoint describes DNS Endpoint. +type Endpoint struct { + // The hostname for the DNS record + DNSName string `json:"dnsName,omitempty"` + + // The targets the DNS service points to + Targets Targets `json:"targets,omitempty"` + + // RecordType type of record, e.g. CNAME, A, SRV, TXT, MX + RecordType string `json:"recordType,omitempty"` + + // TTL for the record + RecordTTL TTL `json:"recordTTL,omitempty"` + + // Labels stores labels defined for the Endpoint + // +optional + Labels Labels `json:"labels,omitempty"` + + // ProviderSpecific stores provider specific config + // +optional + ProviderSpecific ProviderSpecific `json:"providerSpecific,omitempty"` +} + +// ProviderSpecific represents provider specific configuration. +type ProviderSpecific []ProviderSpecificProperty + +// ProviderSpecificProperty represents provider specific config property. +type ProviderSpecificProperty struct { + // Name of the property + Name string `json:"name,omitempty"` + // Value of the property + Value string `json:"value,omitempty"` +} + +// TTL represents TTL for DNS record. +type TTL int64 + +// Targets describe targets the DNS service points to. +type Targets []string + +// Labels describe labels defined for the Endpoint. +type Labels map[string]string + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DNSEndpointList is a list of the DNSEndpoint resources. +type DNSEndpointList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []DNSEndpoint `json:"items"` +} diff --git a/pkg/apis/externaldns/v1/zz_generated.deepcopy.go b/pkg/apis/externaldns/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..fedcf4d90b --- /dev/null +++ b/pkg/apis/externaldns/v1/zz_generated.deepcopy.go @@ -0,0 +1,225 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + 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 *DNSEndpoint) DeepCopyInto(out *DNSEndpoint) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpoint. +func (in *DNSEndpoint) DeepCopy() *DNSEndpoint { + if in == nil { + return nil + } + out := new(DNSEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DNSEndpoint) 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 *DNSEndpointList) DeepCopyInto(out *DNSEndpointList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DNSEndpoint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointList. +func (in *DNSEndpointList) DeepCopy() *DNSEndpointList { + if in == nil { + return nil + } + out := new(DNSEndpointList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DNSEndpointList) 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 *DNSEndpointSpec) DeepCopyInto(out *DNSEndpointSpec) { + *out = *in + if in.Endpoints != nil { + in, out := &in.Endpoints, &out.Endpoints + *out = make([]*Endpoint, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Endpoint) + (*in).DeepCopyInto(*out) + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointSpec. +func (in *DNSEndpointSpec) DeepCopy() *DNSEndpointSpec { + if in == nil { + return nil + } + out := new(DNSEndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DNSEndpointStatus) DeepCopyInto(out *DNSEndpointStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointStatus. +func (in *DNSEndpointStatus) DeepCopy() *DNSEndpointStatus { + if in == nil { + return nil + } + out := new(DNSEndpointStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Endpoint) DeepCopyInto(out *Endpoint) { + *out = *in + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make(Targets, len(*in)) + copy(*out, *in) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ProviderSpecific != nil { + in, out := &in.ProviderSpecific, &out.ProviderSpecific + *out = make(ProviderSpecific, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. +func (in *Endpoint) DeepCopy() *Endpoint { + if in == nil { + return nil + } + out := new(Endpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Labels) DeepCopyInto(out *Labels) { + { + in := &in + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Labels. +func (in Labels) DeepCopy() Labels { + if in == nil { + return nil + } + out := new(Labels) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ProviderSpecific) DeepCopyInto(out *ProviderSpecific) { + { + in := &in + *out = make(ProviderSpecific, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderSpecific. +func (in ProviderSpecific) DeepCopy() ProviderSpecific { + if in == nil { + return nil + } + out := new(ProviderSpecific) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProviderSpecificProperty) DeepCopyInto(out *ProviderSpecificProperty) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderSpecificProperty. +func (in *ProviderSpecificProperty) DeepCopy() *ProviderSpecificProperty { + if in == nil { + return nil + } + out := new(ProviderSpecificProperty) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Targets) DeepCopyInto(out *Targets) { + { + in := &in + *out = make(Targets, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Targets. +func (in Targets) DeepCopy() Targets { + if in == nil { + return nil + } + out := new(Targets) + in.DeepCopyInto(out) + return *out +} diff --git a/pkg/apis/externaldns/validation/doc.go b/pkg/apis/externaldns/validation/doc.go new file mode 100644 index 0000000000..2cb2201333 --- /dev/null +++ b/pkg/apis/externaldns/validation/doc.go @@ -0,0 +1,2 @@ +// Package validation provides validation rules for the ExternalDNS CRD. +package validation diff --git a/pkg/apis/externaldns/validation/externaldns.go b/pkg/apis/externaldns/validation/externaldns.go new file mode 100644 index 0000000000..875a3bc0e2 --- /dev/null +++ b/pkg/apis/externaldns/validation/externaldns.go @@ -0,0 +1,132 @@ +package validation + +import ( + "errors" + "fmt" + "strings" + + "golang.org/x/exp/slices" + + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + "k8s.io/apimachinery/pkg/util/validation" +) + +// ValidateDNSEndpoint validates if all DNSEndpoint fields are valid. +func ValidateDNSEndpoint(dnsendpoint *v1.DNSEndpoint) error { + return validateDNSEndpointSpec(&dnsendpoint.Spec) +} + +func validateDNSEndpointSpec(es *v1.DNSEndpointSpec) error { + if len(es.Endpoints) == 0 { + return fmt.Errorf("%w: no endpoints supplied, expected a list of endpoints", ErrTypeRequired) + } + for _, endpoint := range es.Endpoints { + if err := validateEndpoint(endpoint); err != nil { + return err + } + } + return nil +} + +func validateEndpoint(e *v1.Endpoint) error { + if err := validateDNSName(e.DNSName); err != nil { + return err + } + if err := validateTargets(e.Targets); err != nil { + return err + } + if err := validateDNSRecordType(e.RecordType); err != nil { + return err + } + return validateTTL(e.RecordTTL) +} + +func validateDNSName(name string) error { + if issues := validation.IsDNS1123Subdomain(name); len(issues) > 0 { + return fmt.Errorf("%w: name %s, %s", ErrTypeInvalid, name, strings.Join(issues, ", ")) + } + return nil +} + +func validateTargets(targets v1.Targets) error { + for _, target := range targets { + switch { + case strings.Contains(target, ":"): + if errMsg := validation.IsValidIP(target); len(errMsg) > 0 { + return fmt.Errorf("%w: target %q is invalid: %s", ErrTypeInvalid, target, errMsg[0]) + } + default: + if err := isFullyQualifiedDomainName(target); err != nil { + return fmt.Errorf("%w: target %q is invalid, it should be a valid IP address or hostname", ErrTypeInvalid, target) + } + } + } + return isUnique(targets) +} + +func isUnique(targets v1.Targets) error { + occurred := make(map[string]bool) + for _, target := range targets { + if occurred[target] { + return fmt.Errorf("%w: target %s, expected unique targets", ErrTypeDuplicated, target) + } + occurred[target] = true + } + return nil +} + +func validateDNSRecordType(record string) error { + if !slices.Contains(validRecords, record) { + return fmt.Errorf("%w: record %s, %s", ErrTypeNotSupported, record, strings.Join(validRecords, ",")) + } + return nil +} + +func validateTTL(ttl v1.TTL) error { + if ttl <= 0 { + return fmt.Errorf("%w: ttl %d, ttl value should be > 0", ErrTypeNotInRange, ttl) + } + return nil +} + +func isFullyQualifiedDomainName(name string) error { + if name == "" { + return fmt.Errorf("%w: name not provided", ErrTypeInvalid) + } + name = strings.TrimSuffix(name, ".") + if issues := validation.IsDNS1123Subdomain(name); len(issues) > 0 { + return fmt.Errorf("%w: name %s is not valid subdomain, %s", ErrTypeInvalid, name, strings.Join(issues, ", ")) + } + if len(strings.Split(name, ".")) < 2 { + return fmt.Errorf("%w: name %s should be a domain with at least two segments separated by dots", ErrTypeInvalid, name) + } + for _, label := range strings.Split(name, ".") { + if issues := validation.IsDNS1123Label(label); len(issues) > 0 { + return fmt.Errorf("%w: label %s should conform to the definition of label in DNS (RFC1123), %s", ErrTypeInvalid, label, strings.Join(issues, ", ")) + } + } + return nil +} + +var ( + // validRecords represents allowed DNS record names + // + // NGINX ingress controller at the moment supports + // a subset of DNS record types listed in the external-dns project. + validRecords = []string{"A", "CNAME", "AAAA"} + + // ErrTypeNotSupported indicates that provided value is not currently supported. + ErrTypeNotSupported = errors.New("type not supported") + + // ErrTypeInvalid indicates that provided value is invalid. + ErrTypeInvalid = errors.New("type invalid") + + // ErrTypeDuplicated indicates that provided values must be unique. + ErrTypeDuplicated = errors.New("type duplicated") + + // ErrTypeRequired indicates that value is not provided but it's mandatory. + ErrTypeRequired = errors.New("type required") + + // ErrTypeNotInRange indicates that provided value is outside of defined range. + ErrTypeNotInRange = errors.New("type not in range") +) diff --git a/pkg/apis/externaldns/validation/externaldns_test.go b/pkg/apis/externaldns/validation/externaldns_test.go new file mode 100644 index 0000000000..35a30305cf --- /dev/null +++ b/pkg/apis/externaldns/validation/externaldns_test.go @@ -0,0 +1,292 @@ +package validation_test + +import ( + "errors" + "testing" + + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/validation" +) + +func TestValidateDNSEndpoint(t *testing.T) { + t.Parallel() + tt := []struct { + name string + endpoint v1.DNSEndpoint + }{ + { + name: "with a single valid endpoint", + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"10.2.2.3"}, + RecordType: "A", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "with a single IPv6 target", + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"2001:db8:0:0:0:0:2:1"}, + RecordType: "A", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "with multiple valid endpoints", + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"10.2.2.3"}, + RecordType: "A", + RecordTTL: 600, + }, + { + DNSName: "example.co.uk", + Targets: v1.Targets{"10.2.2.3"}, + RecordType: "CNAME", + RecordTTL: 900, + }, + { + DNSName: "example.ie", + Targets: v1.Targets{"2001:db8:0:0:0:0:2:1"}, + RecordType: "AAAA", + RecordTTL: 900, + }, + }, + }, + }, + }, + { + name: "with multiple valid endpoints and multiple targets", + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"example.ie", "example.io"}, + RecordType: "CNAME", + RecordTTL: 600, + }, + { + DNSName: "example.co.uk", + Targets: v1.Targets{"10.2.2.3", "192.123.23.4"}, + RecordType: "A", + RecordTTL: 900, + }, + }, + }, + }, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + if err := validation.ValidateDNSEndpoint(&tc.endpoint); err != nil { + t.Fatalf("want no error on %v, got %v", tc.endpoint, err) + } + }) + } +} + +func TestValidateDNSEndpoint_ReturnsErrorOn(t *testing.T) { + t.Parallel() + tt := []struct { + name string + want error + endpoint v1.DNSEndpoint + }{ + { + name: "not supported DNS record type", + want: validation.ErrTypeNotSupported, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"10.2.2.3"}, + RecordType: "bogusRecordType", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "bogus target hostname", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"bogusTargetName"}, + RecordType: "A", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "bogus target IPv6 address", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"2001:::0:0:0:0:2:1"}, + RecordType: "A", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "duplicated target", + want: validation.ErrTypeDuplicated, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"acme.com", "10.2.2.3", "acme.com"}, + RecordType: "A", + RecordTTL: 600, + }, + }, + }, + }, + }, + { + name: "bogus ttl record", + want: validation.ErrTypeNotInRange, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"10.2.2.3", "acme.com"}, + RecordType: "A", + RecordTTL: 0, + }, + }, + }, + }, + }, + { + name: "bogus dns name", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "bogusDNSName", + Targets: v1.Targets{"acme.com"}, + RecordType: "A", + RecordTTL: 1800, + }, + }, + }, + }, + }, + { + name: "empty dns name", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "", + Targets: v1.Targets{"acme.com"}, + RecordType: "A", + RecordTTL: 1800, + }, + }, + }, + }, + }, + { + name: "bogus target name", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"acme."}, + RecordType: "A", + RecordTTL: 1800, + }, + }, + }, + }, + }, + { + name: "empty target name", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{""}, + RecordType: "A", + RecordTTL: 1800, + }, + }, + }, + }, + }, + { + name: "bogus target name", + want: validation.ErrTypeInvalid, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{ + { + DNSName: "example.com", + Targets: v1.Targets{"&$$.*&^"}, + RecordType: "A", + RecordTTL: 1800, + }, + }, + }, + }, + }, + { + name: "empty slice of endpoints", + want: validation.ErrTypeRequired, + endpoint: v1.DNSEndpoint{ + Spec: v1.DNSEndpointSpec{ + Endpoints: []*v1.Endpoint{}, + }, + }, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + err := validation.ValidateDNSEndpoint(&tc.endpoint) + if !errors.Is(err, tc.want) { + t.Errorf("want %s, got %v", tc.want, err) + } + }) + } +} diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 00d11fdd32..8eb1d01b18 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -9,6 +9,7 @@ import ( k8sv1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/configuration/v1" k8sv1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/configuration/v1alpha1" appprotectdosv1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/dos/v1beta1" + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/externaldns/v1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" @@ -19,6 +20,7 @@ type Interface interface { K8sV1alpha1() k8sv1alpha1.K8sV1alpha1Interface K8sV1() k8sv1.K8sV1Interface AppprotectdosV1beta1() appprotectdosv1beta1.AppprotectdosV1beta1Interface + ExternaldnsV1() externaldnsv1.ExternaldnsV1Interface } // Clientset contains the clients for groups. Each group has exactly one @@ -28,6 +30,7 @@ type Clientset struct { k8sV1alpha1 *k8sv1alpha1.K8sV1alpha1Client k8sV1 *k8sv1.K8sV1Client appprotectdosV1beta1 *appprotectdosv1beta1.AppprotectdosV1beta1Client + externaldnsV1 *externaldnsv1.ExternaldnsV1Client } // K8sV1alpha1 retrieves the K8sV1alpha1Client @@ -45,6 +48,11 @@ func (c *Clientset) AppprotectdosV1beta1() appprotectdosv1beta1.AppprotectdosV1b return c.appprotectdosV1beta1 } +// ExternaldnsV1 retrieves the ExternaldnsV1Client +func (c *Clientset) ExternaldnsV1() externaldnsv1.ExternaldnsV1Interface { + return c.externaldnsV1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -101,6 +109,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.externaldnsV1, err = externaldnsv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) if err != nil { @@ -125,6 +137,7 @@ func New(c rest.Interface) *Clientset { cs.k8sV1alpha1 = k8sv1alpha1.New(c) cs.k8sV1 = k8sv1.New(c) cs.appprotectdosV1beta1 = appprotectdosv1beta1.New(c) + cs.externaldnsV1 = externaldnsv1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index c6b371b0a8..6f23a69f15 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -10,6 +10,8 @@ import ( fakek8sv1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/configuration/v1alpha1/fake" appprotectdosv1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/dos/v1beta1" fakeappprotectdosv1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/dos/v1beta1/fake" + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/externaldns/v1" + fakeexternaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/externaldns/v1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" @@ -81,3 +83,8 @@ func (c *Clientset) K8sV1() k8sv1.K8sV1Interface { func (c *Clientset) AppprotectdosV1beta1() appprotectdosv1beta1.AppprotectdosV1beta1Interface { return &fakeappprotectdosv1beta1.FakeAppprotectdosV1beta1{Fake: &c.Fake} } + +// ExternaldnsV1 retrieves the ExternaldnsV1Client +func (c *Clientset) ExternaldnsV1() externaldnsv1.ExternaldnsV1Interface { + return &fakeexternaldnsv1.FakeExternaldnsV1{Fake: &c.Fake} +} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 48e1f1eb51..39a686897b 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -6,6 +6,7 @@ import ( k8sv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1" k8sv1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1" appprotectdosv1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/dos/v1beta1" + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -20,6 +21,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ k8sv1alpha1.AddToScheme, k8sv1.AddToScheme, appprotectdosv1beta1.AddToScheme, + externaldnsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 4d37ce9f1b..c1621807d9 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -6,6 +6,7 @@ import ( k8sv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1" k8sv1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1" appprotectdosv1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/dos/v1beta1" + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -20,6 +21,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ k8sv1alpha1.AddToScheme, k8sv1.AddToScheme, appprotectdosv1beta1.AddToScheme, + externaldnsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/dnsendpoint.go b/pkg/client/clientset/versioned/typed/externaldns/v1/dnsendpoint.go new file mode 100644 index 0000000000..a90773de76 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/dnsendpoint.go @@ -0,0 +1,179 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + scheme "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/scheme" + metav1 "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" +) + +// DNSEndpointsGetter has a method to return a DNSEndpointInterface. +// A group's client should implement this interface. +type DNSEndpointsGetter interface { + DNSEndpoints(namespace string) DNSEndpointInterface +} + +// DNSEndpointInterface has methods to work with DNSEndpoint resources. +type DNSEndpointInterface interface { + Create(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.CreateOptions) (*v1.DNSEndpoint, error) + Update(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.UpdateOptions) (*v1.DNSEndpoint, error) + UpdateStatus(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.UpdateOptions) (*v1.DNSEndpoint, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.DNSEndpoint, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.DNSEndpointList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.DNSEndpoint, err error) + DNSEndpointExpansion +} + +// dNSEndpoints implements DNSEndpointInterface +type dNSEndpoints struct { + client rest.Interface + ns string +} + +// newDNSEndpoints returns a DNSEndpoints +func newDNSEndpoints(c *ExternaldnsV1Client, namespace string) *dNSEndpoints { + return &dNSEndpoints{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the dNSEndpoint, and returns the corresponding dNSEndpoint object, and an error if there is any. +func (c *dNSEndpoints) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.DNSEndpoint, err error) { + result = &v1.DNSEndpoint{} + err = c.client.Get(). + Namespace(c.ns). + Resource("dnsendpoints"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of DNSEndpoints that match those selectors. +func (c *dNSEndpoints) List(ctx context.Context, opts metav1.ListOptions) (result *v1.DNSEndpointList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.DNSEndpointList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("dnsendpoints"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested dNSEndpoints. +func (c *dNSEndpoints) Watch(ctx context.Context, opts metav1.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("dnsendpoints"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a dNSEndpoint and creates it. Returns the server's representation of the dNSEndpoint, and an error, if there is any. +func (c *dNSEndpoints) Create(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.CreateOptions) (result *v1.DNSEndpoint, err error) { + result = &v1.DNSEndpoint{} + err = c.client.Post(). + Namespace(c.ns). + Resource("dnsendpoints"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(dNSEndpoint). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a dNSEndpoint and updates it. Returns the server's representation of the dNSEndpoint, and an error, if there is any. +func (c *dNSEndpoints) Update(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.UpdateOptions) (result *v1.DNSEndpoint, err error) { + result = &v1.DNSEndpoint{} + err = c.client.Put(). + Namespace(c.ns). + Resource("dnsendpoints"). + Name(dNSEndpoint.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(dNSEndpoint). + 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 *dNSEndpoints) UpdateStatus(ctx context.Context, dNSEndpoint *v1.DNSEndpoint, opts metav1.UpdateOptions) (result *v1.DNSEndpoint, err error) { + result = &v1.DNSEndpoint{} + err = c.client.Put(). + Namespace(c.ns). + Resource("dnsendpoints"). + Name(dNSEndpoint.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(dNSEndpoint). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the dNSEndpoint and deletes it. Returns an error if one occurs. +func (c *dNSEndpoints) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("dnsendpoints"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *dNSEndpoints) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.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("dnsendpoints"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched dNSEndpoint. +func (c *dNSEndpoints) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.DNSEndpoint, err error) { + result = &v1.DNSEndpoint{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("dnsendpoints"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/doc.go b/pkg/client/clientset/versioned/typed/externaldns/v1/doc.go new file mode 100644 index 0000000000..225e6b2be3 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/doc.go @@ -0,0 +1,4 @@ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/externaldns_client.go b/pkg/client/clientset/versioned/typed/externaldns/v1/externaldns_client.go new file mode 100644 index 0000000000..2e9b1232e9 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/externaldns_client.go @@ -0,0 +1,91 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type ExternaldnsV1Interface interface { + RESTClient() rest.Interface + DNSEndpointsGetter +} + +// ExternaldnsV1Client is used to interact with features provided by the externaldns.nginx.org group. +type ExternaldnsV1Client struct { + restClient rest.Interface +} + +func (c *ExternaldnsV1Client) DNSEndpoints(namespace string) DNSEndpointInterface { + return newDNSEndpoints(c, namespace) +} + +// NewForConfig creates a new ExternaldnsV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*ExternaldnsV1Client, 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 ExternaldnsV1Client 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) (*ExternaldnsV1Client, 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 &ExternaldnsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new ExternaldnsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ExternaldnsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ExternaldnsV1Client for the given RESTClient. +func New(c rest.Interface) *ExternaldnsV1Client { + return &ExternaldnsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.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 *ExternaldnsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/fake/doc.go b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/doc.go new file mode 100644 index 0000000000..2b5ba4c8e4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/doc.go @@ -0,0 +1,4 @@ +// 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/externaldns/v1/fake/fake_dnsendpoint.go b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/fake_dnsendpoint.go new file mode 100644 index 0000000000..24590c7ce5 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/fake_dnsendpoint.go @@ -0,0 +1,126 @@ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeDNSEndpoints implements DNSEndpointInterface +type FakeDNSEndpoints struct { + Fake *FakeExternaldnsV1 + ns string +} + +var dnsendpointsResource = schema.GroupVersionResource{Group: "externaldns.nginx.org", Version: "v1", Resource: "dnsendpoints"} + +var dnsendpointsKind = schema.GroupVersionKind{Group: "externaldns.nginx.org", Version: "v1", Kind: "DNSEndpoint"} + +// Get takes name of the dNSEndpoint, and returns the corresponding dNSEndpoint object, and an error if there is any. +func (c *FakeDNSEndpoints) Get(ctx context.Context, name string, options v1.GetOptions) (result *externaldnsv1.DNSEndpoint, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(dnsendpointsResource, c.ns, name), &externaldnsv1.DNSEndpoint{}) + + if obj == nil { + return nil, err + } + return obj.(*externaldnsv1.DNSEndpoint), err +} + +// List takes label and field selectors, and returns the list of DNSEndpoints that match those selectors. +func (c *FakeDNSEndpoints) List(ctx context.Context, opts v1.ListOptions) (result *externaldnsv1.DNSEndpointList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(dnsendpointsResource, dnsendpointsKind, c.ns, opts), &externaldnsv1.DNSEndpointList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &externaldnsv1.DNSEndpointList{ListMeta: obj.(*externaldnsv1.DNSEndpointList).ListMeta} + for _, item := range obj.(*externaldnsv1.DNSEndpointList).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 dNSEndpoints. +func (c *FakeDNSEndpoints) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(dnsendpointsResource, c.ns, opts)) + +} + +// Create takes the representation of a dNSEndpoint and creates it. Returns the server's representation of the dNSEndpoint, and an error, if there is any. +func (c *FakeDNSEndpoints) Create(ctx context.Context, dNSEndpoint *externaldnsv1.DNSEndpoint, opts v1.CreateOptions) (result *externaldnsv1.DNSEndpoint, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(dnsendpointsResource, c.ns, dNSEndpoint), &externaldnsv1.DNSEndpoint{}) + + if obj == nil { + return nil, err + } + return obj.(*externaldnsv1.DNSEndpoint), err +} + +// Update takes the representation of a dNSEndpoint and updates it. Returns the server's representation of the dNSEndpoint, and an error, if there is any. +func (c *FakeDNSEndpoints) Update(ctx context.Context, dNSEndpoint *externaldnsv1.DNSEndpoint, opts v1.UpdateOptions) (result *externaldnsv1.DNSEndpoint, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(dnsendpointsResource, c.ns, dNSEndpoint), &externaldnsv1.DNSEndpoint{}) + + if obj == nil { + return nil, err + } + return obj.(*externaldnsv1.DNSEndpoint), 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 *FakeDNSEndpoints) UpdateStatus(ctx context.Context, dNSEndpoint *externaldnsv1.DNSEndpoint, opts v1.UpdateOptions) (*externaldnsv1.DNSEndpoint, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(dnsendpointsResource, "status", c.ns, dNSEndpoint), &externaldnsv1.DNSEndpoint{}) + + if obj == nil { + return nil, err + } + return obj.(*externaldnsv1.DNSEndpoint), err +} + +// Delete takes name of the dNSEndpoint and deletes it. Returns an error if one occurs. +func (c *FakeDNSEndpoints) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(dnsendpointsResource, c.ns, name, opts), &externaldnsv1.DNSEndpoint{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeDNSEndpoints) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(dnsendpointsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &externaldnsv1.DNSEndpointList{}) + return err +} + +// Patch applies the patch and returns the patched dNSEndpoint. +func (c *FakeDNSEndpoints) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *externaldnsv1.DNSEndpoint, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(dnsendpointsResource, c.ns, name, pt, data, subresources...), &externaldnsv1.DNSEndpoint{}) + + if obj == nil { + return nil, err + } + return obj.(*externaldnsv1.DNSEndpoint), err +} diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/fake/fake_externaldns_client.go b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/fake_externaldns_client.go new file mode 100644 index 0000000000..ccc09f3e04 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/fake/fake_externaldns_client.go @@ -0,0 +1,24 @@ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned/typed/externaldns/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeExternaldnsV1 struct { + *testing.Fake +} + +func (c *FakeExternaldnsV1) DNSEndpoints(namespace string) v1.DNSEndpointInterface { + return &FakeDNSEndpoints{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeExternaldnsV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/externaldns/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/externaldns/v1/generated_expansion.go new file mode 100644 index 0000000000..11ee66fb29 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/externaldns/v1/generated_expansion.go @@ -0,0 +1,5 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type DNSEndpointExpansion interface{} diff --git a/pkg/client/informers/externalversions/externaldns/interface.go b/pkg/client/informers/externalversions/externaldns/interface.go new file mode 100644 index 0000000000..947e6b788a --- /dev/null +++ b/pkg/client/informers/externalversions/externaldns/interface.go @@ -0,0 +1,30 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package externaldns + +import ( + v1 "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/externaldns/v1" + internalinterfaces "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface +} + +type group 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 &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/externaldns/v1/dnsendpoint.go b/pkg/client/informers/externalversions/externaldns/v1/dnsendpoint.go new file mode 100644 index 0000000000..331f9057df --- /dev/null +++ b/pkg/client/informers/externalversions/externaldns/v1/dnsendpoint.go @@ -0,0 +1,74 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + externaldnsv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + versioned "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned" + internalinterfaces "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/nginxinc/kubernetes-ingress/pkg/client/listers/externaldns/v1" + metav1 "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" +) + +// DNSEndpointInformer provides access to a shared informer and lister for +// DNSEndpoints. +type DNSEndpointInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.DNSEndpointLister +} + +type dNSEndpointInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewDNSEndpointInformer constructs a new informer for DNSEndpoint 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 NewDNSEndpointInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredDNSEndpointInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredDNSEndpointInformer constructs a new informer for DNSEndpoint 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 NewFilteredDNSEndpointInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExternaldnsV1().DNSEndpoints(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ExternaldnsV1().DNSEndpoints(namespace).Watch(context.TODO(), options) + }, + }, + &externaldnsv1.DNSEndpoint{}, + resyncPeriod, + indexers, + ) +} + +func (f *dNSEndpointInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredDNSEndpointInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *dNSEndpointInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&externaldnsv1.DNSEndpoint{}, f.defaultInformer) +} + +func (f *dNSEndpointInformer) Lister() v1.DNSEndpointLister { + return v1.NewDNSEndpointLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/externaldns/v1/interface.go b/pkg/client/informers/externalversions/externaldns/v1/interface.go new file mode 100644 index 0000000000..747d4431af --- /dev/null +++ b/pkg/client/informers/externalversions/externaldns/v1/interface.go @@ -0,0 +1,29 @@ +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // DNSEndpoints returns a DNSEndpointInformer. + DNSEndpoints() DNSEndpointInformer +} + +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} +} + +// DNSEndpoints returns a DNSEndpointInformer. +func (v *version) DNSEndpoints() DNSEndpointInformer { + return &dNSEndpointInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index ddff0833af..d6c85897ff 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -10,6 +10,7 @@ import ( versioned "github.com/nginxinc/kubernetes-ingress/pkg/client/clientset/versioned" configuration "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/configuration" dos "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/dos" + externaldns "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/externaldns" internalinterfaces "github.com/nginxinc/kubernetes-ingress/pkg/client/informers/externalversions/internalinterfaces" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -159,6 +160,7 @@ type SharedInformerFactory interface { K8s() configuration.Interface Appprotectdos() dos.Interface + Externaldns() externaldns.Interface } func (f *sharedInformerFactory) K8s() configuration.Interface { @@ -168,3 +170,7 @@ func (f *sharedInformerFactory) K8s() configuration.Interface { func (f *sharedInformerFactory) Appprotectdos() dos.Interface { return dos.New(f, f.namespace, f.tweakListOptions) } + +func (f *sharedInformerFactory) Externaldns() externaldns.Interface { + return externaldns.New(f, f.namespace, f.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index d466da36d6..6780037382 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -5,9 +5,10 @@ package externalversions import ( "fmt" - v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1" + configurationv1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1" v1alpha1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1" v1beta1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/dos/v1beta1" + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) @@ -42,12 +43,16 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1beta1.SchemeGroupVersion.WithResource("dosprotectedresources"): return &genericInformer{resource: resource.GroupResource(), informer: f.Appprotectdos().V1beta1().DosProtectedResources().Informer()}, nil + // Group=externaldns.nginx.org, Version=v1 + case v1.SchemeGroupVersion.WithResource("dnsendpoints"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Externaldns().V1().DNSEndpoints().Informer()}, nil + // Group=k8s.nginx.org, Version=v1 - case v1.SchemeGroupVersion.WithResource("policies"): + case configurationv1.SchemeGroupVersion.WithResource("policies"): return &genericInformer{resource: resource.GroupResource(), informer: f.K8s().V1().Policies().Informer()}, nil - case v1.SchemeGroupVersion.WithResource("virtualservers"): + case configurationv1.SchemeGroupVersion.WithResource("virtualservers"): return &genericInformer{resource: resource.GroupResource(), informer: f.K8s().V1().VirtualServers().Informer()}, nil - case v1.SchemeGroupVersion.WithResource("virtualserverroutes"): + case configurationv1.SchemeGroupVersion.WithResource("virtualserverroutes"): return &genericInformer{resource: resource.GroupResource(), informer: f.K8s().V1().VirtualServerRoutes().Informer()}, nil // Group=k8s.nginx.org, Version=v1alpha1 diff --git a/pkg/client/listers/externaldns/v1/dnsendpoint.go b/pkg/client/listers/externaldns/v1/dnsendpoint.go new file mode 100644 index 0000000000..2709268b42 --- /dev/null +++ b/pkg/client/listers/externaldns/v1/dnsendpoint.go @@ -0,0 +1,83 @@ +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/externaldns/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// DNSEndpointLister helps list DNSEndpoints. +// All objects returned here must be treated as read-only. +type DNSEndpointLister interface { + // List lists all DNSEndpoints in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.DNSEndpoint, err error) + // DNSEndpoints returns an object that can list and get DNSEndpoints. + DNSEndpoints(namespace string) DNSEndpointNamespaceLister + DNSEndpointListerExpansion +} + +// dNSEndpointLister implements the DNSEndpointLister interface. +type dNSEndpointLister struct { + indexer cache.Indexer +} + +// NewDNSEndpointLister returns a new DNSEndpointLister. +func NewDNSEndpointLister(indexer cache.Indexer) DNSEndpointLister { + return &dNSEndpointLister{indexer: indexer} +} + +// List lists all DNSEndpoints in the indexer. +func (s *dNSEndpointLister) List(selector labels.Selector) (ret []*v1.DNSEndpoint, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.DNSEndpoint)) + }) + return ret, err +} + +// DNSEndpoints returns an object that can list and get DNSEndpoints. +func (s *dNSEndpointLister) DNSEndpoints(namespace string) DNSEndpointNamespaceLister { + return dNSEndpointNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// DNSEndpointNamespaceLister helps list and get DNSEndpoints. +// All objects returned here must be treated as read-only. +type DNSEndpointNamespaceLister interface { + // List lists all DNSEndpoints in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.DNSEndpoint, err error) + // Get retrieves the DNSEndpoint from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.DNSEndpoint, error) + DNSEndpointNamespaceListerExpansion +} + +// dNSEndpointNamespaceLister implements the DNSEndpointNamespaceLister +// interface. +type dNSEndpointNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all DNSEndpoints in the indexer for a given namespace. +func (s dNSEndpointNamespaceLister) List(selector labels.Selector) (ret []*v1.DNSEndpoint, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.DNSEndpoint)) + }) + return ret, err +} + +// Get retrieves the DNSEndpoint from the indexer for a given namespace and name. +func (s dNSEndpointNamespaceLister) Get(name string) (*v1.DNSEndpoint, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("dnsendpoint"), name) + } + return obj.(*v1.DNSEndpoint), nil +} diff --git a/pkg/client/listers/externaldns/v1/expansion_generated.go b/pkg/client/listers/externaldns/v1/expansion_generated.go new file mode 100644 index 0000000000..475dd2c698 --- /dev/null +++ b/pkg/client/listers/externaldns/v1/expansion_generated.go @@ -0,0 +1,11 @@ +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// DNSEndpointListerExpansion allows custom methods to be added to +// DNSEndpointLister. +type DNSEndpointListerExpansion interface{} + +// DNSEndpointNamespaceListerExpansion allows custom methods to be added to +// DNSEndpointNamespaceLister. +type DNSEndpointNamespaceListerExpansion interface{}