diff --git a/go.mod b/go.mod index 7c41d47e17..19bf24aa74 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( k8s.io/client-go v0.26.0 k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 sigs.k8s.io/controller-runtime v0.14.1 - sigs.k8s.io/gateway-api v0.6.0-rc2 + sigs.k8s.io/gateway-api v0.6.0 sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 39640e1e6d..f20201f2c7 100644 --- a/go.sum +++ b/go.sum @@ -715,8 +715,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.14.1 h1:vThDes9pzg0Y+UbCPY3Wj34CGIYPgdmspPm2GIpxpzM= sigs.k8s.io/controller-runtime v0.14.1/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU= -sigs.k8s.io/gateway-api v0.6.0-rc2 h1:Dqys/rLadwLsujhJZixggxXMTCAkz0byRpyllmJdvXY= -sigs.k8s.io/gateway-api v0.6.0-rc2/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= +sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= +sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index 8de55aa683..c664742344 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -498,7 +498,8 @@ func (r *RouteParentContext) SetCondition(route RouteContext, conditionType v1be // return early if the condition is unchanged if existing.Status == cond.Status && existing.Reason == cond.Reason && - existing.Message == cond.Message { + existing.Message == cond.Message && + existing.ObservedGeneration == cond.ObservedGeneration { return } idx = i diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index ce3fff30f1..3921c0fe72 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -495,6 +495,7 @@ func (r *gatewayAPIReconciler) statusUpdateForGateway(gtw *gwapiv1b1.Gateway, sv } gCopy := g.DeepCopy() gCopy.Status.Conditions = status.MergeConditions(gCopy.Status.Conditions, gtw.Status.Conditions...) + gCopy.Status.Addresses = gtw.Status.Addresses return gCopy }), @@ -894,6 +895,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } gCopy := g.DeepCopy() gCopy.Status.Listeners = val.Status.Listeners + return gCopy }), }) @@ -922,6 +924,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context) { } hCopy := h.DeepCopy() hCopy.Status.Parents = val.Status.Parents + return hCopy }), }) diff --git a/internal/provider/kubernetes/testdata/in/gateway-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/gateway-experimental-crd.yaml index b6284c6a94..a9d429a970 100644 --- a/internal/provider/kubernetes/testdata/in/gateway-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/gateway-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gateways.gateway.networking.k8s.io @@ -27,8 +27,8 @@ spec: - jsonPath: .status.addresses[*].value name: Address type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed type: string - jsonPath: .metadata.creationTimestamp name: Age @@ -492,6 +492,11 @@ spec: reason: Pending status: Unknown type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants @@ -502,13 +507,14 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + \n \ttype FooStatus struct{ \t // Represents the observations + of a foo's current state. \t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\" \t // + +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map + \t // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields + \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -588,14 +594,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -724,8 +731,8 @@ spec: - jsonPath: .status.addresses[*].value name: Address type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed type: string - jsonPath: .metadata.creationTimestamp name: Age @@ -1186,6 +1193,11 @@ spec: reason: Pending status: Unknown type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants @@ -1196,13 +1208,14 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + \n \ttype FooStatus struct{ \t // Represents the observations + of a foo's current state. \t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\" \t // + +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map + \t // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields + \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -1282,14 +1295,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition diff --git a/internal/provider/kubernetes/testdata/in/gatewayclass-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/gatewayclass-experimental-crd.yaml index f6da511f3e..9dae2ad7ab 100644 --- a/internal/provider/kubernetes/testdata/in/gatewayclass-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/gatewayclass-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gatewayclasses.gateway.networking.k8s.io @@ -148,13 +148,14 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + \n \ttype FooStatus struct{ \t // Represents the observations + of a foo's current state. \t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\" \t // + +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map + \t // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields + \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -349,13 +350,14 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: - \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // +listMapKey=type - \ Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + \n \ttype FooStatus struct{ \t // Represents the observations + of a foo's current state. \t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\" \t // + +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map + \t // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields + \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition diff --git a/internal/provider/kubernetes/testdata/in/httproute-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/httproute-experimental-crd.yaml index 4530498464..439ff44421 100644 --- a/internal/provider/kubernetes/testdata/in/httproute-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/httproute-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -90,8 +90,8 @@ spec: items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain @@ -120,7 +120,12 @@ spec: that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should - also be merged." + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." items: description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually @@ -157,6 +162,12 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. \n Support: Core" maxLength: 63 minLength: 1 @@ -1460,8 +1471,8 @@ spec: if all conditions are satisfied. \n For example, the match below will match a HTTP request only if its path starts with `/foo` AND it contains the `version: v1` header: \n - ``` match: path: value: \"/foo\" headers: - name: - \"version\" value \"v1\" ```" + ``` match: \n \tpath: \t value: \"/foo\" \theaders: \t- + name: \"version\" \t value \"v1\" \n ```" properties: headers: description: Headers specifies HTTP request header matchers. @@ -1669,14 +1680,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -1789,7 +1801,13 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of - the Route. \n Support: Core" + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -1934,8 +1952,8 @@ spec: items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain @@ -1964,7 +1982,12 @@ spec: that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should - also be merged." + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." items: description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually @@ -2001,6 +2024,12 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. \n Support: Core" maxLength: 63 minLength: 1 @@ -3304,8 +3333,8 @@ spec: if all conditions are satisfied. \n For example, the match below will match a HTTP request only if its path starts with `/foo` AND it contains the `version: v1` header: \n - ``` match: path: value: \"/foo\" headers: - name: - \"version\" value \"v1\" ```" + ``` match: \n \tpath: \t value: \"/foo\" \theaders: \t- + name: \"version\" \t value \"v1\" \n ```" properties: headers: description: Headers specifies HTTP request header matchers. @@ -3513,14 +3542,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -3633,7 +3663,13 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of - the Route. \n Support: Core" + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ diff --git a/internal/provider/kubernetes/testdata/in/referencegrant-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/referencegrant-experimental-crd.yaml index 87de02cc89..513c8025ff 100644 --- a/internal/provider/kubernetes/testdata/in/referencegrant-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/referencegrant-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -34,9 +34,11 @@ spec: add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n ReferenceGrant is a form of runtime verification. Implementations - that support ReferenceGrant MUST respond to removal of a grant by revoking - the access that grant allowed. \n Support: Core" + a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing + users to assert which cross-namespace object references are permitted. Implementations + that support ReferenceGrant MUST NOT permit cross-namespace references which + have no grant, and MUST respond to the removal of a grant by revoking the + access that the grant allowed. \n Support: Core" properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -157,9 +159,11 @@ spec: add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n ReferenceGrant is a form of runtime verification. Implementations - that support ReferenceGrant MUST respond to removal of a grant by revoking - the access that grant allowed. \n Support: Core" + a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing + users to assert which cross-namespace object references are permitted. Implementations + that support ReferenceGrant MUST NOT permit cross-namespace references which + have no grant, and MUST respond to the removal of a grant by revoking the + access that the grant allowed. \n Support: Core" properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation diff --git a/internal/provider/kubernetes/testdata/in/tlsroute-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/tlsroute-experimental-crd.yaml index d820e62ab6..ffb230461a 100644 --- a/internal/provider/kubernetes/testdata/in/tlsroute-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/tlsroute-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -75,8 +75,8 @@ spec: items: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with - 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname - may be prefixed with a wildcard label (`*.`). The wildcard label + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain @@ -105,7 +105,12 @@ spec: that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should - also be merged." + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." items: description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually @@ -142,6 +147,12 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. \n Support: Core" maxLength: 63 minLength: 1 @@ -345,14 +356,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -465,7 +477,13 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of - the Route. \n Support: Core" + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ diff --git a/internal/provider/kubernetes/testdata/in/udproute-experimental-crd.yaml b/internal/provider/kubernetes/testdata/in/udproute-experimental-crd.yaml index 5d8d82dee8..7c2deaa555 100644 --- a/internal/provider/kubernetes/testdata/in/udproute-experimental-crd.yaml +++ b/internal/provider/kubernetes/testdata/in/udproute-experimental-crd.yaml @@ -2,8 +2,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1086 - gateway.networking.k8s.io/bundle-version: v0.6.0-rc1 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io @@ -59,7 +59,12 @@ spec: that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should - also be merged." + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." items: description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually @@ -96,6 +101,12 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. \n Support: Core" maxLength: 63 minLength: 1 @@ -296,14 +307,15 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path - .status.conditions. For example, type FooStatus struct{ - \ // Represents the observations of a foo's current state. - \ // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type - \ // +patchStrategy=merge // +listType=map // - +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" - patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` - \n // other fields }" + .status.conditions. For example, \n \ttype FooStatus struct{ + \t // Represents the observations of a foo's current + state. \t // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type + \t // +patchStrategy=merge \t // +listType=map \t + \ // +listMapKey=type \t Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other + fields \t}" properties: lastTransitionTime: description: lastTransitionTime is the last time the condition @@ -416,7 +428,13 @@ spec: namespace: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of - the Route. \n Support: Core" + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ diff --git a/internal/status/conditions.go b/internal/status/conditions.go index bb2e2f8cf9..d3877f5237 100644 --- a/internal/status/conditions.go +++ b/internal/status/conditions.go @@ -125,5 +125,5 @@ func newCondition(t string, status metav1.ConditionStatus, reason, msg string, l } func conditionChanged(a, b metav1.Condition) bool { - return a.Status != b.Status || a.Reason != b.Reason || a.Message != b.Message + return a.Status != b.Status || a.Reason != b.Reason || a.Message != b.Message || a.ObservedGeneration != b.ObservedGeneration } diff --git a/internal/status/status.go b/internal/status/status.go index 66d9c58011..dbaffd4fb7 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -161,7 +161,7 @@ func (u *UpdateWriter) Send(update Update) { // HTTPRoute // TLSRoute func isStatusEqual(objA, objB interface{}) bool { - opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime", "ObservedGeneration") + opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime") switch a := objA.(type) { case *gwapiv1b1.GatewayClass: if b, ok := objB.(*gwapiv1b1.GatewayClass); ok {