From 2dd2491241a697d6c342a5e7f0f763dc9488b151 Mon Sep 17 00:00:00 2001
From: Saloni
Date: Mon, 16 Sep 2024 17:48:36 -0600
Subject: [PATCH 1/2] add controller to snippetsFilter status
---
apis/v1alpha1/snippetsfilter_types.go | 27 +++-
apis/v1alpha1/zz_generated.deepcopy.go | 28 +++-
.../gateway.nginx.org_snippetsfilters.yaml | 136 +++++++++++-------
internal/mode/static/handler.go | 6 +-
.../mode/static/status/prepare_requests.go | 10 +-
.../static/status/prepare_requests_test.go | 41 ++++--
internal/mode/static/status/status_setters.go | 65 ++++++++-
.../mode/static/status/status_setters_test.go | 98 +++++++++++--
site/content/reference/api.md | 62 +++++++-
9 files changed, 383 insertions(+), 90 deletions(-)
diff --git a/apis/v1alpha1/snippetsfilter_types.go b/apis/v1alpha1/snippetsfilter_types.go
index 81b1b7e134..3519604ad4 100644
--- a/apis/v1alpha1/snippetsfilter_types.go
+++ b/apis/v1alpha1/snippetsfilter_types.go
@@ -2,6 +2,7 @@ package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ v1 "sigs.k8s.io/gateway-api/apis/v1"
)
// +genclient
@@ -79,10 +80,34 @@ const (
// SnippetsFilterStatus defines the state of SnippetsFilter.
type SnippetsFilterStatus struct {
- // Conditions describes the state of the SnippetsFilter.
+ // Controllers describe the state of the SnippetsFilter and controller name.
// +optional
// +listType=map
+ // +kubebuilder:validation:MaxItems=16
+ Controllers []ControllerStatus `json:"controllers,omitempty"`
+}
+
+type ControllerStatus struct {
+ // ControllerName is a domain/path string that indicates the name of the
+ // controller that wrote this status. This corresponds with the
+ // controllerName field on GatewayClass.
+ //
+ // Example: "example.net/gateway-controller".
+ //
+ // The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+ // valid Kubernetes names
+ // (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+ //
+ // Controllers MUST populate this field when writing status. Controllers should ensure that
+ // entries to status populated with their ControllerName are cleaned up when they are no
+ // longer necessary.
+ ControllerName v1.GatewayController `json:"controllerName"`
+
+ // Conditions describe the status of the SnippetsFilter.
+ //
+ // +listType=map
// +listMapKey=type
+ // +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=8
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go
index d64caaa8c8..117a79d2cd 100644
--- a/apis/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/v1alpha1/zz_generated.deepcopy.go
@@ -175,6 +175,28 @@ func (in *ClientSettingsPolicySpec) DeepCopy() *ClientSettingsPolicySpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ControllerStatus) DeepCopyInto(out *ControllerStatus) {
+ *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])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerStatus.
+func (in *ControllerStatus) DeepCopy() *ControllerStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(ControllerStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Logging) DeepCopyInto(out *Logging) {
*out = *in
@@ -560,9 +582,9 @@ func (in *SnippetsFilterSpec) DeepCopy() *SnippetsFilterSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SnippetsFilterStatus) DeepCopyInto(out *SnippetsFilterStatus) {
*out = *in
- if in.Conditions != nil {
- in, out := &in.Conditions, &out.Conditions
- *out = make([]v1.Condition, len(*in))
+ if in.Controllers != nil {
+ in, out := &in.Controllers, &out.Controllers
+ *out = make([]ControllerStatus, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
diff --git a/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml b/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
index 2d8f01c554..a61494bca6 100644
--- a/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
+++ b/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
@@ -86,66 +86,98 @@ spec:
status:
description: Status defines the state of the SnippetsFilter.
properties:
- conditions:
- description: Conditions describes the state of the SnippetsFilter.
+ controllers:
+ description: Controllers describe the state of the SnippetsFilter
+ and controller name.
items:
- description: Condition contains details for one aspect of the current
- state of this API Resource.
properties:
- lastTransitionTime:
+ conditions:
+ description: Conditions describe the status of the SnippetsFilter.
+ 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
+ maxItems: 8
+ minItems: 1
+ type: array
+ x-kubernetes-list-map-keys:
+ - type
+ x-kubernetes-list-type: map
+ controllerName:
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
+ ControllerName is a domain/path string that indicates the name of the
+ controller that wrote this status. This corresponds with the
+ controllerName field on GatewayClass.
+
+ Example: "example.net/gateway-controller".
+
+ The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+ valid Kubernetes names
+ (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+
+ Controllers MUST populate this field when writing status. Controllers should ensure that
+ entries to status populated with their ControllerName are cleaned up when they are no
+ longer necessary.
+ maxLength: 253
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])$
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
required:
- - lastTransitionTime
- - message
- - reason
- - status
- - type
+ - controllerName
type: object
- maxItems: 8
+ maxItems: 16
type: array
- x-kubernetes-list-map-keys:
- - type
x-kubernetes-list-type: map
type: object
required:
diff --git a/internal/mode/static/handler.go b/internal/mode/static/handler.go
index 3681083af1..e0b1eca227 100644
--- a/internal/mode/static/handler.go
+++ b/internal/mode/static/handler.go
@@ -255,7 +255,11 @@ func (h *eventHandlerImpl) updateStatuses(ctx context.Context, logger logr.Logge
polReqs := status.PrepareBackendTLSPolicyRequests(graph.BackendTLSPolicies, transitionTime, h.cfg.gatewayCtlrName)
ngfPolReqs := status.PrepareNGFPolicyRequests(graph.NGFPolicies, transitionTime, h.cfg.gatewayCtlrName)
- snippetsFilterReqs := status.PrepareSnippetsFilterRequests(graph.SnippetsFilters, transitionTime)
+ snippetsFilterReqs := status.PrepareSnippetsFilterRequests(
+ graph.SnippetsFilters,
+ transitionTime,
+ h.cfg.gatewayCtlrName,
+ )
reqs := make(
[]frameworkStatus.UpdateRequest,
diff --git a/internal/mode/static/status/prepare_requests.go b/internal/mode/static/status/prepare_requests.go
index 82924dd21b..10f563034c 100644
--- a/internal/mode/static/status/prepare_requests.go
+++ b/internal/mode/static/status/prepare_requests.go
@@ -410,6 +410,7 @@ func PrepareBackendTLSPolicyRequests(
func PrepareSnippetsFilterRequests(
snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter,
transitionTime metav1.Time,
+ gatewayCtlrName string,
) []frameworkStatus.UpdateRequest {
reqs := make([]frameworkStatus.UpdateRequest, 0, len(snippetsFilters))
@@ -425,13 +426,18 @@ func PrepareSnippetsFilterRequests(
conds := conditions.DeduplicateConditions(allConds)
apiConds := conditions.ConvertConditions(conds, snippetsFilter.Source.GetGeneration(), transitionTime)
status := ngfAPI.SnippetsFilterStatus{
- Conditions: apiConds,
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: apiConds,
+ ControllerName: v1alpha2.GatewayController(gatewayCtlrName),
+ },
+ },
}
reqs = append(reqs, frameworkStatus.UpdateRequest{
NsName: nsname,
ResourceType: snippetsFilter.Source,
- Setter: newSnippetsFilterStatusSetter(status),
+ Setter: newSnippetsFilterStatusSetter(status, gatewayCtlrName),
})
}
diff --git a/internal/mode/static/status/prepare_requests_test.go b/internal/mode/static/status/prepare_requests_test.go
index 5aafea0085..91f46b1a40 100644
--- a/internal/mode/static/status/prepare_requests_test.go
+++ b/internal/mode/static/status/prepare_requests_test.go
@@ -1771,6 +1771,7 @@ func TestBuildNGFPolicyStatuses(t *testing.T) {
func TestBuildSnippetsFilterStatuses(t *testing.T) {
transitionTime := helpers.PrepareTimeForFakeClient(metav1.Now())
+ const gatewayCtlrName = "controller"
validSnippetsFilter := &graph.SnippetsFilter{
Source: &ngfAPI.SnippetsFilter{
@@ -1822,14 +1823,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
expectedReqs: 1,
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
{Namespace: "test", Name: "valid-snippet"}: {
- Conditions: []metav1.Condition{
+ Controllers: []ngfAPI.ControllerStatus{
{
- Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
- Status: metav1.ConditionTrue,
- ObservedGeneration: 1,
- LastTransitionTime: transitionTime,
- Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
- Message: "SnippetsFilter is accepted",
+ Conditions: []metav1.Condition{
+ {
+ Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
+ Status: metav1.ConditionTrue,
+ ObservedGeneration: 1,
+ LastTransitionTime: transitionTime,
+ Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
+ Message: "SnippetsFilter is accepted",
+ },
+ },
+ ControllerName: gatewayCtlrName,
},
},
},
@@ -1843,14 +1849,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
expectedReqs: 1,
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
{Namespace: "test", Name: "invalid-snippet"}: {
- Conditions: []metav1.Condition{
+ Controllers: []ngfAPI.ControllerStatus{
{
- Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
- Status: metav1.ConditionFalse,
- ObservedGeneration: 1,
- LastTransitionTime: transitionTime,
- Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
- Message: "invalid snippetsFilter",
+ Conditions: []metav1.Condition{
+ {
+ Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
+ Status: metav1.ConditionFalse,
+ ObservedGeneration: 1,
+ LastTransitionTime: transitionTime,
+ Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
+ Message: "invalid snippetsFilter",
+ },
+ },
+ ControllerName: gatewayCtlrName,
},
},
},
@@ -1871,7 +1882,7 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
updater := statusFramework.NewUpdater(k8sClient, zap.New())
- reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime)
+ reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime, gatewayCtlrName)
g.Expect(reqs).To(HaveLen(test.expectedReqs))
diff --git a/internal/mode/static/status/status_setters.go b/internal/mode/static/status/status_setters.go
index 54bcdbbbf8..af1d5c1366 100644
--- a/internal/mode/static/status/status_setters.go
+++ b/internal/mode/static/status/status_setters.go
@@ -334,15 +334,74 @@ func ancestorStatusEqual(p1, p2 v1alpha2.PolicyAncestorStatus) bool {
return frameworkStatus.ConditionsEqual(p1.Conditions, p2.Conditions)
}
-func newSnippetsFilterStatusSetter(status ngfAPI.SnippetsFilterStatus) frameworkStatus.Setter {
+func newSnippetsFilterStatusSetter(
+ snippetsFilterStatus ngfAPI.SnippetsFilterStatus,
+ gatewayCtlrName string,
+) frameworkStatus.Setter {
return func(obj client.Object) (wasSet bool) {
sf := helpers.MustCastObject[*ngfAPI.SnippetsFilter](obj)
- if frameworkStatus.ConditionsEqual(sf.Status.Conditions, status.Conditions) {
+ // maxControllerStatus is the max number of controller statuses which is the sum of all new controller statuses
+ // and all old controller statuses.
+ maxControllerStatus := 1 + len(sf.Status.Controllers)
+ controllerStatuses := make([]ngfAPI.ControllerStatus, 0, maxControllerStatus)
+
+ for _, status := range sf.Status.Controllers {
+ if string(status.ControllerName) != gatewayCtlrName {
+ controllerStatuses = append(controllerStatuses, status)
+ }
+ }
+
+ controllerStatuses = append(controllerStatuses, snippetsFilterStatus.Controllers...)
+ snippetsFilterStatus.Controllers = controllerStatuses
+
+ if snippetsFilterStatusEqual(gatewayCtlrName, snippetsFilterStatus.Controllers, sf.Status.Controllers) {
return false
}
- sf.Status = status
+ sf.Status = snippetsFilterStatus
return true
}
}
+
+func snippetsFilterStatusEqual(gatewayCtlrName string, currStatus, prevStatus []ngfAPI.ControllerStatus) bool {
+ // Since other controllers may update snippetsFilter status we can't assume anything about the order of the statuses,
+ // and we have to ignore statuses written by other controllers when checking for equality.
+ // Therefore, we can't use slices.EqualFunc here because it cares about the order.
+
+ // First, we check if the prevStatus has any ControllerStatuses that are no longer present in the currStatus.
+ for _, prev := range prevStatus {
+ if prev.ControllerName != gatewayv1.GatewayController(gatewayCtlrName) {
+ continue
+ }
+
+ exists := slices.ContainsFunc(currStatus, func(currStatus ngfAPI.ControllerStatus) bool {
+ return snippetsStatusEqual(currStatus, prev)
+ })
+
+ if !exists {
+ return false
+ }
+ }
+
+ // Then, we check if the currStatus has any ControllerStatuses that are no longer present in the prevStatus.
+ for _, curr := range currStatus {
+ exists := slices.ContainsFunc(prevStatus, func(prevStatus ngfAPI.ControllerStatus) bool {
+ return snippetsStatusEqual(curr, prevStatus)
+ })
+
+ if !exists {
+ return false
+ }
+ }
+
+ return true
+}
+
+func snippetsStatusEqual(status1, status2 ngfAPI.ControllerStatus) bool {
+ if status1.ControllerName != status2.ControllerName {
+ return false
+ }
+
+ return frameworkStatus.ConditionsEqual(status1.Conditions, status2.Conditions)
+}
diff --git a/internal/mode/static/status/status_setters_test.go b/internal/mode/static/status/status_setters_test.go
index 3673b71555..c0328a86d6 100644
--- a/internal/mode/static/status/status_setters_test.go
+++ b/internal/mode/static/status/status_setters_test.go
@@ -1565,6 +1565,10 @@ func TestPolicyStatusEqual(t *testing.T) {
}
func TestNewSnippetsFilterStatusSetter(t *testing.T) {
+ const (
+ controllerName = "controller"
+ otherControllerName = "other-controller"
+ )
tests := []struct {
name string
status, expStatus, newStatus ngfAPI.SnippetsFilterStatus
@@ -1573,37 +1577,113 @@ func TestNewSnippetsFilterStatusSetter(t *testing.T) {
{
name: "SnippetsFilter has no status",
newStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "new condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
expStatusSet: true,
expStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "new condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
},
{
name: "SnippetsFilter has old status",
status: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "old condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "old condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
newStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "new condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
expStatusSet: true,
expStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "new condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ ControllerName: controllerName,
+ },
+ },
+ },
+ },
+ {
+ name: "SnippetsFilter has old status and other controller status",
+ newStatus: ngfAPI.SnippetsFilterStatus{
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ ControllerName: controllerName,
+ },
+ },
+ },
+ status: ngfAPI.SnippetsFilterStatus{
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ ControllerName: otherControllerName,
+ Conditions: []metav1.Condition{{Message: "some condition"}},
+ },
+ {
+ ControllerName: controllerName,
+ Conditions: []metav1.Condition{{Message: "old condition"}},
+ },
+ },
+ },
+ expStatus: ngfAPI.SnippetsFilterStatus{
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ ControllerName: otherControllerName,
+ Conditions: []metav1.Condition{{Message: "some condition"}},
+ },
+ {
+ ControllerName: controllerName,
+ Conditions: []metav1.Condition{{Message: "new condition"}},
+ },
+ },
},
+ expStatusSet: true,
},
{
name: "SnippetsFilter has same status",
status: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "same condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "same condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
newStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "same condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "same condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
expStatusSet: false,
expStatus: ngfAPI.SnippetsFilterStatus{
- Conditions: []metav1.Condition{{Message: "same condition"}},
+ Controllers: []ngfAPI.ControllerStatus{
+ {
+ Conditions: []metav1.Condition{{Message: "same condition"}},
+ ControllerName: controllerName,
+ },
+ },
},
},
}
@@ -1612,7 +1692,7 @@ func TestNewSnippetsFilterStatusSetter(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
g := NewWithT(t)
- setter := newSnippetsFilterStatusSetter(test.newStatus)
+ setter := newSnippetsFilterStatusSetter(test.newStatus, controllerName)
sf := &ngfAPI.SnippetsFilter{Status: test.status}
statusSet := setter(sf)
diff --git a/site/content/reference/api.md b/site/content/reference/api.md
index fa582def32..254953694c 100644
--- a/site/content/reference/api.md
+++ b/site/content/reference/api.md
@@ -811,6 +811,60 @@ Support: Gateway, HTTPRoute, GRPCRoute.
+ControllerStatus
+
+
+
+(Appears on:
+SnippetsFilterStatus)
+
+
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+controllerName
+
+
+sigs.k8s.io/gateway-api/apis/v1.GatewayController
+
+
+ |
+
+ ControllerName is a domain/path string that indicates the name of the
+controller that wrote this status. This corresponds with the
+controllerName field on GatewayClass.
+Example: “example.net/gateway-controller”.
+The format of this field is DOMAIN “/” PATH, where DOMAIN and PATH are
+valid Kubernetes names
+(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+Controllers MUST populate this field when writing status. Controllers should ensure that
+entries to status populated with their ControllerName are cleaned up when they are no
+longer necessary.
+ |
+
+
+
+conditions
+
+
+[]Kubernetes meta/v1.Condition
+
+
+ |
+
+ Conditions describe the status of the SnippetsFilter.
+ |
+
+
+
Duration
(string
alias)
@@ -1302,16 +1356,16 @@ Allowed contexts: main, http, http.server, http.server.location.
-conditions
+controllers
-
-[]Kubernetes meta/v1.Condition
+
+[]ControllerStatus
|
(Optional)
- Conditions describes the state of the SnippetsFilter.
+Controllers describe the state of the SnippetsFilter and controller name.
|
From 033c24665c242176492f653dab2659c9710c2bf2 Mon Sep 17 00:00:00 2001
From: Saloni
Date: Tue, 17 Sep 2024 14:25:42 -0600
Subject: [PATCH 2/2] update api and docs
---
apis/v1alpha1/snippetsfilter_types.go | 7 ++++---
config/crd/bases/gateway.nginx.org_snippetsfilters.yaml | 6 +++---
site/content/reference/api.md | 5 +++--
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/apis/v1alpha1/snippetsfilter_types.go b/apis/v1alpha1/snippetsfilter_types.go
index 3519604ad4..decb6190a4 100644
--- a/apis/v1alpha1/snippetsfilter_types.go
+++ b/apis/v1alpha1/snippetsfilter_types.go
@@ -80,9 +80,9 @@ const (
// SnippetsFilterStatus defines the state of SnippetsFilter.
type SnippetsFilterStatus struct {
- // Controllers describe the state of the SnippetsFilter and controller name.
- // +optional
- // +listType=map
+ // Controllers is a list of Gateway API controllers that processed the SnippetsFilter
+ // and the status of the SnippetsFilter with respect to each controller.
+ //
// +kubebuilder:validation:MaxItems=16
Controllers []ControllerStatus `json:"controllers,omitempty"`
}
@@ -105,6 +105,7 @@ type ControllerStatus struct {
// Conditions describe the status of the SnippetsFilter.
//
+ // +optional
// +listType=map
// +listMapKey=type
// +kubebuilder:validation:MinItems=1
diff --git a/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml b/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
index a61494bca6..a6e6bf0d25 100644
--- a/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
+++ b/config/crd/bases/gateway.nginx.org_snippetsfilters.yaml
@@ -87,8 +87,9 @@ spec:
description: Status defines the state of the SnippetsFilter.
properties:
controllers:
- description: Controllers describe the state of the SnippetsFilter
- and controller name.
+ description: |-
+ Controllers is a list of Gateway API controllers that processed the SnippetsFilter
+ and the status of the SnippetsFilter with respect to each controller.
items:
properties:
conditions:
@@ -178,7 +179,6 @@ spec:
type: object
maxItems: 16
type: array
- x-kubernetes-list-type: map
type: object
required:
- spec
diff --git a/site/content/reference/api.md b/site/content/reference/api.md
index 254953694c..90ec63ab15 100644
--- a/site/content/reference/api.md
+++ b/site/content/reference/api.md
@@ -860,6 +860,7 @@ longer necessary.
+(Optional)
Conditions describe the status of the SnippetsFilter.
|
@@ -1364,8 +1365,8 @@ Allowed contexts: main, http, http.server, http.server.location.
-(Optional)
- Controllers describe the state of the SnippetsFilter and controller name.
+Controllers is a list of Gateway API controllers that processed the SnippetsFilter
+and the status of the SnippetsFilter with respect to each controller.
|