Skip to content

Commit 7a3725c

Browse files
authored
add controller to snippetsFilter status (#2570)
Add controller to snippetsFilter status Problem: Users want to ensure controller name is added when condition is added to SnippetsFilter. Solution: Modify the SnippetsFilterStatus to include controller name writing status.
1 parent 9c360dd commit 7a3725c

File tree

9 files changed

+387
-92
lines changed

9 files changed

+387
-92
lines changed

apis/v1alpha1/snippetsfilter_types.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package v1alpha1
22

33
import (
44
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
v1 "sigs.k8s.io/gateway-api/apis/v1"
56
)
67

78
// +genclient
@@ -79,10 +80,35 @@ const (
7980

8081
// SnippetsFilterStatus defines the state of SnippetsFilter.
8182
type SnippetsFilterStatus struct {
82-
// Conditions describes the state of the SnippetsFilter.
83+
// Controllers is a list of Gateway API controllers that processed the SnippetsFilter
84+
// and the status of the SnippetsFilter with respect to each controller.
85+
//
86+
// +kubebuilder:validation:MaxItems=16
87+
Controllers []ControllerStatus `json:"controllers,omitempty"`
88+
}
89+
90+
type ControllerStatus struct {
91+
// ControllerName is a domain/path string that indicates the name of the
92+
// controller that wrote this status. This corresponds with the
93+
// controllerName field on GatewayClass.
94+
//
95+
// Example: "example.net/gateway-controller".
96+
//
97+
// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
98+
// valid Kubernetes names
99+
// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
100+
//
101+
// Controllers MUST populate this field when writing status. Controllers should ensure that
102+
// entries to status populated with their ControllerName are cleaned up when they are no
103+
// longer necessary.
104+
ControllerName v1.GatewayController `json:"controllerName"`
105+
106+
// Conditions describe the status of the SnippetsFilter.
107+
//
83108
// +optional
84109
// +listType=map
85110
// +listMapKey=type
111+
// +kubebuilder:validation:MinItems=1
86112
// +kubebuilder:validation:MaxItems=8
87113
Conditions []metav1.Condition `json:"conditions,omitempty"`
88114
}

apis/v1alpha1/zz_generated.deepcopy.go

Lines changed: 25 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/gateway.nginx.org_snippetsfilters.yaml

Lines changed: 85 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -86,67 +86,99 @@ spec:
8686
status:
8787
description: Status defines the state of the SnippetsFilter.
8888
properties:
89-
conditions:
90-
description: Conditions describes the state of the SnippetsFilter.
89+
controllers:
90+
description: |-
91+
Controllers is a list of Gateway API controllers that processed the SnippetsFilter
92+
and the status of the SnippetsFilter with respect to each controller.
9193
items:
92-
description: Condition contains details for one aspect of the current
93-
state of this API Resource.
9494
properties:
95-
lastTransitionTime:
96-
description: |-
97-
lastTransitionTime is the last time the condition transitioned from one status to another.
98-
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
99-
format: date-time
100-
type: string
101-
message:
102-
description: |-
103-
message is a human readable message indicating details about the transition.
104-
This may be an empty string.
105-
maxLength: 32768
106-
type: string
107-
observedGeneration:
95+
conditions:
96+
description: Conditions describe the status of the SnippetsFilter.
97+
items:
98+
description: Condition contains details for one aspect of
99+
the current state of this API Resource.
100+
properties:
101+
lastTransitionTime:
102+
description: |-
103+
lastTransitionTime is the last time the condition transitioned from one status to another.
104+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
105+
format: date-time
106+
type: string
107+
message:
108+
description: |-
109+
message is a human readable message indicating details about the transition.
110+
This may be an empty string.
111+
maxLength: 32768
112+
type: string
113+
observedGeneration:
114+
description: |-
115+
observedGeneration represents the .metadata.generation that the condition was set based upon.
116+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
117+
with respect to the current state of the instance.
118+
format: int64
119+
minimum: 0
120+
type: integer
121+
reason:
122+
description: |-
123+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
124+
Producers of specific condition types may define expected values and meanings for this field,
125+
and whether the values are considered a guaranteed API.
126+
The value should be a CamelCase string.
127+
This field may not be empty.
128+
maxLength: 1024
129+
minLength: 1
130+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
131+
type: string
132+
status:
133+
description: status of the condition, one of True, False,
134+
Unknown.
135+
enum:
136+
- "True"
137+
- "False"
138+
- Unknown
139+
type: string
140+
type:
141+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
142+
maxLength: 316
143+
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])$
144+
type: string
145+
required:
146+
- lastTransitionTime
147+
- message
148+
- reason
149+
- status
150+
- type
151+
type: object
152+
maxItems: 8
153+
minItems: 1
154+
type: array
155+
x-kubernetes-list-map-keys:
156+
- type
157+
x-kubernetes-list-type: map
158+
controllerName:
108159
description: |-
109-
observedGeneration represents the .metadata.generation that the condition was set based upon.
110-
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
111-
with respect to the current state of the instance.
112-
format: int64
113-
minimum: 0
114-
type: integer
115-
reason:
116-
description: |-
117-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
118-
Producers of specific condition types may define expected values and meanings for this field,
119-
and whether the values are considered a guaranteed API.
120-
The value should be a CamelCase string.
121-
This field may not be empty.
122-
maxLength: 1024
160+
ControllerName is a domain/path string that indicates the name of the
161+
controller that wrote this status. This corresponds with the
162+
controllerName field on GatewayClass.
163+
164+
Example: "example.net/gateway-controller".
165+
166+
The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
167+
valid Kubernetes names
168+
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
169+
170+
Controllers MUST populate this field when writing status. Controllers should ensure that
171+
entries to status populated with their ControllerName are cleaned up when they are no
172+
longer necessary.
173+
maxLength: 253
123174
minLength: 1
124-
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
125-
type: string
126-
status:
127-
description: status of the condition, one of True, False, Unknown.
128-
enum:
129-
- "True"
130-
- "False"
131-
- Unknown
132-
type: string
133-
type:
134-
description: type of condition in CamelCase or in foo.example.com/CamelCase.
135-
maxLength: 316
136-
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])$
175+
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
137176
type: string
138177
required:
139-
- lastTransitionTime
140-
- message
141-
- reason
142-
- status
143-
- type
178+
- controllerName
144179
type: object
145-
maxItems: 8
180+
maxItems: 16
146181
type: array
147-
x-kubernetes-list-map-keys:
148-
- type
149-
x-kubernetes-list-type: map
150182
type: object
151183
required:
152184
- spec

