Skip to content

Commit 95f642e

Browse files
salonichf5sjberman
authored andcommitted
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 22a07cd commit 95f642e

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(gr.BackendTLSPolicies, transitionTime, h.cfg.gatewayCtlrName)
257257
ngfPolReqs := status.PrepareNGFPolicyRequests(gr.NGFPolicies, transitionTime, h.cfg.gatewayCtlrName)
258-
snippetsFilterReqs := status.PrepareSnippetsFilterRequests(gr.SnippetsFilters, transitionTime)
258+
snippetsFilterReqs := status.PrepareSnippetsFilterRequests(
259+
gr.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
@@ -413,6 +413,7 @@ func PrepareBackendTLSPolicyRequests(
413413
func PrepareSnippetsFilterRequests(
414414
snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter,
415415
transitionTime metav1.Time,
416+
gatewayCtlrName string,
416417
) []frameworkStatus.UpdateRequest {
417418
reqs := make([]frameworkStatus.UpdateRequest, 0, len(snippetsFilters))
418419

@@ -428,13 +429,18 @@ func PrepareSnippetsFilterRequests(
428429
conds := conditions.DeduplicateConditions(allConds)
429430
apiConds := conditions.ConvertConditions(conds, snippetsFilter.Source.GetGeneration(), transitionTime)
430431
status := ngfAPI.SnippetsFilterStatus{
431-
Conditions: apiConds,
432+
Controllers: []ngfAPI.ControllerStatus{
433+
{
434+
Conditions: apiConds,
435+
ControllerName: v1alpha2.GatewayController(gatewayCtlrName),
436+
},
437+
},
432438
}
433439

434440
reqs = append(reqs, frameworkStatus.UpdateRequest{
435441
NsName: nsname,
436442
ResourceType: snippetsFilter.Source,
437-
Setter: newSnippetsFilterStatusSetter(status),
443+
Setter: newSnippetsFilterStatusSetter(status, gatewayCtlrName),
438444
})
439445
}
440446

internal/mode/static/status/prepare_requests_test.go

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

17861786
func TestBuildSnippetsFilterStatuses(t *testing.T) {
17871787
transitionTime := helpers.PrepareTimeForFakeClient(metav1.Now())
1788+
const gatewayCtlrName = "controller"
17881789

17891790
validSnippetsFilter := &graph.SnippetsFilter{
17901791
Source: &ngfAPI.SnippetsFilter{
@@ -1836,14 +1837,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18361837
expectedReqs: 1,
18371838
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
18381839
{Namespace: "test", Name: "valid-snippet"}: {
1839-
Conditions: []metav1.Condition{
1840+
Controllers: []ngfAPI.ControllerStatus{
18401841
{
1841-
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1842-
Status: metav1.ConditionTrue,
1843-
ObservedGeneration: 1,
1844-
LastTransitionTime: transitionTime,
1845-
Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
1846-
Message: "SnippetsFilter is accepted",
1842+
Conditions: []metav1.Condition{
1843+
{
1844+
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1845+
Status: metav1.ConditionTrue,
1846+
ObservedGeneration: 1,
1847+
LastTransitionTime: transitionTime,
1848+
Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
1849+
Message: "SnippetsFilter is accepted",
1850+
},
1851+
},
1852+
ControllerName: gatewayCtlrName,
18471853
},
18481854
},
18491855
},
@@ -1857,14 +1863,19 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18571863
expectedReqs: 1,
18581864
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
18591865
{Namespace: "test", Name: "invalid-snippet"}: {
1860-
Conditions: []metav1.Condition{
1866+
Controllers: []ngfAPI.ControllerStatus{
18611867
{
1862-
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1863-
Status: metav1.ConditionFalse,
1864-
ObservedGeneration: 1,
1865-
LastTransitionTime: transitionTime,
1866-
Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
1867-
Message: "invalid snippetsFilter",
1868+
Conditions: []metav1.Condition{
1869+
{
1870+
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
1871+
Status: metav1.ConditionFalse,
1872+
ObservedGeneration: 1,
1873+
LastTransitionTime: transitionTime,
1874+
Reason: string(ngfAPI.SnippetsFilterConditionReasonInvalid),
1875+
Message: "invalid snippetsFilter",
1876+
},
1877+
},
1878+
ControllerName: gatewayCtlrName,
18681879
},
18691880
},
18701881
},
@@ -1885,7 +1896,7 @@ func TestBuildSnippetsFilterStatuses(t *testing.T) {
18851896

18861897
updater := statusFramework.NewUpdater(k8sClient, zap.New())
18871898

1888-
reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime)
1899+
reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime, gatewayCtlrName)
18891900

18901901
g.Expect(reqs).To(HaveLen(test.expectedReqs))
18911902

0 commit comments

Comments
 (0)