diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index 9819b8aad2..627de3689c 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -480,12 +480,78 @@ spec: required: - routes type: object + status: + description: IngressRouteStatus defines the observed state of IngressRoute. + properties: + conditions: + description: Conditions lists the conditions of the IngressRoute. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -743,12 +809,78 @@ spec: required: - routes type: object + status: + description: IngressRouteTCPStatus defines the observed state of IngressRouteTCP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -859,12 +991,78 @@ spec: required: - routes type: object + status: + description: IngressRouteUDPStatus defines the observed state of IngressRouteUDP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteUDP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2273,12 +2471,78 @@ spec: type: array type: object type: object + status: + description: MiddlewareStatus defines the observed state of Middleware. + properties: + conditions: + description: Conditions lists the conditions of the Middleware. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2362,12 +2626,78 @@ spec: type: array type: object type: object + status: + description: MiddlewareTCPStatus defines the observed state of MiddlewareTCP. + properties: + conditions: + description: Conditions lists the conditions of the MiddlewareTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2546,12 +2876,78 @@ spec: type: string type: object type: object + status: + description: ServersTransportStatus defines the observed state of ServersTransport. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransport. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2703,12 +3099,78 @@ spec: type: object type: object type: object + status: + description: ServersTransportTCPStatus defines the observed state of ServersTransportTCP. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransportTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2822,12 +3284,78 @@ spec: from clients connections that do not specify a server_name extension. type: boolean type: object + status: + description: TLSOptionStatus defines the observed state of TLSOption. + properties: + conditions: + description: Conditions lists the conditions of the TLSOption. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2919,12 +3447,78 @@ spec: type: string type: object type: object + status: + description: TLSStoreStatus defines the observed state of TLSStore. + properties: + conditions: + description: Conditions lists the conditions of the TLSStore. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -4585,9 +5179,75 @@ spec: type: object type: object type: object + status: + description: TraefikServiceStatus defines the observed state of TraefikService. + properties: + conditions: + description: Conditions lists the conditions of the TraefikService. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml index eb3f708bf5..d5da319d13 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml @@ -64,6 +64,21 @@ rules: - get - list - watch + - apiGroups: + - traefik.io + resources: + - middlewares/status + - middlewaretcps/status + - ingressroutes/status + - traefikservices/status + - ingressroutetcps/status + - ingressrouteudps/status + - tlsoptions/status + - tlsstores/status + - serverstransports/status + - serverstransporttcps/status + verbs: + - update --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml index bd374a3a88..cf29823e0a 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml @@ -481,9 +481,75 @@ spec: required: - routes type: object + status: + description: IngressRouteStatus defines the observed state of IngressRoute. + properties: + conditions: + description: Conditions lists the conditions of the IngressRoute. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml index 10f60e88f0..066f7e0867 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml @@ -255,9 +255,75 @@ spec: required: - routes type: object + status: + description: IngressRouteTCPStatus defines the observed state of IngressRouteTCP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml index 62b8255adc..4f42156461 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml @@ -108,9 +108,75 @@ spec: required: - routes type: object + status: + description: IngressRouteUDPStatus defines the observed state of IngressRouteUDP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteUDP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml index 85b9d35258..5cc6b7ea29 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml @@ -1406,9 +1406,75 @@ spec: type: array type: object type: object + status: + description: MiddlewareStatus defines the observed state of Middleware. + properties: + conditions: + description: Conditions lists the conditions of the Middleware. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml index 92b9003c2f..5b9346aeeb 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml @@ -81,9 +81,75 @@ spec: type: array type: object type: object + status: + description: MiddlewareTCPStatus defines the observed state of MiddlewareTCP. + properties: + conditions: + description: Conditions lists the conditions of the MiddlewareTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml b/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml index 27808e27a9..9aa7044c58 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml @@ -176,9 +176,75 @@ spec: type: string type: object type: object + status: + description: ServersTransportStatus defines the observed state of ServersTransport. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransport. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml index 1f57374ede..58d6343cf1 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml @@ -149,9 +149,75 @@ spec: type: object type: object type: object + status: + description: ServersTransportTCPStatus defines the observed state of ServersTransportTCP. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransportTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml index 66886bfb6a..8b63e23219 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml @@ -111,9 +111,75 @@ spec: from clients connections that do not specify a server_name extension. type: boolean type: object + status: + description: TLSOptionStatus defines the observed state of TLSOption. + properties: + conditions: + description: Conditions lists the conditions of the TLSOption. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml index 8b8d74cfc1..9836d3ac5a 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml @@ -89,9 +89,75 @@ spec: type: string type: object type: object + status: + description: TLSStoreStatus defines the observed state of TLSStore. + properties: + conditions: + description: Conditions lists the conditions of the TLSStore. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml index 1444b6040e..6b2119c534 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml @@ -1658,9 +1658,75 @@ spec: type: object type: object type: object + status: + description: TraefikServiceStatus defines the observed state of TraefikService. + properties: + conditions: + description: Conditions lists the conditions of the TraefikService. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index b5f614949a..781eeafddc 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -481,12 +481,78 @@ spec: required: - routes type: object + status: + description: IngressRouteStatus defines the observed state of IngressRoute. + properties: + conditions: + description: Conditions lists the conditions of the IngressRoute. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -744,12 +810,78 @@ spec: required: - routes type: object + status: + description: IngressRouteTCPStatus defines the observed state of IngressRouteTCP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -860,12 +992,78 @@ spec: required: - routes type: object + status: + description: IngressRouteUDPStatus defines the observed state of IngressRouteUDP. + properties: + conditions: + description: Conditions lists the conditions of the IngressRouteUDP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2274,12 +2472,78 @@ spec: type: array type: object type: object + status: + description: MiddlewareStatus defines the observed state of Middleware. + properties: + conditions: + description: Conditions lists the conditions of the Middleware. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2363,12 +2627,78 @@ spec: type: array type: object type: object + status: + description: MiddlewareTCPStatus defines the observed state of MiddlewareTCP. + properties: + conditions: + description: Conditions lists the conditions of the MiddlewareTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2547,12 +2877,78 @@ spec: type: string type: object type: object + status: + description: ServersTransportStatus defines the observed state of ServersTransport. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransport. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2704,12 +3100,78 @@ spec: type: object type: object type: object + status: + description: ServersTransportTCPStatus defines the observed state of ServersTransportTCP. + properties: + conditions: + description: Conditions lists the conditions of the ServersTransportTCP. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2823,12 +3285,78 @@ spec: from clients connections that do not specify a server_name extension. type: boolean type: object + status: + description: TLSOptionStatus defines the observed state of TLSOption. + properties: + conditions: + description: Conditions lists the conditions of the TLSOption. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2920,12 +3448,78 @@ spec: type: string type: object type: object + status: + description: TLSStoreStatus defines the observed state of TLSStore. + properties: + conditions: + description: Conditions lists the conditions of the TLSStore. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -4586,9 +5180,75 @@ spec: type: object type: object type: object + status: + description: TraefikServiceStatus defines the observed state of TraefikService. + properties: + conditions: + description: Conditions lists the conditions of the TraefikService. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object required: - metadata - spec type: object served: true storage: true + subresources: + status: {} diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 19896b7273..e8237260fc 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -1,6 +1,7 @@ package crd import ( + "context" "errors" "fmt" "os" @@ -26,6 +27,7 @@ import ( kclientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/retry" ) const resyncPeriod = 10 * time.Minute @@ -51,6 +53,16 @@ type Client interface { GetEndpointSlicesForService(namespace, serviceName string) ([]*discoveryv1.EndpointSlice, error) GetNodes() ([]*corev1.Node, bool, error) GetConfigMap(namespace, name string) (*corev1.ConfigMap, bool, error) + UpdateIngressRouteStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateIngressRouteTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateIngressRouteUDPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateMiddlewareStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateMiddlewareTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateServersTransportStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateServersTransportTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateTLSOptionStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateTLSStoreStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error + UpdateTraefikServiceStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error } // TODO: add tests for the clientWrapper (and its methods) itself. @@ -500,6 +512,286 @@ func (c *clientWrapper) GetNodes() ([]*corev1.Node, bool, error) { return nodes, exist, err } +func (c *clientWrapper) UpdateIngressRouteStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update IngressRoute status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().IngressRoutes().Lister().IngressRoutes(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().IngressRoutes(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update IngressRoute %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateIngressRouteTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update IngressRouteTCP status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().IngressRouteTCPs().Lister().IngressRouteTCPs(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().IngressRouteTCPs(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update IngressRouteTCP %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateIngressRouteUDPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update IngressRouteUDP status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().IngressRouteUDPs().Lister().IngressRouteUDPs(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().IngressRouteUDPs(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update IngressRouteUDP %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateMiddlewareStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update Middleware status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().Middlewares().Lister().Middlewares(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().Middlewares(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update Middleware %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateMiddlewareTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update MiddlewareTCP status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().MiddlewareTCPs().Lister().MiddlewareTCPs(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().MiddlewareTCPs(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update MiddlewareTCP %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateServersTransportStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update ServersTransport status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().ServersTransports().Lister().ServersTransports(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().ServersTransports(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update ServersTransport %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateServersTransportTCPStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update ServersTransportTCP status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().ServersTransportTCPs().Lister().ServersTransportTCPs(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().ServersTransportTCPs(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update ServersTransportTCP %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateTLSOptionStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update TLSOption status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().TLSOptions().Lister().TLSOptions(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().TLSOptions(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update TLSOption %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateTLSStoreStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update TLSStore status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().TLSStores().Lister().TLSStores(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().TLSStores(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update TLSStore %s/%s status: %w", namespace, name, err) + } + + return nil +} + +func (c *clientWrapper) UpdateTraefikServiceStatus(ctx context.Context, namespace, name string, conditions []metav1.Condition) error { + if !c.isWatchedNamespace(namespace) { + return fmt.Errorf("cannot update TraefikService status %s/%s: namespace is not within watched namespaces", namespace, name) + } + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + current, err := c.factoriesCrd[c.lookupNamespace(namespace)].Traefik().V1alpha1().TraefikServices().Lister().TraefikServices(namespace).Get(name) + if err != nil { + return err + } + + if conditionsEqual(current.Status.Conditions, conditions) { + return nil + } + + current = current.DeepCopy() + current.Status.Conditions = conditions + + _, err = c.csCrd.TraefikV1alpha1().TraefikServices(namespace).UpdateStatus(ctx, current, metav1.UpdateOptions{}) + return err + }) + if err != nil { + return fmt.Errorf("failed to update TraefikService %s/%s status: %w", namespace, name, err) + } + + return nil +} + // lookupNamespace returns the lookup namespace key for the given namespace. // When listening on all namespaces, it returns the client-go identifier ("") // for all-namespaces. Otherwise, it returns the given namespace. @@ -523,6 +815,16 @@ func (c *clientWrapper) isWatchedNamespace(ns string) bool { return slices.Contains(c.watchedNamespaces, ns) } +func conditionsEqual(a, b []metav1.Condition) bool { + return slices.EqualFunc(a, b, func(cA, cB metav1.Condition) bool { + return cA.Type == cB.Type && + cA.Reason == cB.Reason && + cA.Status == cB.Status && + cA.Message == cB.Message && + cA.ObservedGeneration == cB.ObservedGeneration + }) +} + // translateNotFoundError will translate a "not found" error to a boolean return // value which indicates if the resource exists and a nil error. func translateNotFoundError(err error) (bool, error) { diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroute.go index 77f937d970..bc3717ce20 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroute.go @@ -41,7 +41,8 @@ type IngressRouteApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *IngressRouteSpecApplyConfiguration `json:"spec,omitempty"` + Spec *IngressRouteSpecApplyConfiguration `json:"spec,omitempty"` + Status *IngressRouteStatusApplyConfiguration `json:"status,omitempty"` } // IngressRoute constructs a declarative configuration of the IngressRoute type for use with @@ -223,6 +224,14 @@ func (b *IngressRouteApplyConfiguration) WithSpec(value *IngressRouteSpecApplyCo return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *IngressRouteApplyConfiguration) WithStatus(value *IngressRouteStatusApplyConfiguration) *IngressRouteApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *IngressRouteApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutestatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutestatus.go new file mode 100644 index 0000000000..4063ceb97f --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutestatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// IngressRouteStatusApplyConfiguration represents a declarative configuration of the IngressRouteStatus type for use +// with apply. +// +// IngressRouteStatus defines the observed state of IngressRoute. +type IngressRouteStatusApplyConfiguration struct { + // Conditions lists the conditions of the IngressRoute. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// IngressRouteStatusApplyConfiguration constructs a declarative configuration of the IngressRouteStatus type for use with +// apply. +func IngressRouteStatus() *IngressRouteStatusApplyConfiguration { + return &IngressRouteStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *IngressRouteStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *IngressRouteStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcp.go index 741383cccc..5f88ed87eb 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcp.go @@ -41,7 +41,8 @@ type IngressRouteTCPApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *IngressRouteTCPSpecApplyConfiguration `json:"spec,omitempty"` + Spec *IngressRouteTCPSpecApplyConfiguration `json:"spec,omitempty"` + Status *IngressRouteTCPStatusApplyConfiguration `json:"status,omitempty"` } // IngressRouteTCP constructs a declarative configuration of the IngressRouteTCP type for use with @@ -223,6 +224,14 @@ func (b *IngressRouteTCPApplyConfiguration) WithSpec(value *IngressRouteTCPSpecA return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *IngressRouteTCPApplyConfiguration) WithStatus(value *IngressRouteTCPStatusApplyConfiguration) *IngressRouteTCPApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *IngressRouteTCPApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcpstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcpstatus.go new file mode 100644 index 0000000000..376beecccd --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressroutetcpstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// IngressRouteTCPStatusApplyConfiguration represents a declarative configuration of the IngressRouteTCPStatus type for use +// with apply. +// +// IngressRouteTCPStatus defines the observed state of IngressRouteTCP. +type IngressRouteTCPStatusApplyConfiguration struct { + // Conditions lists the conditions of the IngressRouteTCP. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// IngressRouteTCPStatusApplyConfiguration constructs a declarative configuration of the IngressRouteTCPStatus type for use with +// apply. +func IngressRouteTCPStatus() *IngressRouteTCPStatusApplyConfiguration { + return &IngressRouteTCPStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *IngressRouteTCPStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *IngressRouteTCPStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudp.go index cd94067cb4..8ca90064c1 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudp.go @@ -41,7 +41,8 @@ type IngressRouteUDPApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *IngressRouteUDPSpecApplyConfiguration `json:"spec,omitempty"` + Spec *IngressRouteUDPSpecApplyConfiguration `json:"spec,omitempty"` + Status *IngressRouteUDPStatusApplyConfiguration `json:"status,omitempty"` } // IngressRouteUDP constructs a declarative configuration of the IngressRouteUDP type for use with @@ -223,6 +224,14 @@ func (b *IngressRouteUDPApplyConfiguration) WithSpec(value *IngressRouteUDPSpecA return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *IngressRouteUDPApplyConfiguration) WithStatus(value *IngressRouteUDPStatusApplyConfiguration) *IngressRouteUDPApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *IngressRouteUDPApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudpstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudpstatus.go new file mode 100644 index 0000000000..7c1fcdf69a --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/ingressrouteudpstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// IngressRouteUDPStatusApplyConfiguration represents a declarative configuration of the IngressRouteUDPStatus type for use +// with apply. +// +// IngressRouteUDPStatus defines the observed state of IngressRouteUDP. +type IngressRouteUDPStatusApplyConfiguration struct { + // Conditions lists the conditions of the IngressRouteUDP. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// IngressRouteUDPStatusApplyConfiguration constructs a declarative configuration of the IngressRouteUDPStatus type for use with +// apply. +func IngressRouteUDPStatus() *IngressRouteUDPStatusApplyConfiguration { + return &IngressRouteUDPStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *IngressRouteUDPStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *IngressRouteUDPStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middleware.go index 6b63dad25f..ec6581088b 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middleware.go @@ -42,7 +42,8 @@ type MiddlewareApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *MiddlewareSpecApplyConfiguration `json:"spec,omitempty"` + Spec *MiddlewareSpecApplyConfiguration `json:"spec,omitempty"` + Status *MiddlewareStatusApplyConfiguration `json:"status,omitempty"` } // Middleware constructs a declarative configuration of the Middleware type for use with @@ -224,6 +225,14 @@ func (b *MiddlewareApplyConfiguration) WithSpec(value *MiddlewareSpecApplyConfig return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *MiddlewareApplyConfiguration) WithStatus(value *MiddlewareStatusApplyConfiguration) *MiddlewareApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *MiddlewareApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewarestatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewarestatus.go new file mode 100644 index 0000000000..8ba5dcac9e --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewarestatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// MiddlewareStatusApplyConfiguration represents a declarative configuration of the MiddlewareStatus type for use +// with apply. +// +// MiddlewareStatus defines the observed state of Middleware. +type MiddlewareStatusApplyConfiguration struct { + // Conditions lists the conditions of the Middleware. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// MiddlewareStatusApplyConfiguration constructs a declarative configuration of the MiddlewareStatus type for use with +// apply. +func MiddlewareStatus() *MiddlewareStatusApplyConfiguration { + return &MiddlewareStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *MiddlewareStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *MiddlewareStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcp.go index 4c29177514..35ac8a41e7 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcp.go @@ -42,7 +42,8 @@ type MiddlewareTCPApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *MiddlewareTCPSpecApplyConfiguration `json:"spec,omitempty"` + Spec *MiddlewareTCPSpecApplyConfiguration `json:"spec,omitempty"` + Status *MiddlewareTCPStatusApplyConfiguration `json:"status,omitempty"` } // MiddlewareTCP constructs a declarative configuration of the MiddlewareTCP type for use with @@ -224,6 +225,14 @@ func (b *MiddlewareTCPApplyConfiguration) WithSpec(value *MiddlewareTCPSpecApply return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *MiddlewareTCPApplyConfiguration) WithStatus(value *MiddlewareTCPStatusApplyConfiguration) *MiddlewareTCPApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *MiddlewareTCPApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcpstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcpstatus.go new file mode 100644 index 0000000000..c63755a7f9 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/middlewaretcpstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// MiddlewareTCPStatusApplyConfiguration represents a declarative configuration of the MiddlewareTCPStatus type for use +// with apply. +// +// MiddlewareTCPStatus defines the observed state of MiddlewareTCP. +type MiddlewareTCPStatusApplyConfiguration struct { + // Conditions lists the conditions of the MiddlewareTCP. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// MiddlewareTCPStatusApplyConfiguration constructs a declarative configuration of the MiddlewareTCPStatus type for use with +// apply. +func MiddlewareTCPStatus() *MiddlewareTCPStatusApplyConfiguration { + return &MiddlewareTCPStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *MiddlewareTCPStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *MiddlewareTCPStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransport.go index 65d109eb19..4564b8ae5d 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransport.go @@ -44,7 +44,8 @@ type ServersTransportApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *ServersTransportSpecApplyConfiguration `json:"spec,omitempty"` + Spec *ServersTransportSpecApplyConfiguration `json:"spec,omitempty"` + Status *ServersTransportStatusApplyConfiguration `json:"status,omitempty"` } // ServersTransport constructs a declarative configuration of the ServersTransport type for use with @@ -226,6 +227,14 @@ func (b *ServersTransportApplyConfiguration) WithSpec(value *ServersTransportSpe return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ServersTransportApplyConfiguration) WithStatus(value *ServersTransportStatusApplyConfiguration) *ServersTransportApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *ServersTransportApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransportstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransportstatus.go new file mode 100644 index 0000000000..9c6123f2ef --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransportstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ServersTransportStatusApplyConfiguration represents a declarative configuration of the ServersTransportStatus type for use +// with apply. +// +// ServersTransportStatus defines the observed state of ServersTransport. +type ServersTransportStatusApplyConfiguration struct { + // Conditions lists the conditions of the ServersTransport. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ServersTransportStatusApplyConfiguration constructs a declarative configuration of the ServersTransportStatus type for use with +// apply. +func ServersTransportStatus() *ServersTransportStatusApplyConfiguration { + return &ServersTransportStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ServersTransportStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ServersTransportStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcp.go index 6c2fab7b01..1d7cf19d9a 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcp.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcp.go @@ -44,7 +44,8 @@ type ServersTransportTCPApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *ServersTransportTCPSpecApplyConfiguration `json:"spec,omitempty"` + Spec *ServersTransportTCPSpecApplyConfiguration `json:"spec,omitempty"` + Status *ServersTransportTCPStatusApplyConfiguration `json:"status,omitempty"` } // ServersTransportTCP constructs a declarative configuration of the ServersTransportTCP type for use with @@ -226,6 +227,14 @@ func (b *ServersTransportTCPApplyConfiguration) WithSpec(value *ServersTransport return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ServersTransportTCPApplyConfiguration) WithStatus(value *ServersTransportTCPStatusApplyConfiguration) *ServersTransportTCPApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *ServersTransportTCPApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcpstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcpstatus.go new file mode 100644 index 0000000000..d1eaa2163a --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/serverstransporttcpstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ServersTransportTCPStatusApplyConfiguration represents a declarative configuration of the ServersTransportTCPStatus type for use +// with apply. +// +// ServersTransportTCPStatus defines the observed state of ServersTransportTCP. +type ServersTransportTCPStatusApplyConfiguration struct { + // Conditions lists the conditions of the ServersTransportTCP. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ServersTransportTCPStatusApplyConfiguration constructs a declarative configuration of the ServersTransportTCPStatus type for use with +// apply. +func ServersTransportTCPStatus() *ServersTransportTCPStatusApplyConfiguration { + return &ServersTransportTCPStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ServersTransportTCPStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ServersTransportTCPStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoption.go index 45f6c913ee..10c5f308e7 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoption.go @@ -42,7 +42,8 @@ type TLSOptionApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *TLSOptionSpecApplyConfiguration `json:"spec,omitempty"` + Spec *TLSOptionSpecApplyConfiguration `json:"spec,omitempty"` + Status *TLSOptionStatusApplyConfiguration `json:"status,omitempty"` } // TLSOption constructs a declarative configuration of the TLSOption type for use with @@ -224,6 +225,14 @@ func (b *TLSOptionApplyConfiguration) WithSpec(value *TLSOptionSpecApplyConfigur return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *TLSOptionApplyConfiguration) WithStatus(value *TLSOptionStatusApplyConfiguration) *TLSOptionApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *TLSOptionApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoptionstatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoptionstatus.go new file mode 100644 index 0000000000..3d14b3eec5 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsoptionstatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// TLSOptionStatusApplyConfiguration represents a declarative configuration of the TLSOptionStatus type for use +// with apply. +// +// TLSOptionStatus defines the observed state of TLSOption. +type TLSOptionStatusApplyConfiguration struct { + // Conditions lists the conditions of the TLSOption. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// TLSOptionStatusApplyConfiguration constructs a declarative configuration of the TLSOptionStatus type for use with +// apply. +func TLSOptionStatus() *TLSOptionStatusApplyConfiguration { + return &TLSOptionStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *TLSOptionStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *TLSOptionStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstore.go index f60492d725..f6e3750cbb 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstore.go @@ -44,7 +44,8 @@ type TLSStoreApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *TLSStoreSpecApplyConfiguration `json:"spec,omitempty"` + Spec *TLSStoreSpecApplyConfiguration `json:"spec,omitempty"` + Status *TLSStoreStatusApplyConfiguration `json:"status,omitempty"` } // TLSStore constructs a declarative configuration of the TLSStore type for use with @@ -226,6 +227,14 @@ func (b *TLSStoreApplyConfiguration) WithSpec(value *TLSStoreSpecApplyConfigurat return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *TLSStoreApplyConfiguration) WithStatus(value *TLSStoreStatusApplyConfiguration) *TLSStoreApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *TLSStoreApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstorestatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstorestatus.go new file mode 100644 index 0000000000..0969ca63d8 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/tlsstorestatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// TLSStoreStatusApplyConfiguration represents a declarative configuration of the TLSStoreStatus type for use +// with apply. +// +// TLSStoreStatus defines the observed state of TLSStore. +type TLSStoreStatusApplyConfiguration struct { + // Conditions lists the conditions of the TLSStore. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// TLSStoreStatusApplyConfiguration constructs a declarative configuration of the TLSStoreStatus type for use with +// apply. +func TLSStoreStatus() *TLSStoreStatusApplyConfiguration { + return &TLSStoreStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *TLSStoreStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *TLSStoreStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservice.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservice.go index 6afdd23141..df694a4edf 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservice.go @@ -45,7 +45,8 @@ type TraefikServiceApplyConfiguration struct { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *TraefikServiceSpecApplyConfiguration `json:"spec,omitempty"` + Spec *TraefikServiceSpecApplyConfiguration `json:"spec,omitempty"` + Status *TraefikServiceStatusApplyConfiguration `json:"status,omitempty"` } // TraefikService constructs a declarative configuration of the TraefikService type for use with @@ -227,6 +228,14 @@ func (b *TraefikServiceApplyConfiguration) WithSpec(value *TraefikServiceSpecApp return b } +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *TraefikServiceApplyConfiguration) WithStatus(value *TraefikServiceStatusApplyConfiguration) *TraefikServiceApplyConfiguration { + b.Status = value + return b +} + // GetKind retrieves the value of the Kind field in the declarative configuration. func (b *TraefikServiceApplyConfiguration) GetKind() *string { return b.TypeMetaApplyConfiguration.Kind diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicestatus.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicestatus.go new file mode 100644 index 0000000000..23b5dda8ee --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicestatus.go @@ -0,0 +1,59 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// TraefikServiceStatusApplyConfiguration represents a declarative configuration of the TraefikServiceStatus type for use +// with apply. +// +// TraefikServiceStatus defines the observed state of TraefikService. +type TraefikServiceStatusApplyConfiguration struct { + // Conditions lists the conditions of the TraefikService. + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// TraefikServiceStatusApplyConfiguration constructs a declarative configuration of the TraefikServiceStatus type for use with +// apply. +func TraefikServiceStatus() *TraefikServiceStatusApplyConfiguration { + return &TraefikServiceStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *TraefikServiceStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *TraefikServiceStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go index de36fd858d..e65885eaff 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go @@ -78,14 +78,20 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &traefikiov1alpha1.IngressRouteRefApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteSpec"): return &traefikiov1alpha1.IngressRouteSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteStatus"): + return &traefikiov1alpha1.IngressRouteStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteTCP"): return &traefikiov1alpha1.IngressRouteTCPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteTCPSpec"): return &traefikiov1alpha1.IngressRouteTCPSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteTCPStatus"): + return &traefikiov1alpha1.IngressRouteTCPStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteUDP"): return &traefikiov1alpha1.IngressRouteUDPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteUDPSpec"): return &traefikiov1alpha1.IngressRouteUDPSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("IngressRouteUDPStatus"): + return &traefikiov1alpha1.IngressRouteUDPStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("LoadBalancerSpec"): return &traefikiov1alpha1.LoadBalancerSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("Middleware"): @@ -94,10 +100,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &traefikiov1alpha1.MiddlewareRefApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("MiddlewareSpec"): return &traefikiov1alpha1.MiddlewareSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("MiddlewareStatus"): + return &traefikiov1alpha1.MiddlewareStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("MiddlewareTCP"): return &traefikiov1alpha1.MiddlewareTCPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("MiddlewareTCPSpec"): return &traefikiov1alpha1.MiddlewareTCPSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("MiddlewareTCPStatus"): + return &traefikiov1alpha1.MiddlewareTCPStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("Mirroring"): return &traefikiov1alpha1.MirroringApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("MirrorService"): @@ -130,10 +140,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &traefikiov1alpha1.ServersTransportApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServersTransportSpec"): return &traefikiov1alpha1.ServersTransportSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("ServersTransportStatus"): + return &traefikiov1alpha1.ServersTransportStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServersTransportTCP"): return &traefikiov1alpha1.ServersTransportTCPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServersTransportTCPSpec"): return &traefikiov1alpha1.ServersTransportTCPSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("ServersTransportTCPStatus"): + return &traefikiov1alpha1.ServersTransportTCPStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("Service"): return &traefikiov1alpha1.ServiceApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServiceTCP"): @@ -150,18 +164,24 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &traefikiov1alpha1.TLSOptionRefApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TLSOptionSpec"): return &traefikiov1alpha1.TLSOptionSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("TLSOptionStatus"): + return &traefikiov1alpha1.TLSOptionStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TLSStore"): return &traefikiov1alpha1.TLSStoreApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TLSStoreRef"): return &traefikiov1alpha1.TLSStoreRefApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TLSStoreSpec"): return &traefikiov1alpha1.TLSStoreSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("TLSStoreStatus"): + return &traefikiov1alpha1.TLSStoreStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TLSTCP"): return &traefikiov1alpha1.TLSTCPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TraefikService"): return &traefikiov1alpha1.TraefikServiceApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("TraefikServiceSpec"): return &traefikiov1alpha1.TraefikServiceSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("TraefikServiceStatus"): + return &traefikiov1alpha1.TraefikServiceStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("WeightedRoundRobin"): return &traefikiov1alpha1.WeightedRoundRobinApplyConfiguration{} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go index 66cd158a05..86d4c91929 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go @@ -48,6 +48,8 @@ type IngressRoutesGetter interface { type IngressRouteInterface interface { Create(ctx context.Context, ingressRoute *traefikiov1alpha1.IngressRoute, opts v1.CreateOptions) (*traefikiov1alpha1.IngressRoute, error) Update(ctx context.Context, ingressRoute *traefikiov1alpha1.IngressRoute, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRoute, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, ingressRoute *traefikiov1alpha1.IngressRoute, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRoute, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.IngressRoute, error) @@ -55,6 +57,8 @@ type IngressRouteInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.IngressRoute, err error) Apply(ctx context.Context, ingressRoute *applyconfigurationtraefikiov1alpha1.IngressRouteApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRoute, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, ingressRoute *applyconfigurationtraefikiov1alpha1.IngressRouteApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRoute, err error) IngressRouteExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go index 7449553cc2..bd836aa124 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go @@ -48,6 +48,8 @@ type IngressRouteTCPsGetter interface { type IngressRouteTCPInterface interface { Create(ctx context.Context, ingressRouteTCP *traefikiov1alpha1.IngressRouteTCP, opts v1.CreateOptions) (*traefikiov1alpha1.IngressRouteTCP, error) Update(ctx context.Context, ingressRouteTCP *traefikiov1alpha1.IngressRouteTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRouteTCP, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, ingressRouteTCP *traefikiov1alpha1.IngressRouteTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRouteTCP, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.IngressRouteTCP, error) @@ -55,6 +57,8 @@ type IngressRouteTCPInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.IngressRouteTCP, err error) Apply(ctx context.Context, ingressRouteTCP *applyconfigurationtraefikiov1alpha1.IngressRouteTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRouteTCP, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, ingressRouteTCP *applyconfigurationtraefikiov1alpha1.IngressRouteTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRouteTCP, err error) IngressRouteTCPExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go index 183791e177..d3a1d9108b 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go @@ -48,6 +48,8 @@ type IngressRouteUDPsGetter interface { type IngressRouteUDPInterface interface { Create(ctx context.Context, ingressRouteUDP *traefikiov1alpha1.IngressRouteUDP, opts v1.CreateOptions) (*traefikiov1alpha1.IngressRouteUDP, error) Update(ctx context.Context, ingressRouteUDP *traefikiov1alpha1.IngressRouteUDP, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRouteUDP, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, ingressRouteUDP *traefikiov1alpha1.IngressRouteUDP, opts v1.UpdateOptions) (*traefikiov1alpha1.IngressRouteUDP, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.IngressRouteUDP, error) @@ -55,6 +57,8 @@ type IngressRouteUDPInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.IngressRouteUDP, err error) Apply(ctx context.Context, ingressRouteUDP *applyconfigurationtraefikiov1alpha1.IngressRouteUDPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRouteUDP, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, ingressRouteUDP *applyconfigurationtraefikiov1alpha1.IngressRouteUDPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.IngressRouteUDP, err error) IngressRouteUDPExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go index 3302861511..6669aae615 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go @@ -48,6 +48,8 @@ type MiddlewaresGetter interface { type MiddlewareInterface interface { Create(ctx context.Context, middleware *traefikiov1alpha1.Middleware, opts v1.CreateOptions) (*traefikiov1alpha1.Middleware, error) Update(ctx context.Context, middleware *traefikiov1alpha1.Middleware, opts v1.UpdateOptions) (*traefikiov1alpha1.Middleware, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, middleware *traefikiov1alpha1.Middleware, opts v1.UpdateOptions) (*traefikiov1alpha1.Middleware, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.Middleware, error) @@ -55,6 +57,8 @@ type MiddlewareInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.Middleware, err error) Apply(ctx context.Context, middleware *applyconfigurationtraefikiov1alpha1.MiddlewareApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.Middleware, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, middleware *applyconfigurationtraefikiov1alpha1.MiddlewareApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.Middleware, err error) MiddlewareExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go index 534a57ff12..f237edd817 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go @@ -48,6 +48,8 @@ type MiddlewareTCPsGetter interface { type MiddlewareTCPInterface interface { Create(ctx context.Context, middlewareTCP *traefikiov1alpha1.MiddlewareTCP, opts v1.CreateOptions) (*traefikiov1alpha1.MiddlewareTCP, error) Update(ctx context.Context, middlewareTCP *traefikiov1alpha1.MiddlewareTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.MiddlewareTCP, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, middlewareTCP *traefikiov1alpha1.MiddlewareTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.MiddlewareTCP, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.MiddlewareTCP, error) @@ -55,6 +57,8 @@ type MiddlewareTCPInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.MiddlewareTCP, err error) Apply(ctx context.Context, middlewareTCP *applyconfigurationtraefikiov1alpha1.MiddlewareTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.MiddlewareTCP, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, middlewareTCP *applyconfigurationtraefikiov1alpha1.MiddlewareTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.MiddlewareTCP, err error) MiddlewareTCPExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go index 187bb801f2..dce991d8c9 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go @@ -48,6 +48,8 @@ type ServersTransportsGetter interface { type ServersTransportInterface interface { Create(ctx context.Context, serversTransport *traefikiov1alpha1.ServersTransport, opts v1.CreateOptions) (*traefikiov1alpha1.ServersTransport, error) Update(ctx context.Context, serversTransport *traefikiov1alpha1.ServersTransport, opts v1.UpdateOptions) (*traefikiov1alpha1.ServersTransport, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, serversTransport *traefikiov1alpha1.ServersTransport, opts v1.UpdateOptions) (*traefikiov1alpha1.ServersTransport, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.ServersTransport, error) @@ -55,6 +57,8 @@ type ServersTransportInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.ServersTransport, err error) Apply(ctx context.Context, serversTransport *applyconfigurationtraefikiov1alpha1.ServersTransportApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.ServersTransport, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, serversTransport *applyconfigurationtraefikiov1alpha1.ServersTransportApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.ServersTransport, err error) ServersTransportExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go index f9b56fb3af..abd37662de 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go @@ -48,6 +48,8 @@ type ServersTransportTCPsGetter interface { type ServersTransportTCPInterface interface { Create(ctx context.Context, serversTransportTCP *traefikiov1alpha1.ServersTransportTCP, opts v1.CreateOptions) (*traefikiov1alpha1.ServersTransportTCP, error) Update(ctx context.Context, serversTransportTCP *traefikiov1alpha1.ServersTransportTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.ServersTransportTCP, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, serversTransportTCP *traefikiov1alpha1.ServersTransportTCP, opts v1.UpdateOptions) (*traefikiov1alpha1.ServersTransportTCP, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.ServersTransportTCP, error) @@ -55,6 +57,8 @@ type ServersTransportTCPInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.ServersTransportTCP, err error) Apply(ctx context.Context, serversTransportTCP *applyconfigurationtraefikiov1alpha1.ServersTransportTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.ServersTransportTCP, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, serversTransportTCP *applyconfigurationtraefikiov1alpha1.ServersTransportTCPApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.ServersTransportTCP, err error) ServersTransportTCPExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go index 6f7842f53e..0bea9a80e4 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go @@ -48,6 +48,8 @@ type TLSOptionsGetter interface { type TLSOptionInterface interface { Create(ctx context.Context, tLSOption *traefikiov1alpha1.TLSOption, opts v1.CreateOptions) (*traefikiov1alpha1.TLSOption, error) Update(ctx context.Context, tLSOption *traefikiov1alpha1.TLSOption, opts v1.UpdateOptions) (*traefikiov1alpha1.TLSOption, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, tLSOption *traefikiov1alpha1.TLSOption, opts v1.UpdateOptions) (*traefikiov1alpha1.TLSOption, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.TLSOption, error) @@ -55,6 +57,8 @@ type TLSOptionInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.TLSOption, err error) Apply(ctx context.Context, tLSOption *applyconfigurationtraefikiov1alpha1.TLSOptionApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TLSOption, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, tLSOption *applyconfigurationtraefikiov1alpha1.TLSOptionApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TLSOption, err error) TLSOptionExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go index de517efdb2..5b477ed50b 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go @@ -48,6 +48,8 @@ type TLSStoresGetter interface { type TLSStoreInterface interface { Create(ctx context.Context, tLSStore *traefikiov1alpha1.TLSStore, opts v1.CreateOptions) (*traefikiov1alpha1.TLSStore, error) Update(ctx context.Context, tLSStore *traefikiov1alpha1.TLSStore, opts v1.UpdateOptions) (*traefikiov1alpha1.TLSStore, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, tLSStore *traefikiov1alpha1.TLSStore, opts v1.UpdateOptions) (*traefikiov1alpha1.TLSStore, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.TLSStore, error) @@ -55,6 +57,8 @@ type TLSStoreInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.TLSStore, err error) Apply(ctx context.Context, tLSStore *applyconfigurationtraefikiov1alpha1.TLSStoreApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TLSStore, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, tLSStore *applyconfigurationtraefikiov1alpha1.TLSStoreApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TLSStore, err error) TLSStoreExpansion } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go index 1bc07d33e0..e652225739 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go @@ -48,6 +48,8 @@ type TraefikServicesGetter interface { type TraefikServiceInterface interface { Create(ctx context.Context, traefikService *traefikiov1alpha1.TraefikService, opts v1.CreateOptions) (*traefikiov1alpha1.TraefikService, error) Update(ctx context.Context, traefikService *traefikiov1alpha1.TraefikService, opts v1.UpdateOptions) (*traefikiov1alpha1.TraefikService, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, traefikService *traefikiov1alpha1.TraefikService, opts v1.UpdateOptions) (*traefikiov1alpha1.TraefikService, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*traefikiov1alpha1.TraefikService, error) @@ -55,6 +57,8 @@ type TraefikServiceInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *traefikiov1alpha1.TraefikService, err error) Apply(ctx context.Context, traefikService *applyconfigurationtraefikiov1alpha1.TraefikServiceApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TraefikService, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, traefikService *applyconfigurationtraefikiov1alpha1.TraefikServiceApplyConfiguration, opts v1.ApplyOptions) (result *traefikiov1alpha1.TraefikService, err error) TraefikServiceExpansion } diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index e650e13ebc..5e4de4cfd6 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -34,6 +34,8 @@ import ( "github.com/traefik/traefik/v3/pkg/types" corev1 "k8s.io/api/core/v1" apiextensionv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + kerror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -49,6 +51,58 @@ const ( providerNamespaceSeparator = "@" ) +// statusTracker collects processing errors for a set of Kubernetes resources. +type statusTracker struct { + errors map[string][]error + seen map[string]bool +} + +func newStatusTracker() *statusTracker { + return &statusTracker{ + errors: make(map[string][]error), + seen: make(map[string]bool), + } +} + +func (t *statusTracker) visit(namespace, name string) { + t.seen[namespace+"/"+name] = true +} + +func (t *statusTracker) addError(namespace, name string, err error) { + key := namespace + "/" + name + t.seen[key] = true + t.errors[key] = append(t.errors[key], err) +} + +// configStatuses collects processing results for all CRD resource types. +type configStatuses struct { + ingressRoutes *statusTracker + ingressRoutesTCP *statusTracker + ingressRoutesUDP *statusTracker + middlewares *statusTracker + middlewaresTCP *statusTracker + serversTransports *statusTracker + serversTransportsTCP *statusTracker + tlsOptions *statusTracker + tlsStores *statusTracker + traefikServices *statusTracker +} + +func newConfigStatuses() configStatuses { + return configStatuses{ + ingressRoutes: newStatusTracker(), + ingressRoutesTCP: newStatusTracker(), + ingressRoutesUDP: newStatusTracker(), + middlewares: newStatusTracker(), + middlewaresTCP: newStatusTracker(), + serversTransports: newStatusTracker(), + serversTransportsTCP: newStatusTracker(), + tlsOptions: newStatusTracker(), + tlsStores: newStatusTracker(), + traefikServices: newStatusTracker(), + } +} + // Provider holds configurations of the provider. type Provider struct { Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` @@ -126,7 +180,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. // Note that event is the *first* event that came in during this throttling interval -- if we're hitting our throttle, we may have dropped events. // This is fine, because we don't treat different event types differently. // But if we do in the future, we'll need to track more information about the dropped events. - conf := p.loadConfigurationFromCRD(ctxLog, k8sClient) + conf, statuses := p.loadConfigurationFromCRD(ctxLog, k8sClient) confHash, err := hashstructure.Hash(conf, nil) switch { @@ -142,6 +196,8 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. } } + updateCRDStatuses(ctxLog, k8sClient, statuses) + // If we're throttling, // we sleep here for the throttle duration to enforce that we don't refresh faster than our throttle. // time.Sleep returns immediately if p.ThrottleDuration is 0 (no throttle). @@ -229,19 +285,21 @@ func (p *Provider) newK8sClient(ctx context.Context) (*clientWrapper, error) { return client, nil } -func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) *dynamic.Configuration { - stores, tlsConfigs := buildTLSStores(ctx, client) +func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) (*dynamic.Configuration, configStatuses) { + statuses := newConfigStatuses() + + stores, tlsConfigs := buildTLSStores(ctx, client, statuses.tlsStores) if tlsConfigs == nil { tlsConfigs = make(map[string]*tls.CertAndStores) } conf := &dynamic.Configuration{ // TODO: choose between mutating and returning tlsConfigs - HTTP: p.loadIngressRouteConfiguration(ctx, client, tlsConfigs), - TCP: p.loadIngressRouteTCPConfiguration(ctx, client, tlsConfigs), - UDP: p.loadIngressRouteUDPConfiguration(ctx, client), + HTTP: p.loadIngressRouteConfiguration(ctx, client, tlsConfigs, statuses.ingressRoutes), + TCP: p.loadIngressRouteTCPConfiguration(ctx, client, tlsConfigs, statuses.ingressRoutesTCP), + UDP: p.loadIngressRouteUDPConfiguration(ctx, client, statuses.ingressRoutesUDP), TLS: &dynamic.TLSConfiguration{ - Options: buildTLSOptions(ctx, client), + Options: buildTLSOptions(ctx, client, statuses.tlsOptions), Stores: stores, }, } @@ -253,28 +311,33 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) id := provider.Normalize(makeID(middleware.Namespace, middleware.Name)) logger := log.Ctx(ctx).With().Str(logs.MiddlewareName, id).Logger() ctxMid := logger.WithContext(ctx) + statuses.middlewares.visit(middleware.Namespace, middleware.Name) basicAuth, err := createBasicAuthMiddleware(client, middleware.Namespace, middleware.Spec.BasicAuth) if err != nil { logger.Error().Err(err).Msg("Error while reading basic auth middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } digestAuth, err := createDigestAuthMiddleware(client, middleware.Namespace, middleware.Spec.DigestAuth) if err != nil { logger.Error().Err(err).Msg("Error while reading digest auth middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } forwardAuth, err := createForwardAuthMiddleware(client, middleware.Namespace, middleware.Spec.ForwardAuth) if err != nil { logger.Error().Err(err).Msg("Error while reading forward auth middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } errorPageName, errorPage, errorPageService, err := p.createErrorPageMiddleware(ctxMid, client, middleware.Namespace, middleware.Spec.Errors) if err != nil { logger.Error().Err(err).Msg("Error while reading error page middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } @@ -291,30 +354,35 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) plugin, err := createPluginMiddleware(client, middleware.Namespace, middleware.Spec.Plugin) if err != nil { logger.Error().Err(err).Msg("Error while reading plugins middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } rateLimit, err := createRateLimitMiddleware(client, middleware.Namespace, middleware.Spec.RateLimit) if err != nil { logger.Error().Err(err).Msg("Error while reading rateLimit middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } retry, err := createRetryMiddleware(middleware.Spec.Retry) if err != nil { logger.Error().Err(err).Msg("Error while reading retry middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } circuitBreaker, err := createCircuitBreakerMiddleware(middleware.Spec.CircuitBreaker) if err != nil { logger.Error().Err(err).Msg("Error while reading circuit breaker middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } chain, err := p.createChainMiddleware(ctxMid, middleware.Namespace, middleware.Spec.Chain) if err != nil { logger.Error().Err(err).Msg("Error while reading chain middleware") + statuses.middlewares.addError(middleware.Namespace, middleware.Name, err) continue } @@ -350,6 +418,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) for _, middlewareTCP := range client.GetMiddlewareTCPs() { id := provider.Normalize(makeID(middlewareTCP.Namespace, middlewareTCP.Name)) + statuses.middlewaresTCP.visit(middlewareTCP.Namespace, middlewareTCP.Name) conf.TCP.Middlewares[id] = &dynamic.TCPMiddleware{ InFlightConn: middlewareTCP.Spec.InFlightConn, @@ -367,10 +436,12 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) } for _, service := range client.GetTraefikServices() { + statuses.traefikServices.visit(service.Namespace, service.Name) err := cb.buildTraefikService(ctx, service, conf.HTTP.Services) if err != nil { log.Ctx(ctx).Error().Str(logs.ServiceName, service.Name).Err(err). Msg("Error while building TraefikService") + statuses.traefikServices.addError(service.Namespace, service.Name, err) continue } } @@ -380,6 +451,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Str(logs.ServersTransportName, serversTransport.Name). Str("namespace", serversTransport.Namespace). Logger() + statuses.serversTransports.visit(serversTransport.Namespace, serversTransport.Name) if len(serversTransport.Spec.RootCAsSecrets) > 0 { logger.Warn().Msg("RootCAsSecrets option is deprecated, please use the RootCA option instead.") @@ -393,6 +465,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("secret", secret). Msg("Error while loading CA Secret") + statuses.serversTransports.addError(serversTransport.Namespace, serversTransport.Name, err) continue } @@ -401,7 +474,9 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) for _, rootCA := range serversTransport.Spec.RootCAs { if rootCA.Secret != nil && rootCA.ConfigMap != nil { + err := errors.New("both Secret and ConfigMap are defined for a RootCA") logger.Error().Msg("Error while loading CA: both Secret and ConfigMap are defined") + statuses.serversTransports.addError(serversTransport.Namespace, serversTransport.Name, err) continue } @@ -412,6 +487,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("secret", *rootCA.Secret). Msg("Error while loading CA Secret") + statuses.serversTransports.addError(serversTransport.Namespace, serversTransport.Name, err) continue } @@ -425,6 +501,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("configMap", *rootCA.ConfigMap). Msg("Error while loading CA ConfigMap") + statuses.serversTransports.addError(serversTransport.Namespace, serversTransport.Name, err) continue } @@ -436,6 +513,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) tlsSecret, tlsKey, err := loadAuthTLSSecret(serversTransport.Namespace, secret, client) if err != nil { logger.Error().Err(err).Msgf("Error while loading certificates %s", secret) + statuses.serversTransports.addError(serversTransport.Namespace, serversTransport.Name, err) continue } @@ -547,6 +625,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) for _, serversTransportTCP := range client.GetServersTransportTCPs() { logger := log.Ctx(ctx).With().Str(logs.ServersTransportName, serversTransportTCP.Name).Logger() + statuses.serversTransportsTCP.visit(serversTransportTCP.Namespace, serversTransportTCP.Name) var tcpServerTransport dynamic.TCPServersTransport tcpServerTransport.SetDefaults() @@ -589,6 +668,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("secret", secret). Msg("Error while loading CA Secret") + statuses.serversTransportsTCP.addError(serversTransportTCP.Namespace, serversTransportTCP.Name, err) continue } @@ -597,7 +677,9 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) for _, rootCA := range serversTransportTCP.Spec.TLS.RootCAs { if rootCA.Secret != nil && rootCA.ConfigMap != nil { + err := errors.New("both Secret and ConfigMap are defined for a RootCA") logger.Error().Msg("Error while loading CA: both Secret and ConfigMap are defined") + statuses.serversTransportsTCP.addError(serversTransportTCP.Namespace, serversTransportTCP.Name, err) continue } @@ -608,6 +690,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("secret", *rootCA.Secret). Msg("Error while loading CA Secret") + statuses.serversTransportsTCP.addError(serversTransportTCP.Namespace, serversTransportTCP.Name, err) continue } @@ -621,6 +704,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("configMap", *rootCA.ConfigMap). Msg("Error while loading CA ConfigMap") + statuses.serversTransportsTCP.addError(serversTransportTCP.Namespace, serversTransportTCP.Name, err) continue } @@ -635,6 +719,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) Err(err). Str("certificates", secret). Msg("Error while loading certificates") + statuses.serversTransportsTCP.addError(serversTransportTCP.Namespace, serversTransportTCP.Name, err) continue } @@ -659,7 +744,154 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) conf.TCP.ServersTransports[id] = &tcpServerTransport } - return conf + return conf, statuses +} + +func updateCRDStatuses(ctx context.Context, client Client, statuses configStatuses) { + logger := log.Ctx(ctx) + + writeStatus := func(err error, resource string) bool { + if err == nil { + return true + } + if kerror.IsForbidden(err) { + logger.Warn().Err(err).Msgf("Skipping CRD status updates: missing RBAC permissions to update %s status subresource. Grant update/patch on %s/status to the Traefik Role.", resource, resource) + return false + } + logger.Error().Err(err).Msgf("Failed to update %s status", resource) + return true + } + + for _, ir := range client.GetIngressRoutes() { + if !statuses.ingressRoutes.seen[ir.Namespace+"/"+ir.Name] { + continue + } + conditions := buildResourceCondition(statuses.ingressRoutes, ir.Namespace, ir.Name, ir.Generation) + if !writeStatus(client.UpdateIngressRouteStatus(ctx, ir.Namespace, ir.Name, conditions), "ingressroutes") { + return + } + } + + for _, ir := range client.GetIngressRouteTCPs() { + if !statuses.ingressRoutesTCP.seen[ir.Namespace+"/"+ir.Name] { + continue + } + conditions := buildResourceCondition(statuses.ingressRoutesTCP, ir.Namespace, ir.Name, ir.Generation) + if !writeStatus(client.UpdateIngressRouteTCPStatus(ctx, ir.Namespace, ir.Name, conditions), "ingressroutetcps") { + return + } + } + + for _, ir := range client.GetIngressRouteUDPs() { + if !statuses.ingressRoutesUDP.seen[ir.Namespace+"/"+ir.Name] { + continue + } + conditions := buildResourceCondition(statuses.ingressRoutesUDP, ir.Namespace, ir.Name, ir.Generation) + if !writeStatus(client.UpdateIngressRouteUDPStatus(ctx, ir.Namespace, ir.Name, conditions), "ingressrouteudps") { + return + } + } + + for _, mw := range client.GetMiddlewares() { + if !statuses.middlewares.seen[mw.Namespace+"/"+mw.Name] { + continue + } + conditions := buildResourceCondition(statuses.middlewares, mw.Namespace, mw.Name, mw.Generation) + if !writeStatus(client.UpdateMiddlewareStatus(ctx, mw.Namespace, mw.Name, conditions), "middlewares") { + return + } + } + + for _, mw := range client.GetMiddlewareTCPs() { + if !statuses.middlewaresTCP.seen[mw.Namespace+"/"+mw.Name] { + continue + } + conditions := buildResourceCondition(statuses.middlewaresTCP, mw.Namespace, mw.Name, mw.Generation) + if !writeStatus(client.UpdateMiddlewareTCPStatus(ctx, mw.Namespace, mw.Name, conditions), "middlewaretcps") { + return + } + } + + for _, st := range client.GetServersTransports() { + if !statuses.serversTransports.seen[st.Namespace+"/"+st.Name] { + continue + } + conditions := buildResourceCondition(statuses.serversTransports, st.Namespace, st.Name, st.Generation) + if !writeStatus(client.UpdateServersTransportStatus(ctx, st.Namespace, st.Name, conditions), "serverstransports") { + return + } + } + + for _, st := range client.GetServersTransportTCPs() { + if !statuses.serversTransportsTCP.seen[st.Namespace+"/"+st.Name] { + continue + } + conditions := buildResourceCondition(statuses.serversTransportsTCP, st.Namespace, st.Name, st.Generation) + if !writeStatus(client.UpdateServersTransportTCPStatus(ctx, st.Namespace, st.Name, conditions), "serverstransporttcps") { + return + } + } + + for _, opt := range client.GetTLSOptions() { + if !statuses.tlsOptions.seen[opt.Namespace+"/"+opt.Name] { + continue + } + conditions := buildResourceCondition(statuses.tlsOptions, opt.Namespace, opt.Name, opt.Generation) + if !writeStatus(client.UpdateTLSOptionStatus(ctx, opt.Namespace, opt.Name, conditions), "tlsoptions") { + return + } + } + + for _, store := range client.GetTLSStores() { + if !statuses.tlsStores.seen[store.Namespace+"/"+store.Name] { + continue + } + conditions := buildResourceCondition(statuses.tlsStores, store.Namespace, store.Name, store.Generation) + if !writeStatus(client.UpdateTLSStoreStatus(ctx, store.Namespace, store.Name, conditions), "tlsstores") { + return + } + } + + for _, svc := range client.GetTraefikServices() { + if !statuses.traefikServices.seen[svc.Namespace+"/"+svc.Name] { + continue + } + conditions := buildResourceCondition(statuses.traefikServices, svc.Namespace, svc.Name, svc.Generation) + if !writeStatus(client.UpdateTraefikServiceStatus(ctx, svc.Namespace, svc.Name, conditions), "traefikservices") { + return + } + } +} + +// buildResourceCondition returns a single "Valid" condition for a CRD resource. +// If the tracker recorded no errors, the condition status is True; otherwise False with error details. +func buildResourceCondition(tracker *statusTracker, namespace, name string, generation int64) []metav1.Condition { + errs := tracker.errors[namespace+"/"+name] + now := metav1.Now() + + if len(errs) == 0 { + return []metav1.Condition{{ + Type: "Valid", + Status: metav1.ConditionTrue, + ObservedGeneration: generation, + LastTransitionTime: now, + Reason: "Processed", + Message: "Resource processed successfully.", + }} + } + + msgs := make([]string, 0, len(errs)) + for _, err := range errs { + msgs = append(msgs, err.Error()) + } + return []metav1.Condition{{ + Type: "Valid", + Status: metav1.ConditionFalse, + ObservedGeneration: generation, + LastTransitionTime: now, + Reason: "ProcessingError", + Message: strings.Join(msgs, "; "), + }} } func (p *Provider) createErrorPageMiddleware(ctx context.Context, client Client, namespace string, errorPage *traefikv1alpha1.ErrorPage) (string, *dynamic.ErrorPage, *dynamic.Service, error) { @@ -1307,7 +1539,7 @@ func loadAuthCredentials(secret *corev1.Secret) ([]string, error) { return credentials, nil } -func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options { +func buildTLSOptions(ctx context.Context, client Client, statuses *statusTracker) map[string]tls.Options { tlsOptionsCRDs := client.GetTLSOptions() var tlsOptions map[string]tls.Options @@ -1319,23 +1551,28 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options for _, tlsOptionsCRD := range tlsOptionsCRDs { logger := log.Ctx(ctx).With().Str("tlsOption", tlsOptionsCRD.Name).Str("namespace", tlsOptionsCRD.Namespace).Logger() + statuses.visit(tlsOptionsCRD.Namespace, tlsOptionsCRD.Name) var clientCAs []types.FileOrContent for _, secretName := range tlsOptionsCRD.Spec.ClientAuth.SecretNames { secret, exists, err := client.GetSecret(tlsOptionsCRD.Namespace, secretName) if err != nil { logger.Error().Err(err).Msgf("Failed to fetch secret %s/%s", tlsOptionsCRD.Namespace, secretName) + statuses.addError(tlsOptionsCRD.Namespace, tlsOptionsCRD.Name, err) continue } if !exists { + err = fmt.Errorf("secret %s/%s does not exist", tlsOptionsCRD.Namespace, secretName) logger.Warn().Msgf("Secret %s/%s does not exist", tlsOptionsCRD.Namespace, secretName) + statuses.addError(tlsOptionsCRD.Namespace, tlsOptionsCRD.Name, err) continue } cert, err := getCABlocks(secret, tlsOptionsCRD.Namespace, secretName) if err != nil { logger.Error().Err(err).Msgf("Failed to extract CA from secret %s/%s", tlsOptionsCRD.Namespace, secretName) + statuses.addError(tlsOptionsCRD.Namespace, tlsOptionsCRD.Name, err) continue } @@ -1383,7 +1620,7 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options return tlsOptions } -func buildTLSStores(ctx context.Context, client Client) (map[string]tls.Store, map[string]*tls.CertAndStores) { +func buildTLSStores(ctx context.Context, client Client, statuses *statusTracker) (map[string]tls.Store, map[string]*tls.CertAndStores) { tlsStoreCRD := client.GetTLSStores() if len(tlsStoreCRD) == 0 { return nil, nil @@ -1395,6 +1632,7 @@ func buildTLSStores(ctx context.Context, client Client) (map[string]tls.Store, m for _, t := range tlsStoreCRD { logger := log.Ctx(ctx).With().Str("TLSStore", t.Name).Str("namespace", t.Namespace).Logger() + statuses.visit(t.Namespace, t.Name) id := makeID(t.Namespace, t.Name) @@ -1412,16 +1650,20 @@ func buildTLSStores(ctx context.Context, client Client) (map[string]tls.Store, m secret, exists, err := client.GetSecret(t.Namespace, secretName) if err != nil { logger.Error().Err(err).Msgf("Failed to fetch secret %s/%s", t.Namespace, secretName) + statuses.addError(t.Namespace, t.Name, err) continue } if !exists { + err = fmt.Errorf("secret %s/%s does not exist", t.Namespace, secretName) logger.Error().Msgf("Secret %s/%s does not exist", t.Namespace, secretName) + statuses.addError(t.Namespace, t.Name, err) continue } cert, key, err := getCertificateBlocks(secret, t.Namespace, secretName) if err != nil { logger.Error().Err(err).Msg("Could not get certificate blocks") + statuses.addError(t.Namespace, t.Name, err) continue } diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index 8d1625b3e7..1a6183b629 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -25,7 +25,7 @@ const ( httpProtocol = "http" ) -func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.HTTPConfiguration { +func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores, statuses *statusTracker) *dynamic.HTTPConfiguration { conf := &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, Middlewares: map[string]*dynamic.Middleware{}, @@ -44,9 +44,12 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli continue } + statuses.visit(ingressRoute.Namespace, ingressRoute.Name) + err := getTLSHTTP(ctx, ingressRoute, client, tlsConfigs) if err != nil { logger.Error().Err(err).Msg("Error configuring TLS") + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) } ingressName := ingressRoute.Name @@ -67,17 +70,22 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli parentRouterNames, err := resolveParentRouterNames(client, ingressRoute, p.AllowCrossNamespace) if err != nil { logger.Error().Err(err).Msg("Error resolving parent routers") + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } for _, route := range ingressRoute.Spec.Routes { if len(route.Kind) > 0 && route.Kind != "Rule" { + err := fmt.Errorf("unsupported match kind: %s", route.Kind) logger.Error().Msgf("Unsupported match kind: %s. Only \"Rule\" is supported for now.", route.Kind) + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } if len(route.Match) == 0 { + err := errors.New("empty match rule") logger.Error().Msg("Empty match rule") + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } @@ -86,6 +94,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli mds, err := makeMiddlewareKeys(ctx, ingressRoute.Namespace, route.Middlewares, p.CrossProviderNamespaces, p.AllowCrossNamespace) if err != nil { logger.Error().Err(err).Msg("Failed to create middleware keys") + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } @@ -103,12 +112,14 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli errBuild := cb.buildServicesLB(ctx, ingressRoute.Namespace, spec, serviceName, conf.Services) if errBuild != nil { logger.Error().Err(errBuild).Send() + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, errBuild) continue } case len(route.Services) == 1: fullName, serversLB, err := cb.nameAndService(ctx, ingressRoute.Namespace, route.Services[0].LoadBalancerSpec) if err != nil { logger.Error().Err(err).Send() + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } @@ -154,6 +165,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli r.TLS.Options, err = resolveReference(ctxTLSOption, ingressRoute.Namespace, tlsOptions.Namespace, tlsOptions.Name, p.CrossProviderNamespaces, p.AllowCrossNamespace) if err != nil { logger.Error().Err(err).Msgf("Invalid reference to TLSOption %q", ingressRoute.Spec.TLS.Options.Name) + statuses.addError(ingressRoute.Namespace, ingressRoute.Name, err) continue } } diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index d62e13edb3..cef9313f12 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -17,7 +17,7 @@ import ( corev1 "k8s.io/api/core/v1" ) -func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.TCPConfiguration { +func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores, statuses *statusTracker) *dynamic.TCPConfiguration { conf := &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{}, Middlewares: map[string]*dynamic.TCPMiddleware{}, @@ -36,10 +36,13 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client continue } + statuses.visit(ingressRouteTCP.Namespace, ingressRouteTCP.Name) + if ingressRouteTCP.Spec.TLS != nil && !ingressRouteTCP.Spec.TLS.Passthrough { err := getTLSTCP(ctx, ingressRouteTCP, client, tlsConfigs) if err != nil { logger.Error().Err(err).Msg("Error configuring TLS") + statuses.addError(ingressRouteTCP.Namespace, ingressRouteTCP.Name, err) } } @@ -50,7 +53,9 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client for _, route := range ingressRouteTCP.Spec.Routes { if len(route.Match) == 0 { + err := errors.New("empty match rule") logger.Error().Msg("Empty match rule") + statuses.addError(ingressRouteTCP.Namespace, ingressRouteTCP.Name, err) continue } @@ -59,6 +64,7 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client mds, err := p.makeMiddlewareTCPKeys(ctx, ingressRouteTCP.Namespace, route.Middlewares) if err != nil { logger.Error().Err(err).Msg("Failed to create middleware keys") + statuses.addError(ingressRouteTCP.Namespace, ingressRouteTCP.Name, err) continue } @@ -120,6 +126,7 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client r.TLS.Options, err = resolveReference(ctxTLSOption, ingressRouteTCP.Namespace, tlsOptions.Namespace, tlsOptions.Name, p.CrossProviderNamespaces, p.AllowCrossNamespace) if err != nil { logger.Error().Err(err).Msgf("Invalid reference to TLSOption %q", ingressRouteTCP.Spec.TLS.Options.Name) + statuses.addError(ingressRouteTCP.Namespace, ingressRouteTCP.Name, err) continue } } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 403f33fb0f..936dc5e07b 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -1805,8 +1805,12 @@ func TestLoadIngressRouteTCPs(t *testing.T) { AllowEmptyServices: test.allowEmptyServices, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) + if len(test.paths) == 0 { + assert.Empty(t, statuses.ingressRoutesTCP.seen) + } }) } } @@ -6394,8 +6398,12 @@ func TestLoadIngressRoutes(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) + if len(test.paths) == 0 { + assert.Empty(t, statuses.ingressRoutes.seen) + } }) } } @@ -6470,7 +6478,9 @@ func TestLoadIngressRoutes_multipleEndpointAddresses(t *testing.T) { } p := Provider{} - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) + assert.NotEmpty(t, statuses.ingressRoutes.seen) service, ok := conf.HTTP.Services["default-test-route-6b204d94623b3df4370c"] require.True(t, ok) @@ -7111,8 +7121,12 @@ func TestLoadIngressRouteUDPs(t *testing.T) { AllowEmptyServices: test.allowEmptyServices, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) + if len(test.paths) == 0 { + assert.Empty(t, statuses.ingressRoutesUDP.seen) + } }) } } @@ -8673,8 +8687,12 @@ func TestCrossNamespace(t *testing.T) { p := Provider{AllowCrossNamespace: test.allowCrossNamespace} - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) + if len(test.paths) == 0 { + assert.Empty(t, statuses.ingressRoutes.seen) + } }) } } @@ -8760,7 +8778,8 @@ func TestCrossProviderNamespaces_HTTPMiddleware(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) router, ok := conf.HTTP.Routers["default-test2-route-23c7f4c450289ee29016"] if test.wantRouterDropped { @@ -8847,7 +8866,8 @@ func TestCrossProviderNamespaces_HTTPServiceTransitivity(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) _, mirrorOK := conf.HTTP.Services["foo-mirror-cp"] _, weightedOK := conf.HTTP.Services["bar-weighted-cp"] @@ -8912,7 +8932,8 @@ func TestCrossProviderNamespaces_HTTPTLSOption(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) router, ok := conf.HTTP.Routers["default-test-route-6b204d94623b3df4370c"] if test.wantRouterDropped { @@ -8981,7 +9002,8 @@ func TestCrossProviderNamespaces_TCPTLSOption(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) router, ok := conf.TCP.Routers["default-test.route-fdd3e9338e47a45efefc"] if test.wantRouterDropped { @@ -9050,7 +9072,8 @@ func TestCrossProviderNamespaces_HTTPServersTransport(t *testing.T) { CrossProviderNamespaces: test.crossProviderNamespaces, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) + assertStatusInvariants(t, conf, statuses) service, ok := conf.HTTP.Services["default-test-route-6b204d94623b3df4370c"] if test.wantServiceDropped { @@ -9329,8 +9352,9 @@ func TestExternalNameService(t *testing.T) { p := Provider{AllowExternalNameServices: test.allowExternalNameService} - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) }) } } @@ -9511,8 +9535,9 @@ func TestNativeLB(t *testing.T) { p := Provider{} - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) }) } } @@ -9779,8 +9804,9 @@ func TestNodePortLB(t *testing.T) { DisableClusterScopeResources: test.disableClusterScope, } - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) }) } } @@ -10423,8 +10449,9 @@ func TestGlobalNativeLB(t *testing.T) { p := Provider{NativeLBByDefault: test.NativeLBByDefault} - conf := p.loadConfigurationFromCRD(t.Context(), client) + conf, statuses := p.loadConfigurationFromCRD(t.Context(), client) assert.Equal(t, test.expected, conf) + assertStatusInvariants(t, conf, statuses) }) } } diff --git a/pkg/provider/kubernetes/crd/kubernetes_udp.go b/pkg/provider/kubernetes/crd/kubernetes_udp.go index 719348b06d..60cb2d2458 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_udp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_udp.go @@ -13,7 +13,7 @@ import ( corev1 "k8s.io/api/core/v1" ) -func (p *Provider) loadIngressRouteUDPConfiguration(ctx context.Context, client Client) *dynamic.UDPConfiguration { +func (p *Provider) loadIngressRouteUDPConfiguration(ctx context.Context, client Client, statuses *statusTracker) *dynamic.UDPConfiguration { conf := &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, Services: map[string]*dynamic.UDPService{}, @@ -30,6 +30,8 @@ func (p *Provider) loadIngressRouteUDPConfiguration(ctx context.Context, client continue } + statuses.visit(ingressRouteUDP.Namespace, ingressRouteUDP.Name) + ingressName := ingressRouteUDP.Name if len(ingressName) == 0 { ingressName = ingressRouteUDP.GenerateName @@ -47,6 +49,7 @@ func (p *Provider) loadIngressRouteUDPConfiguration(ctx context.Context, client Stringer("servicePort", &service.Port). Err(err). Msg("Cannot create service") + statuses.addError(ingressRouteUDP.Namespace, ingressRouteUDP.Name, err) continue } diff --git a/pkg/provider/kubernetes/crd/status_test.go b/pkg/provider/kubernetes/crd/status_test.go new file mode 100644 index 0000000000..b35e1bb614 --- /dev/null +++ b/pkg/provider/kubernetes/crd/status_test.go @@ -0,0 +1,326 @@ +package crd + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" + kerror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kschema "k8s.io/apimachinery/pkg/runtime/schema" +) + +// assertStatusInvariants checks invariants that must hold between the produced +// configuration and the status tracker state. It is called from the existing +// table-driven tests in kubernetes_test.go. +func assertStatusInvariants(t *testing.T, conf *dynamic.Configuration, statuses configStatuses) { + t.Helper() + // If routers were produced, the corresponding resource type must have been visited. + if len(conf.HTTP.Routers) > 0 { + assert.NotEmpty(t, statuses.ingressRoutes.seen, "conf has HTTP routers but no IngressRoutes were visited") + } + if conf.TCP != nil && len(conf.TCP.Routers) > 0 { + assert.NotEmpty(t, statuses.ingressRoutesTCP.seen, "conf has TCP routers but no IngressRouteTCPs were visited") + } + if conf.UDP != nil && len(conf.UDP.Routers) > 0 { + assert.NotEmpty(t, statuses.ingressRoutesUDP.seen, "conf has UDP routers but no IngressRouteUDPs were visited") + } + // Every resource that has recorded errors must also be in the seen map. + for key := range statuses.ingressRoutes.errors { + assert.Truef(t, statuses.ingressRoutes.seen[key], "ingressroute %q has errors but was not visited", key) + } + for key := range statuses.ingressRoutesTCP.errors { + assert.Truef(t, statuses.ingressRoutesTCP.seen[key], "ingressroutetcp %q has errors but was not visited", key) + } + for key := range statuses.ingressRoutesUDP.errors { + assert.Truef(t, statuses.ingressRoutesUDP.seen[key], "ingressrouteudp %q has errors but was not visited", key) + } +} + +func TestBuildResourceCondition(t *testing.T) { + testCases := []struct { + desc string + errs []error + generation int64 + expectedStatus metav1.ConditionStatus + expectedReason string + expectedMessage string + }{ + { + desc: "no errors gives Valid=True", + generation: 3, + expectedStatus: metav1.ConditionTrue, + expectedReason: "Processed", + expectedMessage: "Resource processed successfully.", + }, + { + desc: "single error gives Valid=False", + errs: []error{errors.New("service not found")}, + generation: 1, + expectedStatus: metav1.ConditionFalse, + expectedReason: "ProcessingError", + expectedMessage: "service not found", + }, + { + desc: "multiple errors are joined with semicolon", + errs: []error{errors.New("err one"), errors.New("err two")}, + generation: 2, + expectedStatus: metav1.ConditionFalse, + expectedReason: "ProcessingError", + expectedMessage: "err one; err two", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + tracker := newStatusTracker() + tracker.visit("default", "my-route") + for _, err := range test.errs { + tracker.addError("default", "my-route", err) + } + + conds := buildResourceCondition(tracker, "default", "my-route", test.generation) + + require.Len(t, conds, 1) + assert.Equal(t, "Valid", conds[0].Type) + assert.Equal(t, test.expectedStatus, conds[0].Status) + assert.Equal(t, test.expectedReason, conds[0].Reason) + assert.Equal(t, test.expectedMessage, conds[0].Message) + assert.Equal(t, test.generation, conds[0].ObservedGeneration) + }) + } +} + +// statusMockClient records UpdateXxx calls and returns configurable errors. +// All Get methods return whatever is set on the struct fields. +// By default all UpdateXxx methods succeed. +type statusMockClient struct { + ingressRoutes []*traefikv1alpha1.IngressRoute + ingressRoutesTCP []*traefikv1alpha1.IngressRouteTCP + ingressRoutesUDP []*traefikv1alpha1.IngressRouteUDP + middlewares []*traefikv1alpha1.Middleware + middlewaresTCP []*traefikv1alpha1.MiddlewareTCP + serversTransports []*traefikv1alpha1.ServersTransport + serversTransportsTCP []*traefikv1alpha1.ServersTransportTCP + tlsOptions []*traefikv1alpha1.TLSOption + tlsStores []*traefikv1alpha1.TLSStore + traefikServices []*traefikv1alpha1.TraefikService + + // written tracks conditions passed to UpdateXxxStatus by "resource/namespace/name". + written map[string][]metav1.Condition + + // updateIngressRouteErr, if non-nil, is returned by UpdateIngressRouteStatus. + updateIngressRouteErr error +} + +func newStatusMockClient() *statusMockClient { + return &statusMockClient{written: make(map[string][]metav1.Condition)} +} + +func (m *statusMockClient) WatchAll(_ []string, _ <-chan struct{}) (<-chan any, error) { + return nil, nil +} + +func (m *statusMockClient) GetIngressRoutes() []*traefikv1alpha1.IngressRoute { + return m.ingressRoutes +} + +func (m *statusMockClient) GetIngressRouteTCPs() []*traefikv1alpha1.IngressRouteTCP { + return m.ingressRoutesTCP +} + +func (m *statusMockClient) GetIngressRouteUDPs() []*traefikv1alpha1.IngressRouteUDP { + return m.ingressRoutesUDP +} +func (m *statusMockClient) GetMiddlewares() []*traefikv1alpha1.Middleware { return m.middlewares } +func (m *statusMockClient) GetMiddlewareTCPs() []*traefikv1alpha1.MiddlewareTCP { + return m.middlewaresTCP +} + +func (m *statusMockClient) GetTraefikService(_, _ string) (*traefikv1alpha1.TraefikService, bool, error) { + return nil, false, nil +} + +func (m *statusMockClient) GetTraefikServices() []*traefikv1alpha1.TraefikService { + return m.traefikServices +} +func (m *statusMockClient) GetTLSOptions() []*traefikv1alpha1.TLSOption { return m.tlsOptions } +func (m *statusMockClient) GetServersTransports() []*traefikv1alpha1.ServersTransport { + return m.serversTransports +} + +func (m *statusMockClient) GetServersTransportTCPs() []*traefikv1alpha1.ServersTransportTCP { + return m.serversTransportsTCP +} +func (m *statusMockClient) GetTLSStores() []*traefikv1alpha1.TLSStore { return m.tlsStores } +func (m *statusMockClient) GetService(_, _ string) (*corev1.Service, bool, error) { + return nil, false, nil +} + +func (m *statusMockClient) GetSecret(_, _ string) (*corev1.Secret, bool, error) { + return nil, false, nil +} + +func (m *statusMockClient) GetEndpointSlicesForService(_, _ string) ([]*discoveryv1.EndpointSlice, error) { + return nil, nil +} +func (m *statusMockClient) GetNodes() ([]*corev1.Node, bool, error) { return nil, false, nil } +func (m *statusMockClient) GetConfigMap(_, _ string) (*corev1.ConfigMap, bool, error) { + return nil, false, nil +} + +func (m *statusMockClient) UpdateIngressRouteStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + if m.updateIngressRouteErr != nil { + return m.updateIngressRouteErr + } + m.record("ingressroutes", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateIngressRouteTCPStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("ingressroutetcps", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateIngressRouteUDPStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("ingressrouteudps", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateMiddlewareStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("middlewares", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateMiddlewareTCPStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("middlewaretcps", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateServersTransportStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("serverstransports", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateServersTransportTCPStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("serverstransporttcps", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateTLSOptionStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("tlsoptions", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateTLSStoreStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("tlsstores", namespace, name, conds) + return nil +} + +func (m *statusMockClient) UpdateTraefikServiceStatus(_ context.Context, namespace, name string, conds []metav1.Condition) error { + m.record("traefikservices", namespace, name, conds) + return nil +} + +func (m *statusMockClient) record(resource, namespace, name string, conds []metav1.Condition) { + m.written[resource+"/"+namespace+"/"+name] = conds +} + +func TestUpdateCRDStatuses(t *testing.T) { + testCases := []struct { + desc string + ingressRoutes []*traefikv1alpha1.IngressRoute + ingressRoutesTCP []*traefikv1alpha1.IngressRouteTCP + buildStatuses func() configStatuses + updateIngressRouteErr error + expectedWritten map[string]metav1.ConditionStatus // "resource/namespace/name" -> expected Status + expectTCPNotWritten bool + }{ + { + desc: "visited IngressRoute with no errors gets Valid=True", + ingressRoutes: []*traefikv1alpha1.IngressRoute{ + {ObjectMeta: metav1.ObjectMeta{Name: "ok-route", Namespace: "default", Generation: 5}}, + }, + buildStatuses: func() configStatuses { + s := newConfigStatuses() + s.ingressRoutes.visit("default", "ok-route") + return s + }, + expectedWritten: map[string]metav1.ConditionStatus{ + "ingressroutes/default/ok-route": metav1.ConditionTrue, + }, + }, + { + desc: "visited IngressRoute with errors gets Valid=False", + ingressRoutes: []*traefikv1alpha1.IngressRoute{ + {ObjectMeta: metav1.ObjectMeta{Name: "bad-route", Namespace: "default"}}, + }, + buildStatuses: func() configStatuses { + s := newConfigStatuses() + s.ingressRoutes.addError("default", "bad-route", errors.New("service not found")) + return s + }, + expectedWritten: map[string]metav1.ConditionStatus{ + "ingressroutes/default/bad-route": metav1.ConditionFalse, + }, + }, + { + // Nothing is visited — simulates an IngressRoute filtered out by ingressClass. + desc: "unseen IngressRoute is skipped", + ingressRoutes: []*traefikv1alpha1.IngressRoute{ + {ObjectMeta: metav1.ObjectMeta{Name: "other-class-route", Namespace: "default"}}, + }, + buildStatuses: newConfigStatuses, + expectedWritten: map[string]metav1.ConditionStatus{}, + }, + { + desc: "Forbidden error on IngressRoute aborts before TCP update", + ingressRoutes: []*traefikv1alpha1.IngressRoute{ + {ObjectMeta: metav1.ObjectMeta{Name: "route", Namespace: "default"}}, + }, + ingressRoutesTCP: []*traefikv1alpha1.IngressRouteTCP{ + {ObjectMeta: metav1.ObjectMeta{Name: "tcp-route", Namespace: "default"}}, + }, + buildStatuses: func() configStatuses { + s := newConfigStatuses() + s.ingressRoutes.visit("default", "route") + s.ingressRoutesTCP.visit("default", "tcp-route") + return s + }, + updateIngressRouteErr: kerror.NewForbidden(kschema.GroupResource{Group: "traefik.io", Resource: "ingressroutes"}, "route", errors.New("forbidden")), + expectedWritten: map[string]metav1.ConditionStatus{}, + expectTCPNotWritten: true, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + mockClient := newStatusMockClient() + mockClient.ingressRoutes = test.ingressRoutes + mockClient.ingressRoutesTCP = test.ingressRoutesTCP + mockClient.updateIngressRouteErr = test.updateIngressRouteErr + + statuses := test.buildStatuses() + updateCRDStatuses(t.Context(), mockClient, statuses) + + for key, expectedStatus := range test.expectedWritten { + conds, ok := mockClient.written[key] + require.True(t, ok, "expected status update for %q to be written", key) + require.Len(t, conds, 1) + assert.Equal(t, expectedStatus, conds[0].Status, "wrong condition status for %q", key) + } + assert.Len(t, mockClient.written, len(test.expectedWritten), "unexpected extra status updates written") + + if test.expectTCPNotWritten { + _, tcpWritten := mockClient.written["ingressroutetcps/default/tcp-route"] + assert.False(t, tcpWritten, "TCP route status should not be written after 403 abort") + } + }) + } +} diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go index 3c4d13ddb3..5962e3a054 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go @@ -247,6 +247,7 @@ type IngressRouteRef struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // IngressRoute is the CRD implementation of a Traefik HTTP Router. type IngressRoute struct { @@ -255,7 +256,18 @@ type IngressRoute struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec IngressRouteSpec `json:"spec"` + Spec IngressRouteSpec `json:"spec"` + Status IngressRouteStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// IngressRouteStatus defines the observed state of IngressRoute. +type IngressRouteStatus struct { + // Conditions lists the conditions of the IngressRoute. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go index e330aef20e..feabd5c646 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go @@ -114,6 +114,7 @@ type ServiceTCP struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // IngressRouteTCP is the CRD implementation of a Traefik TCP Router. type IngressRouteTCP struct { @@ -122,7 +123,18 @@ type IngressRouteTCP struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec IngressRouteTCPSpec `json:"spec"` + Spec IngressRouteTCPSpec `json:"spec"` + Status IngressRouteTCPStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// IngressRouteTCPStatus defines the observed state of IngressRouteTCP. +type IngressRouteTCPStatus struct { + // Conditions lists the conditions of the IngressRouteTCP. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go index fc7f1e6c4d..20707015b5 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go @@ -52,6 +52,7 @@ type ServiceUDP struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // IngressRouteUDP is a CRD implementation of a Traefik UDP Router. type IngressRouteUDP struct { @@ -60,7 +61,18 @@ type IngressRouteUDP struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec IngressRouteUDPSpec `json:"spec"` + Spec IngressRouteUDPSpec `json:"spec"` + Status IngressRouteUDPStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// IngressRouteUDPStatus defines the observed state of IngressRouteUDP. +type IngressRouteUDPStatus struct { + // Conditions lists the conditions of the IngressRouteUDP. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go index 1ebc21192c..f47ca1ca2d 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go @@ -10,6 +10,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // Middleware is the CRD implementation of a Traefik Middleware. // More info: https://doc.traefik.io/traefik/v3.7/reference/routing-configuration/http/middlewares/overview/ @@ -19,7 +20,18 @@ type Middleware struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec MiddlewareSpec `json:"spec"` + Spec MiddlewareSpec `json:"spec"` + Status MiddlewareStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// MiddlewareStatus defines the observed state of Middleware. +type MiddlewareStatus struct { + // Conditions lists the conditions of the Middleware. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go index b3fa073f0f..687a35ff76 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go @@ -7,6 +7,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:subresource:status // MiddlewareTCP is the CRD implementation of a Traefik TCP middleware. // More info: https://doc.traefik.io/traefik/v3.7/reference/routing-configuration/tcp/middlewares/overview/ @@ -16,7 +17,18 @@ type MiddlewareTCP struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec MiddlewareTCPSpec `json:"spec"` + Spec MiddlewareTCPSpec `json:"spec"` + Status MiddlewareTCPStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// MiddlewareTCPStatus defines the observed state of MiddlewareTCP. +type MiddlewareTCPStatus struct { + // Conditions lists the conditions of the MiddlewareTCP. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go index 1268bf1d69..c1a119bda1 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go @@ -9,6 +9,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // ServersTransport is the CRD implementation of a ServersTransport. // If no serversTransport is specified, the default@internal will be used. @@ -20,7 +21,18 @@ type ServersTransport struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec ServersTransportSpec `json:"spec"` + Spec ServersTransportSpec `json:"spec"` + Status ServersTransportStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// ServersTransportStatus defines the observed state of ServersTransport. +type ServersTransportStatus struct { + // Conditions lists the conditions of the ServersTransport. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go index 2a8511e16e..16fe340fa3 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go @@ -9,6 +9,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // ServersTransportTCP is the CRD implementation of a TCPServersTransport. // If no tcpServersTransport is specified, a default one named default@internal will be used. @@ -20,7 +21,18 @@ type ServersTransportTCP struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec ServersTransportTCPSpec `json:"spec"` + Spec ServersTransportTCPSpec `json:"spec"` + Status ServersTransportTCPStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// ServersTransportTCPStatus defines the observed state of ServersTransportTCP. +type ServersTransportTCPStatus struct { + // Conditions lists the conditions of the ServersTransportTCP. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go index 0ac65261dd..9d98c47ec2 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go @@ -8,6 +8,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // TraefikService is the CRD implementation of a Traefik Service. // TraefikService object allows to: @@ -20,7 +21,18 @@ type TraefikService struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec TraefikServiceSpec `json:"spec"` + Spec TraefikServiceSpec `json:"spec"` + Status TraefikServiceStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// TraefikServiceStatus defines the observed state of TraefikService. +type TraefikServiceStatus struct { + // Conditions lists the conditions of the TraefikService. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go index 3de47f4872..7c48627da1 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go @@ -7,6 +7,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection. // More info: https://doc.traefik.io/traefik/v3.7/reference/routing-configuration/http/tls/tls-certificates/#certificates-stores#tls-options @@ -16,7 +17,18 @@ type TLSOption struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec TLSOptionSpec `json:"spec"` + Spec TLSOptionSpec `json:"spec"` + Status TLSOptionStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// TLSOptionStatus defines the observed state of TLSOption. +type TLSOptionStatus struct { + // Conditions lists the conditions of the TLSOption. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go index 5bed935d8e..8245775e8e 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go @@ -8,6 +8,7 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:storageversion +// +kubebuilder:subresource:status // TLSStore is the CRD implementation of a Traefik TLS Store. // For the time being, only the TLSStore named default is supported. @@ -19,7 +20,18 @@ type TLSStore struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata"` - Spec TLSStoreSpec `json:"spec"` + Spec TLSStoreSpec `json:"spec"` + Status TLSStoreStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// TLSStoreStatus defines the observed state of TLSStore. +type TLSStoreStatus struct { + // Conditions lists the conditions of the TLSStore. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go index 20b6508cb1..70aa45f396 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go @@ -33,7 +33,8 @@ import ( dynamic "github.com/traefik/traefik/v3/pkg/config/dynamic" tls "github.com/traefik/traefik/v3/pkg/tls" types "github.com/traefik/traefik/v3/pkg/types" - v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" intstr "k8s.io/apimachinery/pkg/util/intstr" ) @@ -449,6 +450,7 @@ func (in *IngressRoute) DeepCopyInto(out *IngressRoute) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -562,12 +564,36 @@ func (in *IngressRouteSpec) DeepCopy() *IngressRouteSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteStatus) DeepCopyInto(out *IngressRouteStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteStatus. +func (in *IngressRouteStatus) DeepCopy() *IngressRouteStatus { + if in == nil { + return nil + } + out := new(IngressRouteStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRouteTCP) DeepCopyInto(out *IngressRouteTCP) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -660,12 +686,36 @@ func (in *IngressRouteTCPSpec) DeepCopy() *IngressRouteTCPSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCPStatus) DeepCopyInto(out *IngressRouteTCPStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPStatus. +func (in *IngressRouteTCPStatus) DeepCopy() *IngressRouteTCPStatus { + if in == nil { + return nil + } + out := new(IngressRouteTCPStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressRouteUDP) DeepCopyInto(out *IngressRouteUDP) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -753,6 +803,29 @@ func (in *IngressRouteUDPSpec) DeepCopy() *IngressRouteUDPSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteUDPStatus) DeepCopyInto(out *IngressRouteUDPStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteUDPStatus. +func (in *IngressRouteUDPStatus) DeepCopy() *IngressRouteUDPStatus { + if in == nil { + return nil + } + out := new(IngressRouteUDPStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LoadBalancerSpec) DeepCopyInto(out *LoadBalancerSpec) { *out = *in @@ -816,6 +889,7 @@ func (in *Middleware) DeepCopyInto(out *Middleware) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -1016,7 +1090,7 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) { } if in.Plugin != nil { in, out := &in.Plugin, &out.Plugin - *out = make(map[string]v1.JSON, len(*in)) + *out = make(map[string]apiextensionsv1.JSON, len(*in)) for key, val := range *in { (*out)[key] = *val.DeepCopy() } @@ -1034,12 +1108,36 @@ func (in *MiddlewareSpec) DeepCopy() *MiddlewareSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MiddlewareStatus) DeepCopyInto(out *MiddlewareStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MiddlewareStatus. +func (in *MiddlewareStatus) DeepCopy() *MiddlewareStatus { + if in == nil { + return nil + } + out := new(MiddlewareStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MiddlewareTCP) DeepCopyInto(out *MiddlewareTCP) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -1125,6 +1223,29 @@ func (in *MiddlewareTCPSpec) DeepCopy() *MiddlewareTCPSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MiddlewareTCPStatus) DeepCopyInto(out *MiddlewareTCPStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MiddlewareTCPStatus. +func (in *MiddlewareTCPStatus) DeepCopy() *MiddlewareTCPStatus { + if in == nil { + return nil + } + out := new(MiddlewareTCPStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MirrorService) DeepCopyInto(out *MirrorService) { *out = *in @@ -1534,6 +1655,7 @@ func (in *ServersTransport) DeepCopyInto(out *ServersTransport) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -1636,12 +1758,36 @@ func (in *ServersTransportSpec) DeepCopy() *ServersTransportSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServersTransportStatus) DeepCopyInto(out *ServersTransportStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportStatus. +func (in *ServersTransportStatus) DeepCopy() *ServersTransportStatus { + if in == nil { + return nil + } + out := new(ServersTransportStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServersTransportTCP) DeepCopyInto(out *ServersTransportTCP) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -1737,6 +1883,29 @@ func (in *ServersTransportTCPSpec) DeepCopy() *ServersTransportTCPSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServersTransportTCPStatus) DeepCopyInto(out *ServersTransportTCPStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportTCPStatus. +func (in *ServersTransportTCPStatus) DeepCopy() *ServersTransportTCPStatus { + if in == nil { + return nil + } + out := new(ServersTransportTCPStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Service) DeepCopyInto(out *Service) { *out = *in @@ -1895,6 +2064,7 @@ func (in *TLSOption) DeepCopyInto(out *TLSOption) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -2002,12 +2172,36 @@ func (in *TLSOptionSpec) DeepCopy() *TLSOptionSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSOptionStatus) DeepCopyInto(out *TLSOptionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSOptionStatus. +func (in *TLSOptionStatus) DeepCopy() *TLSOptionStatus { + if in == nil { + return nil + } + out := new(TLSOptionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSStore) DeepCopyInto(out *TLSStore) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -2109,6 +2303,29 @@ func (in *TLSStoreSpec) DeepCopy() *TLSStoreSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSStoreStatus) DeepCopyInto(out *TLSStoreStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSStoreStatus. +func (in *TLSStoreStatus) DeepCopy() *TLSStoreStatus { + if in == nil { + return nil + } + out := new(TLSStoreStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSTCP) DeepCopyInto(out *TLSTCP) { *out = *in @@ -2148,6 +2365,7 @@ func (in *TraefikService) DeepCopyInto(out *TraefikService) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -2238,6 +2456,29 @@ func (in *TraefikServiceSpec) DeepCopy() *TraefikServiceSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TraefikServiceStatus) DeepCopyInto(out *TraefikServiceStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TraefikServiceStatus. +func (in *TraefikServiceStatus) DeepCopy() *TraefikServiceStatus { + if in == nil { + return nil + } + out := new(TraefikServiceStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WeightedRoundRobin) DeepCopyInto(out *WeightedRoundRobin) { *out = *in