internal/mode/static/handler.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,11 @@ func (h *eventHandlerImpl) updateStatuses(ctx context.Context, logger logr.Logge
255255

256256
polReqs := status.PrepareBackendTLSPolicyRequests(graph.BackendTLSPolicies, transitionTime, h.cfg.gatewayCtlrName)
257257
ngfPolReqs := status.PrepareNGFPolicyRequests(graph.NGFPolicies, transitionTime, h.cfg.gatewayCtlrName)
258-
snippetsFilterReqs := status.PrepareSnippetsFilterRequests(graph.SnippetsFilters, transitionTime)
258+
snippetsFilterReqs := status.PrepareSnippetsFilterRequests(
259+
graph.SnippetsFilters,
260+
transitionTime,
261+
h.cfg.gatewayCtlrName,
262+
)
259263

260264
reqs := make(
261265
[]frameworkStatus.UpdateRequest,

internal/mode/static/status/prepare_requests.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ func PrepareBackendTLSPolicyRequests(
410410
func PrepareSnippetsFilterRequests(
411411
snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter,
412412
transitionTime metav1.Time,
413+
gatewayCtlrName string,
413414
) []frameworkStatus.UpdateRequest {
414415
reqs := make([]frameworkStatus.UpdateRequest, 0, len(snippetsFilters))
415416

@@ -425,13 +426,18 @@ func PrepareSnippetsFilterRequests(
425426
conds := conditions.DeduplicateConditions(allConds)
426427
apiConds := conditions.ConvertConditions(conds, snippetsFilter.Source.GetGeneration(), transitionTime)
427428
status := ngfAPI.SnippetsFilterStatus{
428-
Conditions: apiConds,
429+
Controllers: []ngfAPI.ControllerStatus{
430+
{
431+
Conditions: apiConds,
432+
ControllerName: v1alpha2.GatewayController(gatewayCtlrName),
433+
},
434+
},
429435
}
430436

431437
reqs = append(reqs, frameworkStatus.UpdateRequest{
432438
NsName: nsname,
433439
ResourceType: snippetsFilter.Source,
434-
Setter: newSnippetsFilterStatusSetter(status),
440+
Setter: newSnippetsFilterStatusSetter(status, gatewayCtlrName),
435441
})
436442
}
437443

internal/mode/static/status/prepare_requests_test.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,7 @@ func TestBuildNGFPolicyStatuses(t *testing.T) {
17711771

17721772
func TestBuildSnippetsFilterStatuses(t *testing.T) {
17731773
transitionTime := helpers.PrepareTimeForFakeClient(metav1.Now())
1774+
const gatewayCtlrName = "controller"
17741775

17751776
validSnippetsFilter := &graph.SnippetsFilter{
17761777
Source: &ngfAPI.SnippetsFilter{
@@ -1822,14 +1823,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18221823
expectedReqs: 1,
18231824
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
18241825
{Namespace: "test", Name: "valid-snippet"}: {
1825-
Conditions: []metav1.Condition{
1826+
Controllers: []ngfAPI.ControllerStatus{
18261827
{
1827-
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1828-
Status: metav1.ConditionTrue,
1829-
ObservedGeneration: 1,
1830-
LastTransitionTime: transitionTime,
1831-
Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
1832-
Message: "SnippetsFilter is accepted",
1828+
Conditions: []metav1.Condition{
1829+
{
1830+
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1831+
Status: metav1.ConditionTrue,
1832+
ObservedGeneration: 1,
1833+
LastTransitionTime: transitionTime,
1834+
Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
1835+
Message: "SnippetsFilter is accepted",
1836+
},
1837+
},
1838+
ControllerName: gatewayCtlrName,
18331839
},
18341840
},
18351841
},
@@ -1843,14 +1849,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18431849
expectedReqs: 1,
18441850
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
18451851
{Namespace: "test", Name: "invalid-snippet"}: {
1846-
Conditions: []metav1.Condition{
1852+
Controllers: []ngfAPI.ControllerStatus{
18471853
{
1848-
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1849-
Status: metav1.ConditionFalse,
1850-
ObservedGeneration: 1,
1851-
LastTransitionTime: transitionTime,
1852-
Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
1853-
Message: "invalid snippetsFilter",
1854+
Conditions: []metav1.Condition{
1855+
{
1856+
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1857+
Status: metav1.ConditionFalse,
1858+
ObservedGeneration: 1,
1859+
LastTransitionTime: transitionTime,
1860+
Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
1861+
Message: "invalid snippetsFilter",
1862+
},
1863+
},
1864+
ControllerName: gatewayCtlrName,
18541865
},
18551866
},
18561867
},
@@ -1871,7 +1882,7 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18711882

18721883
updater := statusFramework.NewUpdater(k8sClient, zap.New())
18731884

1874-
reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime)
1885+
reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime, gatewayCtlrName)
18751886

18761887
g.Expect(reqs).To(HaveLen(test.expectedReqs))
18771888

0 commit comments

Comments
 (0)