diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index 86fe2808c..69e7d8000 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -31,20 +31,6 @@ whoami: ``` ```yaml tab="Kubernetes IngressRoute" -# As a Kubernetes Traefik IngressRoute -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: middlewares.traefik.containo.us -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: Middleware - plural: middlewares - singular: middleware - scope: Namespaced - --- apiVersion: traefik.containo.us/v1alpha1 kind: Middleware diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index 3d936cb94..fc99f99f3 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -336,3 +336,15 @@ The file parser has been changed, since v2.3 the unknown options/fields in a dyn In `v2.3`, the support of `IngressClass`, which is available since Kubernetes version `1.18`, has been introduced. In order to be able to use this new resource the [Kubernetes RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) must be updated. + +## v2.4 to v2.5 + +### Kubernetes CRD + +In `v2.5`, the [Traefik CRDs](../reference/dynamic-configuration/kubernetes-crd.md#definitions) have been updated to support the new API version `apiextensions.k8s.io/v1`. +As required by `apiextensions.k8s.io/v1`, we have included the OpenAPI validation schema. + +After deploying the new [Traefik CRDs](../reference/dynamic-configuration/kubernetes-crd.md#definitions), the resources will be validated only on creation or update. + +Please note that the unknown fields will not be pruned when migrating from `apiextensions.k8s.io/v1beta1` to `apiextensions.k8s.io/v1` CRDs. +For more details check out the official [documentation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema). diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index 4465b66f2..54c7f512a 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -20,11 +20,17 @@ the Traefik engineering team developed a [Custom Resource Definition](https://ku * Apply the needed kubernetesCRD provider [configuration](#provider-configuration) * Add all necessary Traefik custom [resources](../reference/dynamic-configuration/kubernetes-crd.md#resources) +!!! warning "Deprecated apiextensions.k8s.io/v1beta1 CRD" + + The `apiextensions.k8s.io/v1beta1` CustomResourceDefinition is deprecated in Kubernetes `v1.16+` and will be removed in `v1.22+`. + + For Kubernetes `v1.16+`, please use the Traefik `apiextensions.k8s.io/v1` CRDs instead. + ??? example "Initializing Resource Definition and RBAC" ```yaml tab="Traefik Resource Definition" # All resources definition must be declared - --8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml" + --8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml" ``` ```yaml tab="RBAC for Traefik CRD" diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml new file mode 100644 index 000000000..3ec900d5f --- /dev/null +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -0,0 +1,8 @@ +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml" +--8<-- "content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml" diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml similarity index 100% rename from docs/content/reference/dynamic-configuration/kubernetes-crd-definition.yml rename to docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml index cbe4b3e34..332853401 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml @@ -63,10 +63,10 @@ spec: mirroring: name: wrr2 kind: TraefikService + # Optional + maxBodySize: 2000000000 mirrors: - name: s2 - # Optional - maxBodySize: 2000000000 # Optional, as it is the default value kind: Service percent: 20 @@ -77,6 +77,7 @@ apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: ingressroute + spec: entryPoints: - web @@ -98,6 +99,7 @@ spec: port: 433 serversTransport: mytransport - match: PathPrefix(`/misc`) + kind: Rule services: - name: s3 port: 80 @@ -105,6 +107,7 @@ spec: - name: stripprefix - name: addprefix - match: PathPrefix(`/misc`) + kind: Rule services: - name: s3 # Optional, as it is the default value @@ -113,10 +116,12 @@ spec: # scheme allow to override the scheme for the service. (ex: https or h2c) scheme: https - match: PathPrefix(`/lb`) + kind: Rule services: - name: wrr1 kind: TraefikService - match: PathPrefix(`/mirrored`) + kind: Rule services: - name: mirror1 kind: TraefikService @@ -181,10 +186,10 @@ spec: - foobar - foobar clientAuth: - caFiles: + secretNames: - foobar - foobar - clientAuthType: foobar + clientAuthType: RequireAndVerifyClientCert sniStrict: true preferServerCipherSuites: true diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd.md b/docs/content/reference/dynamic-configuration/kubernetes-crd.md index 477b082f9..ccda41843 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd.md +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd.md @@ -5,8 +5,12 @@ Dynamic configuration with Kubernetes Custom Resource ## Definitions -```yaml ---8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml" +```yaml tab="apiextensions.k8s.io/v1" +--8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml" +``` + +```yaml tab="apiextensions.k8s.io/v1beta1" +--8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml" ``` ## Resources diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml new file mode 100644 index 000000000..726341ba8 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml @@ -0,0 +1,179 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressroutes.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRoute + listKind: IngressRouteList + plural: ingressroutes + singular: ingressroute + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRoute is an Ingress CRD specification. + 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: + description: IngressRouteSpec is a specification for a IngressRouteSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: Route contains the set of routes. + properties: + kind: + enum: + - Rule + type: string + match: + type: string + middlewares: + items: + description: MiddlewareRef is a ref to the Middleware resources. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: array + priority: + type: integer + services: + items: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + required: + - kind + - match + type: object + type: array + tls: + description: "TLS contains the TLS certificates configuration of the routes. To enable Let's Encrypt, use an empty TLS struct, e.g. in YAML: \n \t tls: {} # inline format \n \t tls: \t secretName: # block format" + properties: + certResolver: + type: string + domains: + items: + description: Domain holds a domain name with SANs. + properties: + main: + type: string + sans: + items: + type: string + type: array + type: object + type: array + options: + description: Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + store: + description: Store is a reference to a TLSStore, that specifies the parameters of the TLS store. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: object + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml new file mode 100644 index 000000000..1347fa776 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml @@ -0,0 +1,134 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressroutetcps.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRouteTCP + listKind: IngressRouteTCPList + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRouteTCP is an Ingress CRD specification. + 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: + description: IngressRouteTCPSpec is a specification for a IngressRouteTCPSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: RouteTCP contains the set of routes. + properties: + match: + type: string + services: + items: + description: ServiceTCP defines an upstream to proxy traffic. + properties: + name: + type: string + namespace: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + proxyProtocol: + description: ProxyProtocol holds the ProxyProtocol configuration. + properties: + version: + type: integer + type: object + terminationDelay: + type: integer + weight: + type: integer + required: + - name + - port + type: object + type: array + required: + - match + type: object + type: array + tls: + description: "TLSTCP contains the TLS certificates configuration of the routes. To enable Let's Encrypt, use an empty TLS struct, e.g. in YAML: \n \t tls: {} # inline format \n \t tls: \t secretName: # block format" + properties: + certResolver: + type: string + domains: + items: + description: Domain holds a domain name with SANs. + properties: + main: + type: string + sans: + items: + type: string + type: array + type: object + type: array + options: + description: Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + passthrough: + type: boolean + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + store: + description: Store is a reference to a TLSStore, that specifies the parameters of the TLS store. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: object + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml new file mode 100644 index 000000000..86b045463 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml @@ -0,0 +1,79 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressrouteudps.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRouteUDP + listKind: IngressRouteUDPList + plural: ingressrouteudps + singular: ingressrouteudp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRouteUDP is an Ingress CRD specification. + 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: + description: IngressRouteUDPSpec is a specification for a IngressRouteUDPSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: RouteUDP contains the set of routes. + properties: + services: + items: + description: ServiceUDP defines an upstream to proxy traffic. + properties: + name: + type: string + namespace: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + weight: + type: integer + required: + - name + - port + type: object + type: array + type: object + type: array + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml new file mode 100644 index 000000000..a5b8029d9 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml @@ -0,0 +1,521 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: middlewares.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: Middleware + listKind: MiddlewareList + plural: middlewares + singular: middleware + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Middleware is a specification for a Middleware resource. + 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: + description: MiddlewareSpec holds the Middleware configuration. + properties: + addPrefix: + description: AddPrefix holds the AddPrefix configuration. + properties: + prefix: + type: string + type: object + basicAuth: + description: BasicAuth holds the HTTP basic authentication configuration. + properties: + headerField: + type: string + realm: + type: string + removeHeader: + type: boolean + secret: + type: string + type: object + buffering: + description: Buffering holds the request/response buffering configuration. + properties: + maxRequestBodyBytes: + format: int64 + type: integer + maxResponseBodyBytes: + format: int64 + type: integer + memRequestBodyBytes: + format: int64 + type: integer + memResponseBodyBytes: + format: int64 + type: integer + retryExpression: + type: string + type: object + chain: + description: Chain holds a chain of middlewares. + properties: + middlewares: + items: + description: MiddlewareRef is a ref to the Middleware resources. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: array + type: object + circuitBreaker: + description: CircuitBreaker holds the circuit breaker configuration. + properties: + expression: + type: string + type: object + compress: + description: Compress holds the compress configuration. + properties: + excludedContentTypes: + items: + type: string + type: array + type: object + contentType: + description: ContentType middleware - or rather its unique `autoDetect` option - specifies whether to let the `Content-Type` header, if it has not been set by the backend, be automatically set to a value derived from the contents of the response. As a proxy, the default behavior should be to leave the header alone, regardless of what the backend did with it. However, the historic default was to always auto-detect and set the header if it was nil, and it is going to be kept that way in order to support users currently relying on it. This middleware exists to enable the correct behavior until at least the default one can be changed in a future version. + properties: + autoDetect: + type: boolean + type: object + digestAuth: + description: DigestAuth holds the Digest HTTP authentication configuration. + properties: + headerField: + type: string + realm: + type: string + removeHeader: + type: boolean + secret: + type: string + type: object + errors: + description: ErrorPage holds the custom error page configuration. + properties: + query: + type: string + service: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + status: + items: + type: string + type: array + type: object + forwardAuth: + description: ForwardAuth holds the http forward authentication configuration. + properties: + address: + type: string + authRequestHeaders: + items: + type: string + type: array + authResponseHeaders: + items: + type: string + type: array + authResponseHeadersRegex: + type: string + tls: + description: ClientTLS holds TLS specific configurations as client. + properties: + caOptional: + type: boolean + caSecret: + type: string + certSecret: + type: string + insecureSkipVerify: + type: boolean + type: object + trustForwardHeader: + type: boolean + type: object + headers: + description: Headers holds the custom header configuration. + properties: + accessControlAllowCredentials: + description: AccessControlAllowCredentials is only valid if true. false is ignored. + type: boolean + accessControlAllowHeaders: + description: AccessControlAllowHeaders must be used in response to a preflight request with Access-Control-Request-Headers set. + items: + type: string + type: array + accessControlAllowMethods: + description: AccessControlAllowMethods must be used in response to a preflight request with Access-Control-Request-Method set. + items: + type: string + type: array + accessControlAllowOrigin: + description: AccessControlAllowOrigin Can be "origin-list-or-null" or "*". From (https://www.w3.org/TR/cors/#access-control-allow-origin-response-header) + type: string + accessControlAllowOriginList: + description: AccessControlAllowOriginList is a list of allowable origins. Can also be a wildcard origin "*". + items: + type: string + type: array + accessControlAllowOriginListRegex: + description: AccessControlAllowOriginListRegex is a list of allowable origins written following the Regular Expression syntax (https://golang.org/pkg/regexp/). + items: + type: string + type: array + accessControlExposeHeaders: + description: AccessControlExposeHeaders sets valid headers for the response. + items: + type: string + type: array + accessControlMaxAge: + description: AccessControlMaxAge sets the time that a preflight request may be cached. + format: int64 + type: integer + addVaryHeader: + description: AddVaryHeader controls if the Vary header is automatically added/updated when the AccessControlAllowOrigin is set. + type: boolean + allowedHosts: + items: + type: string + type: array + browserXssFilter: + type: boolean + contentSecurityPolicy: + type: string + contentTypeNosniff: + type: boolean + customBrowserXSSValue: + type: string + customFrameOptionsValue: + type: string + customRequestHeaders: + additionalProperties: + type: string + type: object + customResponseHeaders: + additionalProperties: + type: string + type: object + featurePolicy: + type: string + forceSTSHeader: + type: boolean + frameDeny: + type: boolean + hostsProxyHeaders: + items: + type: string + type: array + isDevelopment: + type: boolean + publicKey: + type: string + referrerPolicy: + type: string + sslForceHost: + type: boolean + sslHost: + type: string + sslProxyHeaders: + additionalProperties: + type: string + type: object + sslRedirect: + type: boolean + sslTemporaryRedirect: + type: boolean + stsIncludeSubdomains: + type: boolean + stsPreload: + type: boolean + stsSeconds: + format: int64 + type: integer + type: object + inFlightReq: + description: InFlightReq limits the number of requests being processed and served concurrently. + properties: + amount: + format: int64 + type: integer + sourceCriterion: + description: SourceCriterion defines what criterion is used to group requests as originating from a common source. If none are set, the default is to use the request's remote address field. All fields are mutually exclusive. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + requestHeaderName: + type: string + requestHost: + type: boolean + type: object + type: object + ipWhiteList: + description: IPWhiteList holds the ip white list configuration. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + sourceRange: + items: + type: string + type: array + type: object + passTLSClientCert: + description: PassTLSClientCert holds the TLS client cert headers configuration. + properties: + info: + description: TLSClientCertificateInfo holds the client TLS certificate info configuration. + properties: + issuer: + description: TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration. cf https://tools.ietf.org/html/rfc3739 + properties: + commonName: + type: boolean + country: + type: boolean + domainComponent: + type: boolean + locality: + type: boolean + organization: + type: boolean + province: + type: boolean + serialNumber: + type: boolean + type: object + notAfter: + type: boolean + notBefore: + type: boolean + sans: + type: boolean + serialNumber: + type: boolean + subject: + description: TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration. cf https://tools.ietf.org/html/rfc3739 + properties: + commonName: + type: boolean + country: + type: boolean + domainComponent: + type: boolean + locality: + type: boolean + organization: + type: boolean + province: + type: boolean + serialNumber: + type: boolean + type: object + type: object + pem: + type: boolean + type: object + plugin: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + rateLimit: + description: RateLimit holds the rate limiting configuration for a given router. + properties: + average: + format: int64 + type: integer + burst: + format: int64 + type: integer + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + sourceCriterion: + description: SourceCriterion defines what criterion is used to group requests as originating from a common source. If none are set, the default is to use the request's remote address field. All fields are mutually exclusive. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + requestHeaderName: + type: string + requestHost: + type: boolean + type: object + type: object + redirectRegex: + description: RedirectRegex holds the redirection configuration. + properties: + permanent: + type: boolean + regex: + type: string + replacement: + type: string + type: object + redirectScheme: + description: RedirectScheme holds the scheme redirection configuration. + properties: + permanent: + type: boolean + port: + type: string + scheme: + type: string + type: object + replacePath: + description: ReplacePath holds the ReplacePath configuration. + properties: + path: + type: string + type: object + replacePathRegex: + description: ReplacePathRegex holds the ReplacePathRegex configuration. + properties: + regex: + type: string + replacement: + type: string + type: object + retry: + description: Retry holds the retry configuration. + properties: + attempts: + type: integer + initialInterval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + stripPrefix: + description: StripPrefix holds the StripPrefix configuration. + properties: + forceSlash: + type: boolean + prefixes: + items: + type: string + type: array + type: object + stripPrefixRegex: + description: StripPrefixRegex holds the StripPrefixRegex configuration. + properties: + regex: + items: + type: string + type: array + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml new file mode 100644 index 000000000..43c9e6db9 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml @@ -0,0 +1,88 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: serverstransports.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: ServersTransport + listKind: ServersTransportList + plural: serverstransports + singular: serverstransport + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ServersTransport is a specification for a ServersTransport resource. + 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: + description: ServersTransportSpec options to configure communication between Traefik and the servers. + properties: + certificatesSecrets: + description: Certificates for mTLS. + items: + type: string + type: array + forwardingTimeouts: + description: Timeouts for requests forwarded to the backend servers. + properties: + dialTimeout: + anyOf: + - type: integer + - type: string + description: The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. + x-kubernetes-int-or-string: true + idleConnTimeout: + anyOf: + - type: integer + - type: string + description: The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself. + x-kubernetes-int-or-string: true + responseHeaderTimeout: + anyOf: + - type: integer + - type: string + description: The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. + x-kubernetes-int-or-string: true + type: object + insecureSkipVerify: + description: Disable SSL certificate verification. + type: boolean + maxIdleConnsPerHost: + description: If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. + type: integer + rootCAsSecrets: + description: Add cert file for self-signed certificate. + items: + type: string + type: array + serverName: + description: ServerName used to contact the server. + type: string + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml new file mode 100644 index 000000000..3b9bdc2f2 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml @@ -0,0 +1,80 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: tlsoptions.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TLSOption + listKind: TLSOptionList + plural: tlsoptions + singular: tlsoption + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TLSOption is a specification for a TLSOption resource. + 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: + description: TLSOptionSpec configures TLS for an entry point. + properties: + cipherSuites: + items: + type: string + type: array + clientAuth: + description: ClientAuth defines the parameters of the client authentication part of the TLS connection, if any. + properties: + clientAuthType: + description: ClientAuthType defines the client authentication type to apply. + enum: + - NoClientCert + - RequestClientCert + - VerifyClientCertIfGiven + - RequireAndVerifyClientCert + type: string + secretNames: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + items: + type: string + type: array + type: object + curvePreferences: + items: + type: string + type: array + maxVersion: + type: string + minVersion: + type: string + preferServerCipherSuites: + type: boolean + sniStrict: + type: boolean + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml new file mode 100644 index 000000000..8bc871801 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml @@ -0,0 +1,58 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: tlsstores.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TLSStore + listKind: TLSStoreList + plural: tlsstores + singular: tlsstore + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TLSStore is a specification for a TLSStore resource. + 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: + description: TLSStoreSpec configures a TLSStore resource. + properties: + defaultCertificate: + description: DefaultCertificate holds a secret name for the TLSOption resource. + properties: + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + required: + - secretName + type: object + required: + - defaultCertificate + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml new file mode 100644 index 000000000..a0792d77c --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml @@ -0,0 +1,238 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: traefikservices.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TraefikService + listKind: TraefikServiceList + plural: traefikservices + singular: traefikservice + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TraefikService is the specification for a service (that an IngressRoute refers to) that is usually not a terminal service (i.e. not a pod of servers), as opposed to a Kubernetes Service. That is to say, it usually refers to other (children) services, which themselves can be TraefikServices or Services. + 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: + description: ServiceSpec defines whether a TraefikService is a load-balancer of services or a mirroring service. + properties: + mirroring: + description: Mirroring defines a mirroring service, which is composed of a main load-balancer, and a list of mirrors. + properties: + kind: + enum: + - Service + - TraefikService + type: string + maxBodySize: + format: int64 + type: integer + mirrors: + items: + description: MirrorService defines one of the mirrors of a Mirroring service. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + percent: + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + weighted: + description: WeightedRoundRobin defines a load-balancer of services. + properties: + services: + items: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 573a26cb2..6a26e0e06 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -9,7 +9,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way. ```yaml tab="Resource Definition" # All resources definition must be declared - --8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml" + --8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml" ``` ```yaml tab="RBAC" diff --git a/docs/content/user-guides/crd-acme/index.md b/docs/content/user-guides/crd-acme/index.md index 100f63b89..04e63807b 100644 --- a/docs/content/user-guides/crd-acme/index.md +++ b/docs/content/user-guides/crd-acme/index.md @@ -43,7 +43,7 @@ First, the definition of the `IngressRoute` and the `Middleware` kinds. Also note the RBAC authorization resources; they'll be referenced through the `serviceAccountName` of the deployment, later on. ```yaml ---8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml" +--8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml" --- --8<-- "content/reference/dynamic-configuration/kubernetes-crd-rbac.yml" diff --git a/go.mod b/go.mod index b6111678b..f38fe1745 100644 --- a/go.mod +++ b/go.mod @@ -90,10 +90,12 @@ require ( gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 k8s.io/api v0.19.2 + k8s.io/apiextensions-apiserver v0.18.6 k8s.io/apimachinery v0.19.2 k8s.io/client-go v0.19.2 k8s.io/code-generator v0.19.2 mvdan.cc/xurls/v2 v2.1.0 + sigs.k8s.io/controller-tools v0.4.0 sigs.k8s.io/service-apis v0.1.0 ) diff --git a/go.sum b/go.sum index b8f5a1eaf..c4e81e53e 100644 --- a/go.sum +++ b/go.sum @@ -296,6 +296,7 @@ github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQo github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exoscale/egoscale v0.23.0 h1:hoUDzrO8yNoobNdnrRvlRFjfg3Ng0vQTrv6bXRJu6z0= github.com/exoscale/egoscale v0.23.0/go.mod h1:hRo78jkjkCDKpivQdRBEpNYF5+cVpCJCPDg2/r45KaY= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= @@ -391,6 +392,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/flect v0.2.0 h1:EWCvMGGxOjsgwlWaP+f4+Hh6yrrte7JeFL2S6b+0hdM= github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= @@ -565,6 +567,7 @@ github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -651,9 +654,11 @@ github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0a github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -908,6 +913,7 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1422,6 +1428,7 @@ k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI= k8s.io/api v0.19.2 h1:q+/krnHWKsL7OBZg/rxnycsl9569Pud76UJ77MvKXms= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= +k8s.io/apiextensions-apiserver v0.18.6 h1:vDlk7cyFsDyfwn2rNAO2DbmUbvXy5yT5GE3rrqOzaMo= k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= @@ -1472,6 +1479,7 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E= +sigs.k8s.io/controller-tools v0.4.0 h1:9zIdrc6q9RKke8+DnVPVBVZ+cfF9L0TwM01cxNnklYo= sigs.k8s.io/controller-tools v0.4.0/go.mod h1:G9rHdZMVlBDocIxGkK3jHLWqcTMNvveypYJwrvYKjWU= sigs.k8s.io/service-apis v0.1.0 h1:yImgpgLrxSD5tMdLqpIDEzroFaUzqwZbrg6/H3VpkYM= sigs.k8s.io/service-apis v0.1.0/go.mod h1:QkiV/PnK7YbN5zqYqXnh5wByTTT1LYJ5scwdIs62qWs= diff --git a/integration/fixtures/k8s/01-crd.yml b/integration/fixtures/k8s/01-crd.yml deleted file mode 100644 index 2bf53b37a..000000000 --- a/integration/fixtures/k8s/01-crd.yml +++ /dev/null @@ -1,119 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressroutes.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRoute - plural: ingressroutes - singular: ingressroute - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: middlewares.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: Middleware - plural: middlewares - singular: middleware - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressroutetcps.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRouteTCP - plural: ingressroutetcps - singular: ingressroutetcp - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressrouteudps.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRouteUDP - plural: ingressrouteudps - singular: ingressrouteudp - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: tlsoptions.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: TLSOption - plural: tlsoptions - singular: tlsoption - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: serverstransports.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: ServersTransport - plural: serverstransports - singular: serverstransport - scope: Namespaced - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: tlsstores.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: TLSStore - plural: tlsstores - singular: tlsstore - scope: Namespaced - - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: traefikservices.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: TraefikService - plural: traefikservices - singular: traefikservice - scope: Namespaced diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml new file mode 100644 index 000000000..53b7a921c --- /dev/null +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -0,0 +1,1377 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressroutes.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRoute + listKind: IngressRouteList + plural: ingressroutes + singular: ingressroute + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRoute is an Ingress CRD specification. + 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: + description: IngressRouteSpec is a specification for a IngressRouteSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: Route contains the set of routes. + properties: + kind: + enum: + - Rule + type: string + match: + type: string + middlewares: + items: + description: MiddlewareRef is a ref to the Middleware resources. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: array + priority: + type: integer + services: + items: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + required: + - kind + - match + type: object + type: array + tls: + description: "TLS contains the TLS certificates configuration of the routes. To enable Let's Encrypt, use an empty TLS struct, e.g. in YAML: \n \t tls: {} # inline format \n \t tls: \t secretName: # block format" + properties: + certResolver: + type: string + domains: + items: + description: Domain holds a domain name with SANs. + properties: + main: + type: string + sans: + items: + type: string + type: array + type: object + type: array + options: + description: Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + store: + description: Store is a reference to a TLSStore, that specifies the parameters of the TLS store. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: object + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressroutetcps.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRouteTCP + listKind: IngressRouteTCPList + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRouteTCP is an Ingress CRD specification. + 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: + description: IngressRouteTCPSpec is a specification for a IngressRouteTCPSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: RouteTCP contains the set of routes. + properties: + match: + type: string + services: + items: + description: ServiceTCP defines an upstream to proxy traffic. + properties: + name: + type: string + namespace: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + proxyProtocol: + description: ProxyProtocol holds the ProxyProtocol configuration. + properties: + version: + type: integer + type: object + terminationDelay: + type: integer + weight: + type: integer + required: + - name + - port + type: object + type: array + required: + - match + type: object + type: array + tls: + description: "TLSTCP contains the TLS certificates configuration of the routes. To enable Let's Encrypt, use an empty TLS struct, e.g. in YAML: \n \t tls: {} # inline format \n \t tls: \t secretName: # block format" + properties: + certResolver: + type: string + domains: + items: + description: Domain holds a domain name with SANs. + properties: + main: + type: string + sans: + items: + type: string + type: array + type: object + type: array + options: + description: Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + passthrough: + type: boolean + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + store: + description: Store is a reference to a TLSStore, that specifies the parameters of the TLS store. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: object + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: ingressrouteudps.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: IngressRouteUDP + listKind: IngressRouteUDPList + plural: ingressrouteudps + singular: ingressrouteudp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressRouteUDP is an Ingress CRD specification. + 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: + description: IngressRouteUDPSpec is a specification for a IngressRouteUDPSpec resource. + properties: + entryPoints: + items: + type: string + type: array + routes: + items: + description: RouteUDP contains the set of routes. + properties: + services: + items: + description: ServiceUDP defines an upstream to proxy traffic. + properties: + name: + type: string + namespace: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + weight: + type: integer + required: + - name + - port + type: object + type: array + type: object + type: array + required: + - routes + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: middlewares.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: Middleware + listKind: MiddlewareList + plural: middlewares + singular: middleware + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Middleware is a specification for a Middleware resource. + 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: + description: MiddlewareSpec holds the Middleware configuration. + properties: + addPrefix: + description: AddPrefix holds the AddPrefix configuration. + properties: + prefix: + type: string + type: object + basicAuth: + description: BasicAuth holds the HTTP basic authentication configuration. + properties: + headerField: + type: string + realm: + type: string + removeHeader: + type: boolean + secret: + type: string + type: object + buffering: + description: Buffering holds the request/response buffering configuration. + properties: + maxRequestBodyBytes: + format: int64 + type: integer + maxResponseBodyBytes: + format: int64 + type: integer + memRequestBodyBytes: + format: int64 + type: integer + memResponseBodyBytes: + format: int64 + type: integer + retryExpression: + type: string + type: object + chain: + description: Chain holds a chain of middlewares. + properties: + middlewares: + items: + description: MiddlewareRef is a ref to the Middleware resources. + properties: + name: + type: string + namespace: + type: string + required: + - name + type: object + type: array + type: object + circuitBreaker: + description: CircuitBreaker holds the circuit breaker configuration. + properties: + expression: + type: string + type: object + compress: + description: Compress holds the compress configuration. + properties: + excludedContentTypes: + items: + type: string + type: array + type: object + contentType: + description: ContentType middleware - or rather its unique `autoDetect` option - specifies whether to let the `Content-Type` header, if it has not been set by the backend, be automatically set to a value derived from the contents of the response. As a proxy, the default behavior should be to leave the header alone, regardless of what the backend did with it. However, the historic default was to always auto-detect and set the header if it was nil, and it is going to be kept that way in order to support users currently relying on it. This middleware exists to enable the correct behavior until at least the default one can be changed in a future version. + properties: + autoDetect: + type: boolean + type: object + digestAuth: + description: DigestAuth holds the Digest HTTP authentication configuration. + properties: + headerField: + type: string + realm: + type: string + removeHeader: + type: boolean + secret: + type: string + type: object + errors: + description: ErrorPage holds the custom error page configuration. + properties: + query: + type: string + service: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + status: + items: + type: string + type: array + type: object + forwardAuth: + description: ForwardAuth holds the http forward authentication configuration. + properties: + address: + type: string + authRequestHeaders: + items: + type: string + type: array + authResponseHeaders: + items: + type: string + type: array + authResponseHeadersRegex: + type: string + tls: + description: ClientTLS holds TLS specific configurations as client. + properties: + caOptional: + type: boolean + caSecret: + type: string + certSecret: + type: string + insecureSkipVerify: + type: boolean + type: object + trustForwardHeader: + type: boolean + type: object + headers: + description: Headers holds the custom header configuration. + properties: + accessControlAllowCredentials: + description: AccessControlAllowCredentials is only valid if true. false is ignored. + type: boolean + accessControlAllowHeaders: + description: AccessControlAllowHeaders must be used in response to a preflight request with Access-Control-Request-Headers set. + items: + type: string + type: array + accessControlAllowMethods: + description: AccessControlAllowMethods must be used in response to a preflight request with Access-Control-Request-Method set. + items: + type: string + type: array + accessControlAllowOrigin: + description: AccessControlAllowOrigin Can be "origin-list-or-null" or "*". From (https://www.w3.org/TR/cors/#access-control-allow-origin-response-header) + type: string + accessControlAllowOriginList: + description: AccessControlAllowOriginList is a list of allowable origins. Can also be a wildcard origin "*". + items: + type: string + type: array + accessControlAllowOriginListRegex: + description: AccessControlAllowOriginListRegex is a list of allowable origins written following the Regular Expression syntax (https://golang.org/pkg/regexp/). + items: + type: string + type: array + accessControlExposeHeaders: + description: AccessControlExposeHeaders sets valid headers for the response. + items: + type: string + type: array + accessControlMaxAge: + description: AccessControlMaxAge sets the time that a preflight request may be cached. + format: int64 + type: integer + addVaryHeader: + description: AddVaryHeader controls if the Vary header is automatically added/updated when the AccessControlAllowOrigin is set. + type: boolean + allowedHosts: + items: + type: string + type: array + browserXssFilter: + type: boolean + contentSecurityPolicy: + type: string + contentTypeNosniff: + type: boolean + customBrowserXSSValue: + type: string + customFrameOptionsValue: + type: string + customRequestHeaders: + additionalProperties: + type: string + type: object + customResponseHeaders: + additionalProperties: + type: string + type: object + featurePolicy: + type: string + forceSTSHeader: + type: boolean + frameDeny: + type: boolean + hostsProxyHeaders: + items: + type: string + type: array + isDevelopment: + type: boolean + publicKey: + type: string + referrerPolicy: + type: string + sslForceHost: + type: boolean + sslHost: + type: string + sslProxyHeaders: + additionalProperties: + type: string + type: object + sslRedirect: + type: boolean + sslTemporaryRedirect: + type: boolean + stsIncludeSubdomains: + type: boolean + stsPreload: + type: boolean + stsSeconds: + format: int64 + type: integer + type: object + inFlightReq: + description: InFlightReq limits the number of requests being processed and served concurrently. + properties: + amount: + format: int64 + type: integer + sourceCriterion: + description: SourceCriterion defines what criterion is used to group requests as originating from a common source. If none are set, the default is to use the request's remote address field. All fields are mutually exclusive. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + requestHeaderName: + type: string + requestHost: + type: boolean + type: object + type: object + ipWhiteList: + description: IPWhiteList holds the ip white list configuration. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + sourceRange: + items: + type: string + type: array + type: object + passTLSClientCert: + description: PassTLSClientCert holds the TLS client cert headers configuration. + properties: + info: + description: TLSClientCertificateInfo holds the client TLS certificate info configuration. + properties: + issuer: + description: TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration. cf https://tools.ietf.org/html/rfc3739 + properties: + commonName: + type: boolean + country: + type: boolean + domainComponent: + type: boolean + locality: + type: boolean + organization: + type: boolean + province: + type: boolean + serialNumber: + type: boolean + type: object + notAfter: + type: boolean + notBefore: + type: boolean + sans: + type: boolean + serialNumber: + type: boolean + subject: + description: TLSCLientCertificateDNInfo holds the client TLS certificate distinguished name info configuration. cf https://tools.ietf.org/html/rfc3739 + properties: + commonName: + type: boolean + country: + type: boolean + domainComponent: + type: boolean + locality: + type: boolean + organization: + type: boolean + province: + type: boolean + serialNumber: + type: boolean + type: object + type: object + pem: + type: boolean + type: object + plugin: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + rateLimit: + description: RateLimit holds the rate limiting configuration for a given router. + properties: + average: + format: int64 + type: integer + burst: + format: int64 + type: integer + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + sourceCriterion: + description: SourceCriterion defines what criterion is used to group requests as originating from a common source. If none are set, the default is to use the request's remote address field. All fields are mutually exclusive. + properties: + ipStrategy: + description: IPStrategy holds the ip strategy configuration. + properties: + depth: + type: integer + excludedIPs: + items: + type: string + type: array + type: object + requestHeaderName: + type: string + requestHost: + type: boolean + type: object + type: object + redirectRegex: + description: RedirectRegex holds the redirection configuration. + properties: + permanent: + type: boolean + regex: + type: string + replacement: + type: string + type: object + redirectScheme: + description: RedirectScheme holds the scheme redirection configuration. + properties: + permanent: + type: boolean + port: + type: string + scheme: + type: string + type: object + replacePath: + description: ReplacePath holds the ReplacePath configuration. + properties: + path: + type: string + type: object + replacePathRegex: + description: ReplacePathRegex holds the ReplacePathRegex configuration. + properties: + regex: + type: string + replacement: + type: string + type: object + retry: + description: Retry holds the retry configuration. + properties: + attempts: + type: integer + initialInterval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + stripPrefix: + description: StripPrefix holds the StripPrefix configuration. + properties: + forceSlash: + type: boolean + prefixes: + items: + type: string + type: array + type: object + stripPrefixRegex: + description: StripPrefixRegex holds the StripPrefixRegex configuration. + properties: + regex: + items: + type: string + type: array + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: serverstransports.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: ServersTransport + listKind: ServersTransportList + plural: serverstransports + singular: serverstransport + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ServersTransport is a specification for a ServersTransport resource. + 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: + description: ServersTransportSpec options to configure communication between Traefik and the servers. + properties: + certificatesSecrets: + description: Certificates for mTLS. + items: + type: string + type: array + forwardingTimeouts: + description: Timeouts for requests forwarded to the backend servers. + properties: + dialTimeout: + anyOf: + - type: integer + - type: string + description: The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. + x-kubernetes-int-or-string: true + idleConnTimeout: + anyOf: + - type: integer + - type: string + description: The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself. + x-kubernetes-int-or-string: true + responseHeaderTimeout: + anyOf: + - type: integer + - type: string + description: The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists. + x-kubernetes-int-or-string: true + type: object + insecureSkipVerify: + description: Disable SSL certificate verification. + type: boolean + maxIdleConnsPerHost: + description: If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. + type: integer + rootCAsSecrets: + description: Add cert file for self-signed certificate. + items: + type: string + type: array + serverName: + description: ServerName used to contact the server. + type: string + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: tlsoptions.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TLSOption + listKind: TLSOptionList + plural: tlsoptions + singular: tlsoption + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TLSOption is a specification for a TLSOption resource. + 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: + description: TLSOptionSpec configures TLS for an entry point. + properties: + cipherSuites: + items: + type: string + type: array + clientAuth: + description: ClientAuth defines the parameters of the client authentication part of the TLS connection, if any. + properties: + clientAuthType: + description: ClientAuthType defines the client authentication type to apply. + enum: + - NoClientCert + - RequestClientCert + - VerifyClientCertIfGiven + - RequireAndVerifyClientCert + type: string + secretNames: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + items: + type: string + type: array + type: object + curvePreferences: + items: + type: string + type: array + maxVersion: + type: string + minVersion: + type: string + preferServerCipherSuites: + type: boolean + sniStrict: + type: boolean + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: tlsstores.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TLSStore + listKind: TLSStoreList + plural: tlsstores + singular: tlsstore + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TLSStore is a specification for a TLSStore resource. + 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: + description: TLSStoreSpec configures a TLSStore resource. + properties: + defaultCertificate: + description: DefaultCertificate holds a secret name for the TLSOption resource. + properties: + secretName: + description: SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + type: string + required: + - secretName + type: object + required: + - defaultCertificate + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: traefikservices.traefik.containo.us +spec: + group: traefik.containo.us + names: + kind: TraefikService + listKind: TraefikServiceList + plural: traefikservices + singular: traefikservice + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: TraefikService is the specification for a service (that an IngressRoute refers to) that is usually not a terminal service (i.e. not a pod of servers), as opposed to a Kubernetes Service. That is to say, it usually refers to other (children) services, which themselves can be TraefikServices or Services. + 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: + description: ServiceSpec defines whether a TraefikService is a load-balancer of services or a mirroring service. + properties: + mirroring: + description: Mirroring defines a mirroring service, which is composed of a main load-balancer, and a list of mirrors. + properties: + kind: + enum: + - Service + - TraefikService + type: string + maxBodySize: + format: int64 + type: integer + mirrors: + items: + description: MirrorService defines one of the mirrors of a Mirroring service. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + percent: + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + weighted: + description: WeightedRoundRobin defines a load-balancer of services. + properties: + services: + items: + description: Service defines an upstream to proxy traffic. + properties: + kind: + enum: + - Service + - TraefikService + type: string + name: + description: Name is a reference to a Kubernetes Service object (for a load-balancer of servers), or to a TraefikService object (service load-balancer, mirroring, etc). The differentiation between the two is specified in the Kind field. + type: string + namespace: + type: string + passHostHeader: + type: boolean + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding holds configuration for the forward of the response. + properties: + flushInterval: + type: string + type: object + scheme: + type: string + serversTransport: + type: string + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + strategy: + type: string + weight: + description: Weight should only be specified when Name references a TraefikService object (and to be precise, one that embeds a Weighted Round Robin). + type: integer + required: + - name + type: object + type: array + sticky: + description: Sticky holds the sticky configuration. + properties: + cookie: + description: Cookie holds the sticky configuration based on cookie. + properties: + httpOnly: + type: boolean + name: + type: string + sameSite: + type: string + secure: + type: boolean + type: object + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 4b8417632..086757fe9 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "crypto/sha256" + "encoding/json" "errors" "fmt" "os" @@ -23,6 +24,7 @@ import ( "github.com/traefik/traefik/v2/pkg/safe" "github.com/traefik/traefik/v2/pkg/tls" corev1 "k8s.io/api/core/v1" + apiextensionv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -219,6 +221,24 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) conf.HTTP.Services[serviceName] = errorPageService } + plugin, err := createPluginMiddleware(middleware.Spec.Plugin) + if err != nil { + log.FromContext(ctxMid).Errorf("Error while reading plugins middleware: %v", err) + continue + } + + rateLimit, err := createRateLimitMiddleware(middleware.Spec.RateLimit) + if err != nil { + log.FromContext(ctxMid).Errorf("Error while reading rateLimit middleware: %v", err) + continue + } + + retry, err := createRetryMiddleware(middleware.Spec.Retry) + if err != nil { + log.FromContext(ctxMid).Errorf("Error while reading retry middleware: %v", err) + continue + } + conf.HTTP.Middlewares[id] = &dynamic.Middleware{ AddPrefix: middleware.Spec.AddPrefix, StripPrefix: middleware.Spec.StripPrefix, @@ -229,7 +249,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) IPWhiteList: middleware.Spec.IPWhiteList, Headers: middleware.Spec.Headers, Errors: errorPage, - RateLimit: middleware.Spec.RateLimit, + RateLimit: rateLimit, RedirectRegex: middleware.Spec.RedirectRegex, RedirectScheme: middleware.Spec.RedirectScheme, BasicAuth: basicAuth, @@ -240,9 +260,9 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) CircuitBreaker: middleware.Spec.CircuitBreaker, Compress: middleware.Spec.Compress, PassTLSClientCert: middleware.Spec.PassTLSClientCert, - Retry: middleware.Spec.Retry, + Retry: retry, ContentType: middleware.Spec.ContentType, - Plugin: middleware.Spec.Plugin, + Plugin: plugin, } } @@ -356,6 +376,62 @@ func getServicePort(svc *corev1.Service, port intstr.IntOrString) (*corev1.Servi return &corev1.ServicePort{Port: port.IntVal}, nil } +func createPluginMiddleware(plugins map[string]apiextensionv1.JSON) (map[string]dynamic.PluginConf, error) { + if plugins == nil { + return nil, nil + } + + data, err := json.Marshal(plugins) + if err != nil { + return nil, err + } + + pc := map[string]dynamic.PluginConf{} + err = json.Unmarshal(data, &pc) + if err != nil { + return nil, err + } + + return pc, nil +} + +func createRateLimitMiddleware(rateLimit *v1alpha1.RateLimit) (*dynamic.RateLimit, error) { + if rateLimit == nil { + return nil, nil + } + + rl := &dynamic.RateLimit{Average: rateLimit.Average} + rl.SetDefaults() + + if rateLimit.Burst != nil { + rl.Burst = *rateLimit.Burst + } + + if rateLimit.Period != nil { + err := rl.Period.Set(rateLimit.Period.String()) + if err != nil { + return nil, err + } + } + + return rl, nil +} + +func createRetryMiddleware(retry *v1alpha1.Retry) (*dynamic.Retry, error) { + if retry == nil { + return nil, nil + } + + r := &dynamic.Retry{Attempts: retry.Attempts} + + err := r.InitialInterval.Set(retry.InitialInterval.String()) + if err != nil { + return nil, err + } + + return r, nil +} + func (p *Provider) createErrorPageMiddleware(client Client, namespace string, errorPage *v1alpha1.ErrorPage) (*dynamic.ErrorPage, *dynamic.Service, error) { if errorPage == nil { return nil, nil, nil diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go index b48bd747b..0de26e8fa 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go @@ -10,17 +10,18 @@ import ( // IngressRouteSpec is a specification for a IngressRouteSpec resource. type IngressRouteSpec struct { Routes []Route `json:"routes"` - EntryPoints []string `json:"entryPoints"` + EntryPoints []string `json:"entryPoints,omitempty"` TLS *TLS `json:"tls,omitempty"` } // Route contains the set of routes. type Route struct { - Match string `json:"match"` + Match string `json:"match"` + // +kubebuilder:validation:Enum=Rule Kind string `json:"kind"` - Priority int `json:"priority"` + Priority int `json:"priority,omitempty"` Services []Service `json:"services,omitempty"` - Middlewares []MiddlewareRef `json:"middlewares"` + Middlewares []MiddlewareRef `json:"middlewares,omitempty"` } // TLS contains the TLS certificates configuration of the routes. @@ -34,7 +35,7 @@ type Route struct { type TLS struct { // SecretName is the name of the referenced Kubernetes Secret to specify the // certificate details. - SecretName string `json:"secretName"` + SecretName string `json:"secretName,omitempty"` // Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. Options *TLSOptionRef `json:"options,omitempty"` // Store is a reference to a TLSStore, that specifies the parameters of the TLS store. @@ -46,13 +47,13 @@ type TLS struct { // TLSOptionRef is a ref to the TLSOption resources. type TLSOptionRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // TLSStoreRef is a ref to the TLSStore resource. type TLSStoreRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // LoadBalancerSpec can reference either a Kubernetes Service object (a load-balancer of servers), @@ -61,14 +62,16 @@ type LoadBalancerSpec struct { // Name is a reference to a Kubernetes Service object (for a load-balancer of servers), // or to a TraefikService object (service load-balancer, mirroring, etc). // The differentiation between the two is specified in the Kind field. - Name string `json:"name"` - Kind string `json:"kind"` - Namespace string `json:"namespace"` + Name string `json:"name"` + // +kubebuilder:validation:Enum=Service;TraefikService + Kind string `json:"kind,omitempty"` + Namespace string `json:"namespace,omitempty"` Sticky *dynamic.Sticky `json:"sticky,omitempty"` // Port and all the fields below are related to a servers load-balancer, // and therefore should only be specified when Name references a Kubernetes Service. - Port intstr.IntOrString `json:"port"` + + Port intstr.IntOrString `json:"port,omitempty"` Scheme string `json:"scheme,omitempty"` Strategy string `json:"strategy,omitempty"` PassHostHeader *bool `json:"passHostHeader,omitempty"` @@ -82,17 +85,18 @@ type LoadBalancerSpec struct { // Service defines an upstream to proxy traffic. type Service struct { - LoadBalancerSpec + LoadBalancerSpec `json:",inline"` } // MiddlewareRef is a ref to the Middleware resources. type MiddlewareRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // IngressRoute is an Ingress CRD specification. type IngressRoute struct { diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go index 5c11256fd..a508328e7 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go @@ -10,7 +10,7 @@ import ( // IngressRouteTCPSpec is a specification for a IngressRouteTCPSpec resource. type IngressRouteTCPSpec struct { Routes []RouteTCP `json:"routes"` - EntryPoints []string `json:"entryPoints"` + EntryPoints []string `json:"entryPoints,omitempty"` TLS *TLSTCP `json:"tls,omitempty"` } @@ -31,32 +31,32 @@ type RouteTCP struct { type TLSTCP struct { // SecretName is the name of the referenced Kubernetes Secret to specify the // certificate details. - SecretName string `json:"secretName"` - Passthrough bool `json:"passthrough"` + SecretName string `json:"secretName,omitempty"` + Passthrough bool `json:"passthrough,omitempty"` // Options is a reference to a TLSOption, that specifies the parameters of the TLS connection. - Options *TLSOptionTCPRef `json:"options"` + Options *TLSOptionTCPRef `json:"options,omitempty"` // Store is a reference to a TLSStore, that specifies the parameters of the TLS store. - Store *TLSStoreTCPRef `json:"store"` - CertResolver string `json:"certResolver"` + Store *TLSStoreTCPRef `json:"store,omitempty"` + CertResolver string `json:"certResolver,omitempty"` Domains []types.Domain `json:"domains,omitempty"` } // TLSOptionTCPRef is a ref to the TLSOption resources. type TLSOptionTCPRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // TLSStoreTCPRef is a ref to the TLSStore resources. type TLSStoreTCPRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // ServiceTCP defines an upstream to proxy traffic. type ServiceTCP struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` Port intstr.IntOrString `json:"port"` Weight *int `json:"weight,omitempty"` TerminationDelay *int `json:"terminationDelay,omitempty"` @@ -65,6 +65,7 @@ type ServiceTCP struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // IngressRouteTCP is an Ingress CRD specification. type IngressRouteTCP struct { diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go index be6140e13..eb44cd64f 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go @@ -8,7 +8,7 @@ import ( // IngressRouteUDPSpec is a specification for a IngressRouteUDPSpec resource. type IngressRouteUDPSpec struct { Routes []RouteUDP `json:"routes"` - EntryPoints []string `json:"entryPoints"` + EntryPoints []string `json:"entryPoints,omitempty"` } // RouteUDP contains the set of routes. @@ -19,19 +19,20 @@ type RouteUDP struct { // TLSOptionUDPRef is a ref to the TLSOption resources. type TLSOptionUDPRef struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` } // ServiceUDP defines an upstream to proxy traffic. type ServiceUDP struct { Name string `json:"name"` - Namespace string `json:"namespace"` + Namespace string `json:"namespace,omitempty"` Port intstr.IntOrString `json:"port"` Weight *int `json:"weight,omitempty"` } // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // IngressRouteUDP is an Ingress CRD specification. type IngressRouteUDP struct { diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go index 07e96611f..2fff164a5 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go @@ -2,11 +2,14 @@ package v1alpha1 import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" + apiextensionv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // Middleware is a specification for a Middleware resource. type Middleware struct { @@ -20,29 +23,29 @@ type Middleware struct { // MiddlewareSpec holds the Middleware configuration. type MiddlewareSpec struct { - AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty"` - StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty"` - StripPrefixRegex *dynamic.StripPrefixRegex `json:"stripPrefixRegex,omitempty"` - ReplacePath *dynamic.ReplacePath `json:"replacePath,omitempty"` - ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"` - Chain *Chain `json:"chain,omitempty"` - IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"` - Headers *dynamic.Headers `json:"headers,omitempty"` - Errors *ErrorPage `json:"errors,omitempty"` - RateLimit *dynamic.RateLimit `json:"rateLimit,omitempty"` - RedirectRegex *dynamic.RedirectRegex `json:"redirectRegex,omitempty"` - RedirectScheme *dynamic.RedirectScheme `json:"redirectScheme,omitempty"` - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - DigestAuth *DigestAuth `json:"digestAuth,omitempty"` - ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` - InFlightReq *dynamic.InFlightReq `json:"inFlightReq,omitempty"` - Buffering *dynamic.Buffering `json:"buffering,omitempty"` - CircuitBreaker *dynamic.CircuitBreaker `json:"circuitBreaker,omitempty"` - Compress *dynamic.Compress `json:"compress,omitempty"` - PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"` - Retry *dynamic.Retry `json:"retry,omitempty"` - ContentType *dynamic.ContentType `json:"contentType,omitempty"` - Plugin map[string]dynamic.PluginConf `json:"plugin,omitempty"` + AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty"` + StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty"` + StripPrefixRegex *dynamic.StripPrefixRegex `json:"stripPrefixRegex,omitempty"` + ReplacePath *dynamic.ReplacePath `json:"replacePath,omitempty"` + ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"` + Chain *Chain `json:"chain,omitempty"` + IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"` + Headers *dynamic.Headers `json:"headers,omitempty"` + Errors *ErrorPage `json:"errors,omitempty"` + RateLimit *RateLimit `json:"rateLimit,omitempty"` + RedirectRegex *dynamic.RedirectRegex `json:"redirectRegex,omitempty"` + RedirectScheme *dynamic.RedirectScheme `json:"redirectScheme,omitempty"` + BasicAuth *BasicAuth `json:"basicAuth,omitempty"` + DigestAuth *DigestAuth `json:"digestAuth,omitempty"` + ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` + InFlightReq *dynamic.InFlightReq `json:"inFlightReq,omitempty"` + Buffering *dynamic.Buffering `json:"buffering,omitempty"` + CircuitBreaker *dynamic.CircuitBreaker `json:"circuitBreaker,omitempty"` + Compress *dynamic.Compress `json:"compress,omitempty"` + PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"` + Retry *Retry `json:"retry,omitempty"` + ContentType *dynamic.ContentType `json:"contentType,omitempty"` + Plugin map[string]apiextensionv1.JSON `json:"plugin,omitempty"` } // +k8s:deepcopy-gen=true @@ -110,3 +113,21 @@ type MiddlewareList struct { Items []Middleware `json:"items"` } + +// +k8s:deepcopy-gen=true + +// RateLimit holds the rate limiting configuration for a given router. +type RateLimit struct { + Average int64 `json:"average,omitempty"` + Period *intstr.IntOrString `json:"period,omitempty"` + Burst *int64 `json:"burst,omitempty"` + SourceCriterion *dynamic.SourceCriterion `json:"sourceCriterion,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// Retry holds the retry configuration. +type Retry struct { + Attempts int `json:"attempts,omitempty"` + InitialInterval intstr.IntOrString `json:"initialInterval,omitempty"` +} diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go index 37f211ff1..130598214 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go @@ -7,6 +7,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // ServersTransport is a specification for a ServersTransport resource. type ServersTransport struct { @@ -20,21 +21,31 @@ type ServersTransport struct { // ServersTransportSpec options to configure communication between Traefik and the servers. type ServersTransportSpec struct { - ServerName string `description:"ServerName used to contact the server" json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty" export:"true"` - InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` - RootCAsSecrets []string `description:"Add cert file for self-signed certificate." json:"rootCAsSecrets,omitempty" toml:"rootCAsSecrets,omitempty" yaml:"rootCAsSecrets,omitempty"` - CertificatesSecrets []string `description:"Certificates for mTLS." json:"certificatesSecrets,omitempty" toml:"certificatesSecrets,omitempty" yaml:"certificatesSecrets,omitempty"` - MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"` - ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"` + // ServerName used to contact the server. + ServerName string `json:"serverName,omitempty"` + // Disable SSL certificate verification. + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + // Add cert file for self-signed certificate. + RootCAsSecrets []string `json:"rootCAsSecrets,omitempty"` + // Certificates for mTLS. + CertificatesSecrets []string `json:"certificatesSecrets,omitempty"` + // If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. + MaxIdleConnsPerHost int `json:"maxIdleConnsPerHost,omitempty"` + // Timeouts for requests forwarded to the backend servers. + ForwardingTimeouts *ForwardingTimeouts `json:"forwardingTimeouts,omitempty"` } // +k8s:deepcopy-gen=true // ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers. type ForwardingTimeouts struct { - DialTimeout *intstr.IntOrString `description:"The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"` - ResponseHeaderTimeout *intstr.IntOrString `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` - IdleConnTimeout *intstr.IntOrString `description:"The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself" json:"idleConnTimeout,omitempty" toml:"idleConnTimeout,omitempty" yaml:"idleConnTimeout,omitempty" export:"true"` + // The amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. + DialTimeout *intstr.IntOrString `json:"dialTimeout,omitempty"` + // The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). + // If zero, no timeout exists. + ResponseHeaderTimeout *intstr.IntOrString `json:"responseHeaderTimeout,omitempty"` + // The maximum period for which an idle HTTP keep-alive connection will remain open before closing itself. + IdleConnTimeout *intstr.IntOrString `json:"idleConnTimeout,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go index 2e01f8506..fa70a253b 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go @@ -7,6 +7,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // TraefikService is the specification for a service (that an IngressRoute refers // to) that is usually not a terminal service (i.e. not a pod of servers), as @@ -43,8 +44,9 @@ type ServiceSpec struct { // Mirroring defines a mirroring service, which is composed of a main // load-balancer, and a list of mirrors. type Mirroring struct { - LoadBalancerSpec - MaxBodySize *int64 + LoadBalancerSpec `json:",inline"` + + MaxBodySize *int64 `json:"maxBodySize,omitempty"` Mirrors []MirrorService `json:"mirrors,omitempty"` } @@ -52,7 +54,8 @@ type Mirroring struct { // MirrorService defines one of the mirrors of a Mirroring service. type MirrorService struct { - LoadBalancerSpec + LoadBalancerSpec `json:",inline"` + Percent int `json:"percent,omitempty"` } diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go index 6c6b67ad8..52eb84a48 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go @@ -6,6 +6,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // TLSOption is a specification for a TLSOption resource. type TLSOption struct { @@ -32,12 +33,11 @@ type TLSOptionSpec struct { // ClientAuth defines the parameters of the client authentication part of the TLS connection, if any. type ClientAuth struct { - // SecretName is the name of the referenced Kubernetes Secret to specify the - // certificate details. - SecretNames []string `json:"secretNames"` + // SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + SecretNames []string `json:"secretNames,omitempty"` + // +kubebuilder:validation:Enum=NoClientCert;RequestClientCert;VerifyClientCertIfGiven;RequireAndVerifyClientCert // ClientAuthType defines the client authentication type to apply. - // The available values are: "NoClientCert", "RequestClientCert", "VerifyClientCertIfGiven" and "RequireAndVerifyClientCert". - ClientAuthType string `json:"clientAuthType"` + ClientAuthType string `json:"clientAuthType,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go index 25dee994a..404f07f96 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go @@ -6,6 +6,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion // TLSStore is a specification for a TLSStore resource. type TLSStore struct { @@ -26,9 +27,8 @@ type TLSStoreSpec struct { // DefaultCertificate holds a secret name for the TLSOption resource. type DefaultCertificate struct { - // SecretName is the name of the referenced Kubernetes Secret to specify the - // certificate details. - SecretName string `json:"secretName,omitempty"` + // SecretName is the name of the referenced Kubernetes Secret to specify the certificate details. + SecretName string `json:"secretName"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go index 2e6856095..eb264ce72 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go @@ -31,6 +31,7 @@ package v1alpha1 import ( dynamic "github.com/traefik/traefik/v2/pkg/config/dynamic" types "github.com/traefik/traefik/v2/pkg/types" + v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtime "k8s.io/apimachinery/pkg/runtime" intstr "k8s.io/apimachinery/pkg/util/intstr" ) @@ -662,7 +663,7 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) { } if in.RateLimit != nil { in, out := &in.RateLimit, &out.RateLimit - *out = new(dynamic.RateLimit) + *out = new(RateLimit) (*in).DeepCopyInto(*out) } if in.RedirectRegex != nil { @@ -717,7 +718,7 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) { } if in.Retry != nil { in, out := &in.Retry, &out.Retry - *out = new(dynamic.Retry) + *out = new(Retry) **out = **in } if in.ContentType != nil { @@ -727,7 +728,7 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) { } if in.Plugin != nil { in, out := &in.Plugin, &out.Plugin - *out = make(map[string]dynamic.PluginConf, len(*in)) + *out = make(map[string]v1.JSON, len(*in)) for key, val := range *in { (*out)[key] = *val.DeepCopy() } @@ -791,6 +792,54 @@ func (in *Mirroring) DeepCopy() *Mirroring { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimit) DeepCopyInto(out *RateLimit) { + *out = *in + if in.Period != nil { + in, out := &in.Period, &out.Period + *out = new(intstr.IntOrString) + **out = **in + } + if in.Burst != nil { + in, out := &in.Burst, &out.Burst + *out = new(int64) + **out = **in + } + if in.SourceCriterion != nil { + in, out := &in.SourceCriterion, &out.SourceCriterion + *out = new(dynamic.SourceCriterion) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimit. +func (in *RateLimit) DeepCopy() *RateLimit { + if in == nil { + return nil + } + out := new(RateLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Retry) DeepCopyInto(out *Retry) { + *out = *in + out.InitialInterval = in.InitialInterval + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Retry. +func (in *Retry) DeepCopy() *Retry { + if in == nil { + return nil + } + out := new(Retry) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Route) DeepCopyInto(out *Route) { *out = *in diff --git a/script/update-generated-crd-code.sh b/script/update-generated-crd-code.sh index 78b70420c..a58af5fe7 100755 --- a/script/update-generated-crd-code.sh +++ b/script/update-generated-crd-code.sh @@ -9,6 +9,7 @@ rm -rf "${REPO_ROOT}"/vendor go mod vendor chmod +x "${REPO_ROOT}"/vendor/k8s.io/code-generator/*.sh +# Generate the crd client "${REPO_ROOT}"/vendor/k8s.io/code-generator/generate-groups.sh \ all \ github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/provider/kubernetes/crd/generated \ @@ -18,12 +19,21 @@ chmod +x "${REPO_ROOT}"/vendor/k8s.io/code-generator/*.sh "$@" deepcopy-gen \ ---input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/config/dynamic \ ---input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/tls \ ---input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/types \ ---output-package github.com/traefik/traefik \ --O zz_generated.deepcopy --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl + --input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/config/dynamic \ + --input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/tls \ + --input-dirs github.com/traefik/traefik/${TRAEFIK_MODULE_VERSION}/pkg/types \ + --output-package github.com/traefik/traefik \ + -O zz_generated.deepcopy --go-header-file "${HACK_DIR}"/boilerplate.go.tmpl cp -r "${REPO_ROOT}"/"${TRAEFIK_MODULE_VERSION:?}"/* "${REPO_ROOT}"; rm -rf "${REPO_ROOT}"/"${TRAEFIK_MODULE_VERSION:?}" +# Generate the CRD definitions for the documentation +go run "${REPO_ROOT}"/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen \ + crd:crdVersions=v1 \ + paths="${REPO_ROOT}"/pkg/provider/kubernetes/crd/traefik/v1alpha1/... \ + output:dir="${REPO_ROOT}"/docs/content/reference/dynamic-configuration/ + +# Concatenate the CRD definitions for the integration tests +cat "${REPO_ROOT}"/docs/content/reference/dynamic-configuration/traefik.containo.us_*.yaml > "${REPO_ROOT}"/integration/fixtures/k8s/01-traefik-crd.yml + rm -rf "${REPO_ROOT}"/vendor diff --git a/tools.go b/tools.go index 1185af9e3..cb6b3341b 100644 --- a/tools.go +++ b/tools.go @@ -4,4 +4,5 @@ package main import ( _ "k8s.io/code-generator" + _ "sigs.k8s.io/controller-tools/cmd/controller-gen" )